summaryrefslogtreecommitdiff
path: root/documentation/secure_storage_rpmb.md
blob: 7ac2304a1221d388831c788099f5b547fb15b932 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# RPMB Secure Storage

## Introduction

This document describes the RPMB secure storage implementation in OP-TEE,
which is enabled by setting CFG_RPMB_FS=y. Trusted Applications may use
this implementation by passing a storage ID equal to
TEE_STORAGE_PRIVATE_RPMB, or TEE_STORAGE_PRIVATE if CFG_REE_FS is disabled.
For details about RPMB, please refer to the JEDEC eMMC specification
[[1]](#JEDECeMMC).

The architecture is depicted below.

```
            NORMAL WORLD           :            SECURE WORLD
                                   :
 U        tee-supplicant           :        Trusted application
 S           (rpmb.c)              :        (secure storage API)
 E         ^          ^            :                  ^
 R         |          |            :~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~ ioctl ~~~~~~~|~~~~~~~~~~~~:                  v
 K         |          |            :               OP-TEE
 E         v          v            :         (tee_svc_storage.c)
 R  MMC/SD subsys.  OP-TEE driver  : (tee_rpmb_fs.c, tee_fs_key_manager.c)
 N         ^                 ^     :                  ^
 E         |                 |     :                  |
 L         v                 |     :                  |
     Controller driver       |     :                  |
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~
                             v                        v
                           Secure monitor / EL3 firmware
```

For information about the `ioctl()` interface to the MMC/SD subsystem in the
Linux kernel, see the Linux core MMC header file [[2]](#mmc-core-h) and the
mmc-utils repository [[3]](#mmc-utils).

## The Secure Storage API

This part is common with the REE-based filesystem. The interface between the
system calls in [core/tee/tee_svc_storage.c](../core/tee/tee_svc_storage.c) and
the RPMB filesystem is the **tee_file_operations** structure `tee_file_ops`.

## The RPMB filesystem

The FS implementation is entirely in
[core/tee/tee_rpmb_fs.c](../core/tee/tee_rpmb_fs.c).

The RPMB partition is divided in three parts:

- The first 128 bytes are reserved for partition data (struct
**rpmb_fs_partition**).
- At offset 512 is the File Allocation Table (FAT). It is an array of
struct **rpmb_fat_entry** elements, one per file. The FAT grows dynamically as
files are added to the filesystem. Among other things, each entry has the start
address for the file data, its size, and the filename.
- Starting from the end of the RPMB partition and extending downwards is the
file data area.

Space in the partition is allocated by the general-purpose allocator functions:
`tee_mm_alloc()` and `tee_mm_alloc2()`.

All file operations are atomic. This is achieved thanks to the following
properties:
- Writing one single block of data to the RPMB partition is guaranteed to be
atomic by the eMMC specification.
- The FAT block for the modified file is always updated last, after data have
been written successfully.
- Updates to file content is done in-place only if the data do not span more
than the "reliable write block count" blocks. Otherwise, or if the file needs
to be extended, a new file is created.

## Device access

There is no eMMC controller driver in OP-TEE. The device operations all have to
go through the normal world. They are handled by the `tee-supplicant` process
which further relies on the kernel's `ioctl()` interface to access the device.
`tee-supplicant` also has an emulation mode which implements a virtual RPMB
device for test purposes.

RPMB operations are the following:
- Reading device information (partition size, reliable write block count)
- Programming the security key. This key is used for authentication purposes.
Note that it is different from the Secure Storage Key (SSK) defined below, which
is used for encryption. Like the SSK however, the security key is also derived
from a hardware unique key or identifier. Currently, the function
`tee_otp_get_hw_unique_key()` is used to generate the RPMB security key.
- Reading the write counter value. The write counter is used in the HMAC
computation during read and write requests. The value is read at initialization
time, and stored in the **tee_rpmb_ctx** structure, `rpmb_ctx->wr_cnt`.
- Reading or writing blocks of data

RPMB operations are initiated on request from the FS layer. Memory buffers for
requests and responses are allocated in shared memory using
`thread_optee_rpc_alloc_payload()`.
Buffers are passed to the normal world in a `TEE_RPC_RPMB_CMD` message, thanks
to the `thread_rpc_cmd()` function. Most RPMB requests and responses use the
data frame format defined by the JEDEC eMMC specification.

HMAC authentication is implemented here also.

## Encryption

The FS encryption routines are in [core/tee/tee_fs_key_manager.c](../core/tee/tee_fs_key_manager.c).

Block encryption protects file data. The algorithm is 128-bit AES in Cipher Block Chaining
(CBC) mode with Encrypted Salt-Sector Initialization Vector (ESSIV)
[[4]](#CBC-ESSIV).

- During OP-TEE initialization, a 128-bit AES Secure Storage Key (SSK) is
derived from a Hardware Unique Key (HUK). It is kept in secure memory and never
written to disk. A Trusted Application Storage Key is derived from the SSK and
the TA UUID.
- For each file, a 128-bit encrypted File Encryption Key (FEK) is randomly
generated when the file is created, encrypted with the TSK and stored in the FAT
entry for the file.
- Each 256-byte block of data is then encrypted in CBC mode. The initialization
vector is obtained by the ESSIV algorithm, that is, by encrypting the block
number with a hash of the FEK. This allows direct access to any block in the
file, as follows:
```
    FEK = AES-Decrypt(TSK, encrypted FEK);
    k = SHA256(FEK);
    IV = AES-Encrypt(128 bits of k, block index padded to 16 bytes)
	Encrypted block = AES-CBC-Encrypt(FEK, IV, block data);
	Decrypted block = AES-CBC-Decrypt(FEK, IV, encrypted block data);
```


SSK, TSK and FEK handling is common with the REE-based secure storage, while the AES
CBC block encryption is used only for RPMB (the REE implementation uses GCM).

The FAT is not encrypted.

## References

- <a name="JEDECeMMC"></a>[1] _Embedded Multi-Media Card (e•MMC) Electrical Standard (5.1)_, JEDEC JESD84-B51, February 2015
- <a name="mmc-core-h"></a>[2] [linux/mmc/core.h](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/mmc/core.h), Linux kernel sources
- <a name="mmc-utils"></a>[3] The [mmc-utils](http://git.kernel.org/cgit/linux/kernel/git/cjb/mmc-utils.git) repository
- <a name="CBC-ESSIV"></a>[4] [_Cipher Block Chaining_](https://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29),
Wikipedia