blob: a29f057c31386756da5c0a8c9a9df1d4bc8c03a4 [file] [log] [blame]
Julian Hall1751ce72022-08-30 13:54:13 +01001Block Storage Service
2=====================
3Overview
4--------
5The Block Storage service can be used to share a block-oriented storage device
6such as a QSPI flash between a set of independent secure world clients. A block
7storage service provider presents a block level interface for accessing an
8underlying block storage device. To allow multiple higher layer filesystems to
9share the same storage device, logical block addresses are partitioned, based on
10configuration data provided by a system integrator. The partition configuration
11data may be read from a GUID Partition Table (GPT) or from the block storage SP
12manifest. The configuration data restricts access to a storage partition to a
13defined owner. Each owner is allocated a maximum number of blocks and is given
14exclusive access to its own blocks, based on the client ID of the calling client.
15
16The following diagram illustrates a firmware integration that uses a single block
17storage service provider to control access to a dedicated flash device. In this
18example StMM, OP-TEE, Update Agent and the Protected Storage SP act as clients of
19the service. Each client independently manages its own filesystem and is presented
20with its own logical partition, starting with a logical block address (LBA) of zero.
21
22.. image:: image/block-storage-example-usage.svg
23
24Project Directories
25-------------------
26Components within the Trusted Services project related to the Block Storage service
27are located under the following directories:
28
29.. list-table::
30 :header-rows: 1
31
32 * - Directory
33 - Contains
34 * - ``components/service/block_storage``
35 - Service specific code components.
36 * - ``deployments/block-storage``
37 - Build files and deployment specific code for building alternative configurations
38 of the block storage service provider.
39 * - ``protocols/service/block_storage``
40 - Service access protocol definitions.
41
42Service Interface
43-----------------
44The Block Storage service supports a conventional set of block-level operations that
45can be adapted to different driver models by clients. The following table summarizes
46supported operations:
47
48.. list-table::
49 :header-rows: 1
50
51 * - Operation
52 - Description
53 * - Open
54 - Open a session - take the required *UniquePartitionGUID* as a parameter. Returns
55 a handle to be used as a qualifier for other requests made by a client.
56 * - Close
57 - Close a previously opened session.
58 * - GetInfo
59 - Returns information about the partition associated with an open session. Includes
60 the block size and the total number of blocks assigned to the partition.
61 * - Read
62 - Read data from the specified block.
63 * - Write
64 - Write data to the specified block.
65 * - Erase
66 - Erase a set of one or more blocks.
67
68Protocol definitions live under: ``protocols/service/block_storage``.
69
70The service interface is realized by the block storage service provider. It delegates
71storage operations to a backend *block_store*. The *block_store* defines a common
72interface for components that realize block storage operations. Where an underlying storage
73technology does not support an explicit erase operation (e.g. RPMB), the corresponding
74concrete *block_store* should return success for a call to erase but perform no actual
75operation (if the partition is writable and the LBA falls within the limits of the
76partition).
77
78Service Provider Configuration
79------------------------------
80A platform integrator must provide a set of configuration data to configure how the block
81storage service provider presents block storage to clients. Configuration data relates to
82the following:
83
84 - **Storage partition configuration** - determines how storage is divided into separate partitions
85 - **Block device configuration** - determines how the backed storage device is configured
86
87Storage Partition Configuration
88^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
89The block storage service allows a block storage device to be presented as a single storage
90partition or as a set of smaller storage partitions. The way that storage is presented is
91determined by configuration data prepared by a platform integrator. Each storage partition
92presented by a block storage service provider starts at LBA zero. The number of partitions
93and their size are defined by configuration data. Configuration data assigns partitions
94to owners to enable access to be controlled. If no partition configuration exists for a
95requesting client or if an attempt is made to access a block outside of the configured LBA
96range, access is denied. The set of storage partitions used for secure block storage will
97not necessarily span the entire underlying storage device. A platform integrator is free to
98limit the area used for secure block storage to allow the storage device to be used for other
99purposes e.g. as a boot source, read by the boot loader during early boot stages.
100
101Two partition configuration methods will be supported; one where partition configuration data
102is read from an SP manifest and the other where configuration is defined by a GUID Partition
103Table. Both methods may be used in combination if necessary. Initial implementations will
104use the SP manifest configuration method.
105
106Each partition configuration entry includes an attributes bitmap that conforms to the UEFI
107GPT Partition Entry attributes definition (see section 5.3 of the UEFI specification). Bits
10848-63 are reserved for GUID specific use. For partitions labelled with the Secure Block Store
109GUID, bits will be defined for:
110
111 - **Read-only** - write and erase operations are forbidden.
112
113A GPT partition entry includes the PartitionName property which normally holds a human readable
114name for the partition. For secure block store partitions, the PartitionName property will
115hold the canonical UUID string identifying the owner. An empty string is interpreted as
116'no specific owner' and any client will be granted access.
117
118Configuration via SP Manifest
119"""""""""""""""""""""""""""""
120For an SP deployment, the partition configuration may be read from a device tree blob (DTB),
121passed as an initialization parameter. Per-partition configuration data comprises the following:
122
123.. list-table::
124 :header-rows: 1
125
126 * - Config Value
127 - Description
128 * - UniquePartitionGUID
129 - GUID that is unique for a partition entry.
130 * - StartingLBA
131 - The storage block address corresponding to LBA zero.
132 * - EndingLBA
133 - The last storage block in the contiguous range of blocks.
134 * - Attributes
135 - See UEFI specification
136 * - Owner
137 - Holds canonical UUID string for owner.
138
139The partition configuration is included as a sub-node of the block-dev node that includes
140configuration values related to the block device. The following is an example of how a block
141device and related partitions are defined within a DT based SP manifest::
142
143 block-dev {
144 compatible = "tforg,ts-block-dev"
145 disk-guid = "af9f72de-d71f-4492-b44b-a4b4d96000bf"
146
147 partitions {
148 compatible = "tforg,ts-block-partitions"
149
150 fwu-meta {
151 guid = "a6f99e90-7a75-4384-847a-29c9a86c6279"
152 start-lba = <0x00000000>
153 end-lba = <0x00000003>
154 attr = <0x00000000>
155 owner = "afb995cd-9354-4333-9ea2-bd62ccaedb22"
156 };
157
158 fip {
159 guid = "1eccc9bc-9a5f-43d0-bcd3-466fd21c9a92"
160 start-lba = <0x00000004>
161 end-lba = <0x00040003>
162 attr = <0x00000000>
163 owner = "afb995cd-9354-4333-9ea2-bd62ccaedb22"
164 };
165
166 uefi-var {
167 guid = "1022a92b-4b4a-47b4-94cb-35faf5a45dc2"
168 start-lba = <0x00040004>
169 end-lba = <0x00080003>
170 attr = <0x00000000>
171 owner = "ed32d533-99e6-4209-9cc0-2d72cdd998a7"
172 };
173 };
174 };
175
176Configuration via GUID Partition Table (GPT)
177""""""""""""""""""""""""""""""""""""""""""""
178The UEFI specification defines a standard layout for physical storage devices where storage
179partitions are described by partition entries within the GUID Partition Table. During
180initialization, the Block Storage SP will read the GPT and iterate over partition entries,
181identifying those with the secure block store partition type GUID. Each entry contains the
182following:
183
184.. list-table::
185 :header-rows: 1
186
187 * - Offset
188 - Length
189 - contents
190 * - 0
191 - 16 bytes
192 - PartitionTypeGUID - Secure Block Store GUID
193 * - 16
194 - 16 bytes
195 - UniquePartitionGUID
196 * - 32
197 - 8 bytes
198 - Starting LBA
199 * - 40
200 - 8 bytes
201 - Ending LBA
202 * - 48
203 - 8 bytes
204 - Attributes (e.g. read-only)
205 * - 56
206 - 72 bytes
207 - PartitionName - Holds canonical UUID string for owner.
208
209Design Description
210------------------
211The block storage service provider conforms to the same model as other service providers
212within the TS project. Service requests from clients are received by a service provider
213that is responsible for parameter deserialization/serialization and service level access
214control. Block storage operations are delegated to a backend *block_store* that provides
215block-level storage in some way. There is much flexibility to realize the backend block-level
216storage in different ways, allowing platform integrators to use alternative *block_store*
217realizations to provide storage solutions that meet specific product requirements.
218
219The following class diagram illustrates the block storage service provider model:
220
221.. uml:: uml/BlockStorageProvider.puml
222
223Block Store
224^^^^^^^^^^^
225The *block_store* component defines a virtual interface for block IO operations. Alternative
226concrete *block_store* implementations are supported. Some *block_store* components are stackable
227over other *block_store* components to add features such as store partitioning or block
228authentication. Separation of functionality into stackable *block_store* components gives
229platform integrators the flexibility to create alternative storage solutions with different
230security/cost tradeoffs. The base *block_store* interface is defined in::
231
232 components/service/block_storage/block_store/block_store.h
233
234Components that implement the *block_store* interface are located in subdirectories beneath
235``components/service/block_storage/block_store``. A *block_device* is class of *block_store*
236that actually provides block-level storage. In a stack of *block_store* components, a
237*block_device* will always live at the bottom. The following layer diagram illustrates a
238typical block storage deployment where storage is provided by a stack of *block_store* components:
239
240.. image:: image/block-storage-layers.svg
241
242Some block devices supported in the TS project (located under:
243``components/service/block_storage/block_store/block_device``) are:
244
245 - **ram_block_store** - stores blocks in RAM. Intended for test purposes.
246 - **null_block_store** - a store with no real storage. Always accepts legal writes and returns
247 zeros for reads.
248 - **fvb_block_store** - an adapter that uses a UEFI firmware volume block driver to access
249 storage. Can be used with drivers from the EDK2 project.
250
251Other supported block_store components:
252
253 - **partitioned_block_store** - a stackable *block_store* that presents an underlying *block_store*
254 as a set of configurable storage partitions.
255 - **block_storage_client** - communicates with a remote block storage service provider to provide
256 storage.
257
258--------------
259
260*Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
261
262SPDX-License-Identifier: BSD-3-Clause