blob: 7dbb8e8d36f7e08a1f1339f1cb9f6f0de63c5b86 [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
Gabor Toth666e2bc2024-12-03 15:42:24 +01008underlying block storage device. The basic storage functionality provided by a
9device can be extended by Stacked Block Stores, which add extra features, like
10encryption or partitioning on top of a device.
Julian Hall1751ce72022-08-30 13:54:13 +010011
12The following diagram illustrates a firmware integration that uses a single block
13storage service provider to control access to a dedicated flash device. In this
14example StMM, OP-TEE, Update Agent and the Protected Storage SP act as clients of
15the service. Each client independently manages its own filesystem and is presented
16with its own logical partition, starting with a logical block address (LBA) of zero.
17
Gabor Toth666e2bc2024-12-03 15:42:24 +010018.. image:: ../image/block-storage-example-usage.svg
Julian Hall1751ce72022-08-30 13:54:13 +010019
20Project Directories
21-------------------
22Components within the Trusted Services project related to the Block Storage service
23are located under the following directories:
24
25.. list-table::
26 :header-rows: 1
27
28 * - Directory
29 - Contains
30 * - ``components/service/block_storage``
31 - Service specific code components.
Gabor Toth666e2bc2024-12-03 15:42:24 +010032 * - ``components/service/block_storage/block_store``
33 - Client, devices, stacked block stores.
Julian Hall1751ce72022-08-30 13:54:13 +010034 * - ``deployments/block-storage``
35 - Build files and deployment specific code for building alternative configurations
36 of the block storage service provider.
37 * - ``protocols/service/block_storage``
38 - Service access protocol definitions.
39
Gabor Toth666e2bc2024-12-03 15:42:24 +010040Design Description
41------------------
42The block storage service provider conforms to the same model as other service providers
43within the TS project. Service requests from clients are received by a service provider
44that is responsible for parameter deserialization/serialization and service level access
45control. Block storage operations are delegated to a backend *block_store* that provides
46block-level storage in some way. There is much flexibility to realize the backend block-level
47storage in different ways, allowing platform integrators to use alternative *block_store*
48realizations to provide storage solutions that meet specific product requirements.
49
50The following class diagram illustrates the block storage service provider model:
51
52.. uml:: ../uml/BlockStorageProvider.puml
53
54Block Store
55^^^^^^^^^^^
56The *block_store* component defines a virtual interface for block IO operations. Alternative
57concrete *block_store* implementations are supported. Some *block_store* components are stackable
58over other *block_store* components to add features such as store partitioning or block
59authentication. Separation of functionality into stackable *block_store* components gives
60platform integrators the flexibility to create alternative storage solutions with different
61security/cost tradeoffs. The base *block_store* interface is defined in::
62
63 components/service/block_storage/block_store/block_store.h
64
65Components that implement the *block_store* interface are located in subdirectories beneath
66``components/service/block_storage/block_store``. A *block_device* is class of *block_store*
67that actually provides block-level storage. In a stack of *block_store* components, a
68*block_device* will always live at the bottom. The following layer diagram illustrates a
69typical block storage deployment where storage is provided by a stack of *block_store* components:
70
71.. image:: ../image/block-storage-layers.svg
72
Julian Hall1751ce72022-08-30 13:54:13 +010073Service Interface
74-----------------
75The Block Storage service supports a conventional set of block-level operations that
76can be adapted to different driver models by clients. The following table summarizes
77supported operations:
78
79.. list-table::
80 :header-rows: 1
81
82 * - Operation
83 - Description
84 * - Open
85 - Open a session - take the required *UniquePartitionGUID* as a parameter. Returns
86 a handle to be used as a qualifier for other requests made by a client.
87 * - Close
88 - Close a previously opened session.
Gabor Toth666e2bc2024-12-03 15:42:24 +010089 * - GetPartitionInfo
Julian Hall1751ce72022-08-30 13:54:13 +010090 - Returns information about the partition associated with an open session. Includes
91 the block size and the total number of blocks assigned to the partition.
92 * - Read
93 - Read data from the specified block.
94 * - Write
95 - Write data to the specified block.
96 * - Erase
97 - Erase a set of one or more blocks.
98
Julian Hall1751ce72022-08-30 13:54:13 +010099The service interface is realized by the block storage service provider. It delegates
100storage operations to a backend *block_store*. The *block_store* defines a common
101interface for components that realize block storage operations. Where an underlying storage
102technology does not support an explicit erase operation (e.g. RPMB), the corresponding
103concrete *block_store* should return success for a call to erase but perform no actual
104operation (if the partition is writable and the LBA falls within the limits of the
105partition).
106
Gabor Toth666e2bc2024-12-03 15:42:24 +0100107Block Store Client
108------------------
Julian Hall1751ce72022-08-30 13:54:13 +0100109
Gabor Toth666e2bc2024-12-03 15:42:24 +0100110Communicates with a remote block storage service provider to provide storage.
111
112Block Store Devices
113-------------------
114
115 - **file_block_store** - stores blocks in file accessed using the standard C file (stdio.h) API.
116 The file represents a contiguous array of storage blocks. Designed to be used in a POSIX
117 environment as a virtual storage media.
118 - **fvb_block_store** - an adapter that uses a UEFI firmware volume block driver to access
119 storage. Can be used with drivers from the EDK2 project.
120 - **mock_block_store** - mocked block store for unit testing.
121 - **null_block_store** - a store with no real storage. Always accepts legal writes and returns
122 zeros for reads.
123 - **ram_block_store** - stores blocks in RAM. Intended for test purposes.
124 - **rpmb_block_store** - it is a Replay Protected Memory Block device
125 (see `SD Association home page`_) that uses the RPMB frontend to provide RPMB based storage.
126 - **semihosting_block_store** - it is a block device that can be used on emulators
127 (FVP, qemu, etc...) or on target platforms where the debugger can provide the file-system
128 semihosting features (See `this page`_.). Semihosting allows accessing files from the host
129 environment. This block store uses a single file to represent a contiguous array of storage
130 blocks.
131
132Stacked Block Stores
133--------------------
134
135Partitioned Block Store
136^^^^^^^^^^^^^^^^^^^^^^^
137
138To allow multiple higher layer filesystems to share the same storage device,
139logical block addresses are partitioned, based on configuration data provided
140by a system integrator. The partition configuration data may be read from a
141GUID Partition Table (GPT) or from the block storage SP manifest. The
142configuration data restricts access to a storage partition to a defined owner.
143Each owner is allocated a maximum number of blocks and is given exclusive access
144to its own blocks, based on the client ID of the calling client.
Julian Hall1751ce72022-08-30 13:54:13 +0100145
146Storage Partition Configuration
Gabor Toth666e2bc2024-12-03 15:42:24 +0100147"""""""""""""""""""""""""""""""
Julian Hall1751ce72022-08-30 13:54:13 +0100148The block storage service allows a block storage device to be presented as a single storage
149partition or as a set of smaller storage partitions. The way that storage is presented is
150determined by configuration data prepared by a platform integrator. Each storage partition
151presented by a block storage service provider starts at LBA zero. The number of partitions
152and their size are defined by configuration data. Configuration data assigns partitions
153to owners to enable access to be controlled. If no partition configuration exists for a
154requesting client or if an attempt is made to access a block outside of the configured LBA
155range, access is denied. The set of storage partitions used for secure block storage will
156not necessarily span the entire underlying storage device. A platform integrator is free to
157limit the area used for secure block storage to allow the storage device to be used for other
158purposes e.g. as a boot source, read by the boot loader during early boot stages.
159
160Two partition configuration methods will be supported; one where partition configuration data
161is read from an SP manifest and the other where configuration is defined by a GUID Partition
162Table. Both methods may be used in combination if necessary. Initial implementations will
163use the SP manifest configuration method.
164
165Each partition configuration entry includes an attributes bitmap that conforms to the UEFI
166GPT Partition Entry attributes definition (see section 5.3 of the UEFI specification). Bits
16748-63 are reserved for GUID specific use. For partitions labelled with the Secure Block Store
168GUID, bits will be defined for:
169
170 - **Read-only** - write and erase operations are forbidden.
171
172A GPT partition entry includes the PartitionName property which normally holds a human readable
173name for the partition. For secure block store partitions, the PartitionName property will
174hold the canonical UUID string identifying the owner. An empty string is interpreted as
175'no specific owner' and any client will be granted access.
176
177Configuration via SP Manifest
178"""""""""""""""""""""""""""""
179For an SP deployment, the partition configuration may be read from a device tree blob (DTB),
180passed as an initialization parameter. Per-partition configuration data comprises the following:
181
182.. list-table::
183 :header-rows: 1
184
185 * - Config Value
186 - Description
187 * - UniquePartitionGUID
188 - GUID that is unique for a partition entry.
189 * - StartingLBA
190 - The storage block address corresponding to LBA zero.
191 * - EndingLBA
192 - The last storage block in the contiguous range of blocks.
193 * - Attributes
194 - See UEFI specification
195 * - Owner
196 - Holds canonical UUID string for owner.
197
198The partition configuration is included as a sub-node of the block-dev node that includes
199configuration values related to the block device. The following is an example of how a block
200device and related partitions are defined within a DT based SP manifest::
201
202 block-dev {
203 compatible = "tforg,ts-block-dev"
204 disk-guid = "af9f72de-d71f-4492-b44b-a4b4d96000bf"
205
206 partitions {
207 compatible = "tforg,ts-block-partitions"
208
209 fwu-meta {
210 guid = "a6f99e90-7a75-4384-847a-29c9a86c6279"
211 start-lba = <0x00000000>
212 end-lba = <0x00000003>
213 attr = <0x00000000>
214 owner = "afb995cd-9354-4333-9ea2-bd62ccaedb22"
215 };
216
217 fip {
218 guid = "1eccc9bc-9a5f-43d0-bcd3-466fd21c9a92"
219 start-lba = <0x00000004>
220 end-lba = <0x00040003>
221 attr = <0x00000000>
222 owner = "afb995cd-9354-4333-9ea2-bd62ccaedb22"
223 };
224
225 uefi-var {
226 guid = "1022a92b-4b4a-47b4-94cb-35faf5a45dc2"
227 start-lba = <0x00040004>
228 end-lba = <0x00080003>
229 attr = <0x00000000>
230 owner = "ed32d533-99e6-4209-9cc0-2d72cdd998a7"
231 };
232 };
233 };
234
235Configuration via GUID Partition Table (GPT)
236""""""""""""""""""""""""""""""""""""""""""""
237The UEFI specification defines a standard layout for physical storage devices where storage
238partitions are described by partition entries within the GUID Partition Table. During
239initialization, the Block Storage SP will read the GPT and iterate over partition entries,
240identifying those with the secure block store partition type GUID. Each entry contains the
241following:
242
243.. list-table::
244 :header-rows: 1
245
246 * - Offset
247 - Length
248 - contents
249 * - 0
250 - 16 bytes
251 - PartitionTypeGUID - Secure Block Store GUID
252 * - 16
253 - 16 bytes
254 - UniquePartitionGUID
255 * - 32
256 - 8 bytes
257 - Starting LBA
258 * - 40
259 - 8 bytes
260 - Ending LBA
261 * - 48
262 - 8 bytes
263 - Attributes (e.g. read-only)
264 * - 56
265 - 72 bytes
266 - PartitionName - Holds canonical UUID string for owner.
267
Gabor Toth666e2bc2024-12-03 15:42:24 +0100268Encrypted Block Store
269^^^^^^^^^^^^^^^^^^^^^
Julian Hall1751ce72022-08-30 13:54:13 +0100270
Gabor Toth666e2bc2024-12-03 15:42:24 +0100271To provide data in rest, and data in transit protection for the stored data using encryption.
272The current implementation uses *AES-CBC with ESSIV* encryption, where the encryption key is
273derived from the Encryption Root key (ERK).
274This way a unique, deterministic, but unpredictable vector is generated for each sector, which
275mitigates IV prediction based attacks, like watermarking attack.
276To implement the algorithm two keys are derived from the root key and generated with the same
277salt value, but with different info:
Julian Hall1751ce72022-08-30 13:54:13 +0100278
Gabor Toth666e2bc2024-12-03 15:42:24 +0100279 - **encryption key** - encryption and decryption of the data (AES with CBC block cipher mode)
280 - **essiv key** - generation of the IV (AES with ECB block cipher mode)
Julian Hall1751ce72022-08-30 13:54:13 +0100281
Gabor Toth666e2bc2024-12-03 15:42:24 +0100282Encrypted Block Store Configuration
283"""""""""""""""""""""""""""""""""""
Julian Hall1751ce72022-08-30 13:54:13 +0100284
Gabor Toth666e2bc2024-12-03 15:42:24 +0100285 - **ENCRYPTED_BLK_AES_KEY_BITS** - determines the size of the keys derived from the root key
286 supported values are 128, 192 and 256.
287 - **ENCRYPTED_BLK_BLOCK_ENCRYPTION_ROOT_KEY** - root key to be used to derive encryption
288 and ESSIV keys from.
289 - **ENCRYPTED_BLK_BLOCK_ENCRYPTION_SALT** - Salt value to make impossible for an attacker to
290 derive the same keys as the ones used for encryption without knowing this value.
Julian Hall1751ce72022-08-30 13:54:13 +0100291
Gabor Toth666e2bc2024-12-03 15:42:24 +0100292Encrypted Block Store Limitations
293"""""""""""""""""""""""""""""""""
Julian Hall1751ce72022-08-30 13:54:13 +0100294
Gabor Toth666e2bc2024-12-03 15:42:24 +0100295 - Block size of the store must be multiple of the AES block size (16 bytes).
296 - Encryption root key is currently a configurable vector in the future it should come from a
297 secure source, like from the Crypto SP or a separate SP responsible for root key storage and
298 key derivation, but in the current implementation
299 - AES with CBC block method encrypts a whole block, where the consecutive AES blocks are
300 interconnected. A drawback of this algorithm is that partial read or write does not
301 work. To mitigate this limitation at read request the whole block is read and only partial
302 data is returned, at write request the read-modify-write methodology is used.
Julian Hall1751ce72022-08-30 13:54:13 +0100303
304--------------
305
Gabor Toth666e2bc2024-12-03 15:42:24 +0100306.. _`SD Association home page`: https://www.sdcard.org/developers/boot-and-new-security-features/replay-protected-memory-block/
307.. _`this page`: https://developer.arm.com/documentation/dui0203/j/semihosting?lang=en
308
Julian Hall1751ce72022-08-30 13:54:13 +0100309*Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
310
311SPDX-License-Identifier: BSD-3-Clause