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