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 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 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 */ 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