1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2015, Linaro Limited
4 */
5 #ifndef SIGNED_HDR_H
6 #define SIGNED_HDR_H
7
8 #include <inttypes.h>
9 #include <stdlib.h>
10 #include <tee_api_types.h>
11 #include <util.h>
12
13 enum shdr_img_type {
14 SHDR_TA = 0,
15 SHDR_BOOTSTRAP_TA = 1,
16 SHDR_ENCRYPTED_TA = 2,
17 SHDR_SUBKEY = 3,
18 };
19
20 #define SHDR_MAGIC 0x4f545348
21
22 /**
23 * struct shdr - signed header
24 * @magic: magic number must match SHDR_MAGIC
25 * @img_type: image type, values defined by enum shdr_img_type
26 * @img_size: image size in bytes
27 * @algo: algorithm, defined by public key algorithms TEE_ALG_*
28 * from TEE Internal API specification
29 * @hash_size: size of the signed hash
30 * @sig_size: size of the signature
31 * @hash: hash of an image
32 * @sig: signature of @hash
33 */
34 struct shdr {
35 uint32_t magic;
36 uint32_t img_type;
37 uint32_t img_size;
38 uint32_t algo;
39 uint16_t hash_size;
40 uint16_t sig_size;
41 /*
42 * Commented out element used to visualize the layout dynamic part
43 * of the struct.
44 *
45 * hash is accessed through the macro SHDR_GET_HASH and
46 * signature is accessed through the macro SHDR_GET_SIG
47 *
48 * uint8_t hash[hash_size];
49 * uint8_t sig[sig_size];
50 */
51 };
52
shdr_get_size(const struct shdr * shdr)53 static inline size_t shdr_get_size(const struct shdr *shdr)
54 {
55 size_t s = sizeof(*shdr);
56
57 if (ADD_OVERFLOW(s, shdr->hash_size, &s) ||
58 ADD_OVERFLOW(s, shdr->sig_size, &s))
59 return 0;
60
61 return s;
62 }
63
64 #define SHDR_GET_SIZE(x) shdr_get_size((x))
65 #define SHDR_GET_HASH(x) (uint8_t *)(((struct shdr *)(x)) + 1)
66 #define SHDR_GET_SIG(x) (SHDR_GET_HASH(x) + (x)->hash_size)
67
68 /**
69 * struct shdr_subkey - subkey header
70 * @uuid: UUID of the subkey
71 * @name_size: The size of a name field that follows right
72 * after this header, before the next signed header.
73 * @subkey_version: Version of the subkey
74 * @max_depth: Maximum depth supported below this subkey
75 * @algo: Algorithm, defined by public key algorithms TEE_ALG_*
76 * from TEE Internal API specification
77 * @attr_count: Number of attributes for the public key matching
78 * @algo.
79 * @attrs: Attributes for the public key matching @algo.
80 * @attrs[].id: Attribute ID TEE_ATTR_* from GlobalPlatform
81 * @attrs[].offs: Offset of the attribute value from start of
82 * struct shdr_subkey
83 * @attrs[].size: Attribute size
84 *
85 * The @uuid defines UUID URN Namespace (RFC4122), the next UUID after this
86 * header (another subkey or a TA) must be in the namespace of this UUID.
87 * This means that further subkeys or TAs have their UUID fixed in the
88 * hierarchy and cannot be moved up or below another subkey.
89 *
90 * If @name_size is non-zero it indicates that a name field of this size
91 * exists and is used to generate the UUID of the following TA or subkey.
92 * If it's zero the following TA or subkey must have a matching UUID.
93 *
94 * The @subkey_version field is used as a rollback measure. The version is
95 * checked against earlier saved values of this subkey. If the latest known
96 * version is less than this the stored value is updated. If the latest
97 * known version is larger than this then the subkey is refused.
98 *
99 * The @max_depth defines how many levels are allowed below this subkey,
100 * the value 0 means only TAs are allowed below. The value 1 means that
101 * eventual subkeys below must have the value 0 in their @max_depth field.
102 *
103 * Each attribute of @attrs must be within range of the image size of this
104 * header defined in the preceding struct shdr.
105 *
106 * The next struct shdr is found right after the indicated end of the
107 * previous struct shdr. Signature verification starts over with the
108 * next struct shdr using this subkey instead of the root key.
109 */
110 struct shdr_subkey {
111 uint8_t uuid[sizeof(TEE_UUID)];
112 uint32_t name_size;
113 uint32_t subkey_version;
114 uint32_t max_depth;
115 uint32_t algo;
116 uint32_t attr_count;
117 struct shdr_subkey_attr {
118 uint32_t id;
119 uint32_t offs;
120 uint32_t size;
121 } attrs[];
122 };
123
124 /**
125 * struct shdr_bootstrap_ta - bootstrap TA subheader
126 * @uuid: UUID of the TA
127 * @ta_version: Version of the TA
128 */
129 struct shdr_bootstrap_ta {
130 uint8_t uuid[sizeof(TEE_UUID)];
131 uint32_t ta_version;
132 };
133
134 /**
135 * struct shdr_encrypted_ta - encrypted TA header
136 * @enc_algo: authenticated encyption algorithm, defined by symmetric key
137 * algorithms TEE_ALG_* from TEE Internal API
138 * specification
139 * @flags: authenticated encyption flags
140 * @iv_size: size of the initialization vector
141 * @tag_size: size of the authentication tag
142 * @iv: initialization vector
143 * @tag: authentication tag
144 */
145 struct shdr_encrypted_ta {
146 uint32_t enc_algo;
147 uint32_t flags;
148 uint16_t iv_size;
149 uint16_t tag_size;
150 /*
151 * Commented out element used to visualize the layout dynamic part
152 * of the struct.
153 *
154 * iv is accessed through the macro SHDR_ENC_GET_IV and
155 * tag is accessed through the macro SHDR_ENC_GET_TAG
156 *
157 * uint8_t iv[iv_size];
158 * uint8_t tag[tag_size];
159 */
160 };
161
162 #define SHDR_ENC_KEY_TYPE_MASK 0x1
163
164 enum shdr_enc_key_type {
165 SHDR_ENC_KEY_DEV_SPECIFIC = 0,
166 SHDR_ENC_KEY_CLASS_WIDE = 1,
167 };
168
shdr_enc_get_size(const struct shdr_encrypted_ta * ehdr)169 static inline size_t shdr_enc_get_size(const struct shdr_encrypted_ta *ehdr)
170 {
171 size_t s = sizeof(*ehdr);
172
173 if (ADD_OVERFLOW(s, ehdr->iv_size, &s) ||
174 ADD_OVERFLOW(s, ehdr->tag_size, &s))
175 return 0;
176
177 return s;
178 }
179
180 #define SHDR_ENC_GET_SIZE(x) shdr_enc_get_size((x))
181 #define SHDR_ENC_GET_IV(x) ((uint8_t *) \
182 (((struct shdr_encrypted_ta *)(x)) + 1))
183 #define SHDR_ENC_GET_TAG(x) ({ typeof(x) _x = (x); \
184 (SHDR_ENC_GET_IV(_x) + _x->iv_size); })
185
186 /*
187 * Allocates a struct shdr large enough to hold the entire header,
188 * excluding a subheader like struct shdr_bootstrap_ta.
189 */
190 struct shdr *shdr_alloc_and_copy(size_t offs, const void *img, size_t img_size);
191
192 /* Frees a previously allocated struct shdr */
shdr_free(struct shdr * shdr)193 static inline void shdr_free(struct shdr *shdr)
194 {
195 free(shdr);
196 }
197
198 struct shdr_pub_key {
199 uint32_t main_algo;
200 uint8_t uuid[sizeof(TEE_UUID)];
201 uint8_t next_uuid[sizeof(TEE_UUID)];
202 uint32_t max_depth;
203 uint32_t name_size;
204 uint32_t version;
205 union {
206 struct rsa_public_key *rsa;
207 } pub_key;
208 };
209
210 TEE_Result shdr_load_pub_key(const struct shdr *shdr, size_t offs,
211 const uint8_t *ns_img, size_t ns_img_size,
212 const uint8_t next_uuid[sizeof(TEE_UUID)],
213 uint32_t max_depth, struct shdr_pub_key *key);
214 void shdr_free_pub_key(struct shdr_pub_key *key);
215 TEE_Result shdr_verify_signature2(struct shdr_pub_key *key,
216 const struct shdr *shdr);
217
218 /*
219 * Verifies the signature in the @shdr.
220 *
221 * Note that the static part of struct shdr and payload still need to be
222 * checked against the hash contained in the header.
223 *
224 * Returns TEE_SUCCESS on success or TEE_ERROR_SECURITY on failure
225 */
226 TEE_Result shdr_verify_signature(const struct shdr *shdr);
227
228 #endif /*SIGNED_HDR_H*/
229