blob: 9ca6abd8891e9490ee22f0adf680bbc0da61cbee [file] [log] [blame]
Jens Wiklandere5010392022-10-14 08:58:27 +02001.. _subkeys:
2
3#######
4Subkeys
5#######
6Subkeys is an OP-TEE-specific implementation to provide a public key
7hierarchy. Subkeys can be delegated to allow different actors to sign
8different TAs without sharing a private key.
9
10The first key in the chain is verified using a root key. Example Subkey
11hierarchy:
12
13
14.. uml::
15 :width: 800
16
17 object "Root key" as root
18 object "First-level subkey" as first
19 object "Second-level subkey" as second
20
21 object root {
22 PublicKey
23 }
24
25 object first {
26 Signature
27 UUID
28 PublicKey
29 }
30
31 object second {
32 Signature
33 UUID
34 PublicKey
35 }
36
37 root -> first
38 first -> second
39
40Each subkey defines a UUIDv5 namespace [#f1]_ to which another signed
41subkey or TA must belong. This avoids that one subkey can be used to sign
42TAs which should be signed with a different key. Since the UUIDs are
43restricted by this there is also a special kind of subkey, called identity
44subkey, which uses the same UUID as the TA it is supposed to sign.
45
46A subkey consists of two files, a private key pair in a .pem file and the
47signed public key in a .bin file. Subkeys reuse the signed header (SHDR)
48format used for signed TAs, followed by a payload holding a public key and
49UUID among other fields. A subkey is formatted with all fields in
50little endian as:
51
52+-----------+-------------------+---------------------+-----------------------+
53| Size in | Field Name | Protected by field | |
54| bytes | | | |
55+-----------+-------------------+---------------------+-----------------------+
56| .. centered:: Signed header (struct shdr) | |
57+-----------+-------------------+---------------------+-----------------------+
58| 4 | magic | hash | 0x4f545348 |
59+-----------+-------------------+---------------------+-----------------------+
60| 4 | img_type | hash | 3, SHDR_SUBKEY |
61+-----------+-------------------+---------------------+-----------------------+
62| 4 | img_size | hash | |
63+-----------+-------------------+---------------------+-----------------------+
64| 4 | algo | hash | Signature algorithm, |
65| | | | GP TEE_ALG_* |
66+-----------+-------------------+---------------------+-----------------------+
67| 4 | hash_size | hash | |
68+-----------+-------------------+---------------------+-----------------------+
69| 4 | sig_size | hash | |
70+-----------+-------------------+---------------------+-----------------------+
71| hash_size | hash | sig | |
72+-----------+-------------------+---------------------+-----------------------+
73| sig_size | sig | previous pub key | Root key or a subkey |
74| | | | higher up in the |
75| | | | chain |
76+-----------+-------------------+---------------------+-----------------------+
77| .. centered:: Subkey header (struct shdr_subkey) | |
78+-----------+-------------------+---------------------+-----------------------+
79| 16 | UUID | hash | UUIDv5 namespace for |
80| | | | next subkey or TA |
81+-----------+-------------------+---------------------+-----------------------+
82| 4 | name_size | hash | Size of the UUIDv5 |
83| | | | name for the |
84| | | | next subkey or TA, |
85| | | | 0 for identiy subkeys |
86+-----------+-------------------+---------------------+-----------------------+
87| 4 | subkey_version | hash | |
88+-----------+-------------------+---------------------+-----------------------+
89| 4 | max_depth | hash | |
90+-----------+-------------------+---------------------+-----------------------+
91| 4 | algo | hash | Signature algorithm |
92| | | | for the next |
93| | | | subkey or TA |
94+-----------+-------------------+---------------------+-----------------------+
95| 4 | attr_count | hash | |
96+-----------+-------------------+---------------------+-----------------------+
97| | .. centered:: Subkey attrs * attr_count | Attributes of the |
98| | | public key in this |
99| | | subkey |
100+-----------+-------------------+---------------------+-----------------------+
101| 4 | id | hash | GP TEE_ATTR_* |
102+-----------+-------------------+---------------------+-----------------------+
103| 4 | offs | hash | |
104+-----------+-------------------+---------------------+-----------------------+
105| 4 | size | hash | |
106+-----------+-------------------+---------------------+-----------------------+
107| opaque data padding up this | hash | The subkey attributes |
108| binary to img_size | | above point into |
109| | | this area using |
110| | | offset and size |
111+-------------------------------+---------------------+-----------------------+
112
113All subkeys included in the subkey hierarchy are added in front when a TA
114is signed using a subkey. For example, if a TA is signed using the
115second-level subkey above it would look like this:
116
117+------------------+----------------------+-----------------------------------+
118| Size in bytes | Binary | |
119+------------------+----------------------+-----------------------------------+
120| first.img_size | First-level subkey | Signed by Root key |
121+------------------+----------------------+-----------------------------------+
122| first.name_size | UUIDv5 name string | Not signed, used to prove that |
123| | for the next subkey | the next UUID is in the namespace |
124| | | of the First-level subkey. |
125| | | This size is from "name_size" |
126| | | of the previous subkey |
127| | | (First-level). |
128+------------------+----------------------+-----------------------------------+
129| second.img_size | Second-level subkey | Signed by First-level subkey |
130+------------------+----------------------+-----------------------------------+
131| second.name_size | UUIDv5 name string | Not signed used to prove that |
132| | for the TA | the next UUID is in the namespace |
133| | | of the Second-level subkey. |
134| | | This size is from "name_size" |
135| | | of the previous subkey |
136| | | (Second-level). |
137+------------------+----------------------+-----------------------------------+
138| second.img_size | TA | Signed by Second-level subkey |
139+------------------+----------------------+-----------------------------------+
140
141The signed TA binary is self-contained with all the public keys
142needed for verification included, except the public root key which is
143embedded in the TEE core binary.
144
145The UUIDv5 name string is a separate field between subkeys and the next
146subkey or TA to allow a subkey to be used to sign more than one other
147subkey or TA.
148
149A signed TA or subkey can be inspected using the sign_encrypt.py script,
150for example::
151
152 $ scripts/sign_encrypt.py display --in 5c206987-16a3-59cc-ab0f-64b9cfc9e758.ta
153 Subkey
154 struct shdr
155 magic: 0x4f545348
156 img_type: 3 (SHDR_SUBKEY)
157 img_size: 320 bytes
158 algo: 0x70414930 (TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256)
159 hash_size: 32 bytes
160 sig_size: 256 bytes
161 hash: f573f329fe77be686ce71647909c4ea35b5e1cd7de86369bd7d9fca31f6a4d65
162 struct shdr_subkey
163 uuid: f04fa996-148a-453c-b037-1dcfbad120a6
164 name_size: 64
165 subkey_version: 1
166 max_depth: 4
167 algo: 0x70414930 (TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256)
168 attr_count: 2
169 next name: "mid_level_subkey"
170 Next header at offset: 692 (0x2b4)
171 Subkey
172 struct shdr
173 magic: 0x4f545348
174 img_type: 3 (SHDR_SUBKEY)
175 img_size: 320 bytes
176 algo: 0x70414930 (TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256)
177 hash_size: 32 bytes
178 sig_size: 256 bytes
179 hash: 233a6dcf1a2cf69e50cde8e20c4129157da707c76fa86ce12ee31037edef02d7
180 struct shdr_subkey
181 uuid: 1a5948c5-1aa0-518c-86f4-be6f6a057b16
182 name_size: 64
183 subkey_version: 1
184 max_depth: 3
185 algo: 0x70414930 (TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256)
186 attr_count: 2
187 next name: "subkey1_ta"
188 Next header at offset: 1384 (0x568)
189 Bootstrap TA
190 struct shdr
191 magic: 0x4f545348
192 img_type: 1 (SHDR_BOOTSTRAP_TA)
193 img_size: 84576 bytes
194 algo: 0x70414930 (TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256)
195 hash_size: 32 bytes
196 sig_size: 256 bytes
197 hash: ea31ac7dc2cc06a9dc2853cd791dd00f784b5edc062ecfa274deeb66589b4ca5
198 struct shdr_bootstrap_ta
199 uuid: 5c206987-16a3-59cc-ab0f-64b9cfc9e758
200 ta_version: 0
201 TA offset: 1712 (0x6b0) bytes
202 TA size: 84576 (0x14a60) bytes
203
204
205.. rubric:: Footnotes
206
207.. [#f1] UUIDv5 and namespaces are described in
208 `RFC4122 <https://datatracker.ietf.org/doc/html/rfc4122>`_.
209 Note that OP-TEE uses a truncated SHA-512 instead of the
210 weak SHA-1 hash when when deriving a new UUID from a
211 namespace and name.