1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2015-2022, Linaro Limited 4 */ 5 6 #include <crypto/crypto.h> 7 #include <kernel/panic.h> 8 #include <mempool.h> 9 #include <signed_hdr.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <ta_pub_key.h> 13 #include <tee_api_types.h> 14 #include <tee/tee_cryp_utl.h> 15 #include <tee/uuid.h> 16 #include <utee_defines.h> 17 #include <util.h> 18 19 struct shdr *shdr_alloc_and_copy(size_t offs, const void *img, size_t img_size) 20 { 21 size_t shdr_size; 22 struct shdr *shdr; 23 vaddr_t img_va = (vaddr_t)img; 24 vaddr_t tmp = 0; 25 size_t end = 0; 26 27 if (ADD_OVERFLOW(offs, sizeof(struct shdr), &end) || end > img_size) 28 return NULL; 29 30 shdr_size = SHDR_GET_SIZE((const struct shdr *)(img_va + offs)); 31 if (ADD_OVERFLOW(offs, shdr_size, &end) || end > img_size) 32 return NULL; 33 34 if (ADD_OVERFLOW(img_va, shdr_size, &tmp)) 35 return NULL; 36 37 shdr = malloc(shdr_size); 38 if (!shdr) 39 return NULL; 40 memcpy(shdr, (const uint8_t *)img + offs, shdr_size); 41 42 /* Check that the data wasn't modified before the copy was completed */ 43 if (shdr_size != SHDR_GET_SIZE(shdr)) { 44 free(shdr); 45 return NULL; 46 } 47 48 return shdr; 49 } 50 51 static bool is_weak_hash_algo(uint32_t algo) 52 { 53 return algo == TEE_ALG_MD5 || algo == TEE_ALG_SHA1 || 54 algo == TEE_ALG_MD5SHA1; 55 } 56 57 TEE_Result shdr_verify_signature(const struct shdr *shdr) 58 { 59 struct rsa_public_key key = { }; 60 TEE_Result res = TEE_SUCCESS; 61 uint32_t e = TEE_U32_TO_BIG_ENDIAN(ta_pub_key_exponent); 62 size_t hash_size = 0; 63 size_t hash_algo = 0; 64 65 if (shdr->magic != SHDR_MAGIC) 66 return TEE_ERROR_SECURITY; 67 68 if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != TEE_MAIN_ALGO_RSA) 69 return TEE_ERROR_SECURITY; 70 71 hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo); 72 if (is_weak_hash_algo(hash_algo)) 73 return TEE_ERROR_SECURITY; 74 75 res = tee_alg_get_digest_size(hash_algo, &hash_size); 76 if (res) 77 return TEE_ERROR_SECURITY; 78 if (hash_size != shdr->hash_size) 79 return TEE_ERROR_SECURITY; 80 81 res = crypto_acipher_alloc_rsa_public_key(&key, 82 ta_pub_key_modulus_size * 8); 83 if (res) 84 return TEE_ERROR_SECURITY; 85 86 res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e); 87 if (res) 88 goto out; 89 res = crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size, 90 key.n); 91 if (res) 92 goto out; 93 94 res = crypto_acipher_rsassa_verify(shdr->algo, &key, shdr->hash_size, 95 SHDR_GET_HASH(shdr), shdr->hash_size, 96 SHDR_GET_SIG(shdr), shdr->sig_size); 97 out: 98 crypto_acipher_free_rsa_public_key(&key); 99 if (res) 100 return TEE_ERROR_SECURITY; 101 return TEE_SUCCESS; 102 } 103 104 static const struct shdr_subkey_attr * 105 find_attr(const struct shdr_subkey *subkey, uint32_t id) 106 { 107 size_t n = 0; 108 109 for (n = 0; n < subkey->attr_count; n++) 110 if (subkey->attrs[n].id == id) 111 return subkey->attrs + n; 112 113 return NULL; 114 } 115 116 static TEE_Result load_rsa_key(const struct shdr_subkey *subkey, 117 struct rsa_public_key **key_pp) 118 { 119 const uint8_t *base = (const uint8_t *)subkey; 120 const struct shdr_subkey_attr *pub_exp = NULL; 121 const struct shdr_subkey_attr *modulus = NULL; 122 struct rsa_public_key *key = NULL; 123 TEE_Result res = TEE_SUCCESS; 124 125 pub_exp = find_attr(subkey, TEE_ATTR_RSA_PUBLIC_EXPONENT); 126 if (!pub_exp) 127 return TEE_ERROR_SECURITY; 128 modulus = find_attr(subkey, TEE_ATTR_RSA_MODULUS); 129 if (!modulus) 130 return TEE_ERROR_SECURITY; 131 132 key = calloc(1, sizeof(*key)); 133 if (!key) 134 return TEE_ERROR_OUT_OF_MEMORY; 135 res = crypto_acipher_alloc_rsa_public_key(key, modulus->size * 8); 136 if (res) 137 goto err_key; 138 139 res = crypto_bignum_bin2bn(base + pub_exp->offs, pub_exp->size, key->e); 140 if (res) 141 goto err; 142 res = crypto_bignum_bin2bn(base + modulus->offs, modulus->size, key->n); 143 if (res) 144 goto err; 145 146 *key_pp = key; 147 return TEE_SUCCESS; 148 err: 149 crypto_acipher_free_rsa_public_key(key); 150 err_key: 151 free(key); 152 return TEE_ERROR_SECURITY; 153 } 154 155 static TEE_Result check_attrs(const struct shdr_subkey *subkey, size_t img_size) 156 { 157 const struct shdr_subkey_attr *attrs = subkey->attrs; 158 size_t end = 0; 159 size_t n = 0; 160 161 if (MUL_OVERFLOW(subkey->attr_count, sizeof(*attrs), &end) || 162 ADD_OVERFLOW(end, sizeof(*subkey), &end) || 163 end > img_size) 164 return TEE_ERROR_SECURITY; 165 166 for (n = 0; n < subkey->attr_count; n++) 167 if (ADD_OVERFLOW(attrs[n].offs, attrs[n].size, &end) || 168 end > img_size) 169 return TEE_ERROR_SECURITY; 170 171 return TEE_SUCCESS; 172 } 173 174 static TEE_Result calc_next_uuid(uint8_t uuid[sizeof(TEE_UUID)], 175 const uint8_t my_uuid[sizeof(TEE_UUID)], 176 const void *ns_name, size_t name_size) 177 { 178 TEE_Result res = TEE_ERROR_SECURITY; 179 void *ctx = NULL; 180 struct { 181 uint8_t digest[TEE_SHA1_HASH_SIZE]; 182 TEE_UUID uuid; 183 char name_str[]; 184 } *tmp = NULL; 185 186 if (!name_size) { 187 memcpy(uuid, my_uuid, sizeof(TEE_UUID)); 188 return TEE_SUCCESS; 189 } 190 191 /* 192 * RFC 4122 requires a SHA-1 digest for UUID v5. Use SHA-512 193 * instead for better collision resistance. 194 */ 195 if (crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA512)) 196 return TEE_ERROR_SECURITY; 197 198 tmp = mempool_alloc(mempool_default, sizeof(*tmp) + name_size); 199 if (!tmp) 200 goto out_ctx; 201 memcpy(tmp->name_str, ns_name, name_size); 202 203 if (crypto_hash_init(ctx) || 204 crypto_hash_update(ctx, my_uuid, sizeof(TEE_UUID)) || 205 crypto_hash_update(ctx, (const void *)tmp->name_str, 206 strnlen(tmp->name_str, name_size)) || 207 crypto_hash_final(ctx, tmp->digest, sizeof(tmp->digest))) 208 goto out_mempool; 209 210 tee_uuid_from_octets(&tmp->uuid, tmp->digest); 211 /* 212 * Set the four most significant bits (bits 12 through 15) of the 213 * time_hi_and_version field to 5. 214 */ 215 tmp->uuid.timeHiAndVersion &= ~SHIFT_U32(0xf, 12); 216 tmp->uuid.timeHiAndVersion |= SHIFT_U32(5, 12); 217 /* 218 * Set the two most significant bits (bits 6 and 7) of the 219 * clock_seq_hi_and_reserved to zero and one, respectively. 220 */ 221 tmp->uuid.clockSeqAndNode[0] &= ~BIT(6); 222 tmp->uuid.clockSeqAndNode[0] |= BIT(7); 223 224 tee_uuid_to_octets(uuid, &tmp->uuid); 225 res = TEE_SUCCESS; 226 227 out_mempool: 228 mempool_free(mempool_default, tmp); 229 out_ctx: 230 crypto_hash_free_ctx(ctx); 231 232 return res; 233 } 234 235 TEE_Result shdr_load_pub_key(const struct shdr *shdr, size_t offs, 236 const uint8_t *ns_img, size_t ns_img_size, 237 const uint8_t next_uuid[sizeof(TEE_UUID)], 238 uint32_t max_depth, struct shdr_pub_key *key) 239 { 240 struct shdr_subkey *subkey = NULL; 241 TEE_Result res = TEE_SUCCESS; 242 void *digest = NULL; 243 uint8_t *img = NULL; 244 void *ctx = NULL; 245 size_t end = 0; 246 247 if (shdr->img_type != SHDR_SUBKEY) 248 return TEE_ERROR_SECURITY; 249 250 if (shdr->img_size < sizeof(*subkey)) 251 return TEE_ERROR_SECURITY; 252 253 if (ADD_OVERFLOW(shdr->img_size, offs, &end) || end > ns_img_size) 254 return TEE_ERROR_SECURITY; 255 256 img = mempool_alloc(mempool_default, shdr->img_size + shdr->hash_size); 257 if (!img) 258 return TEE_ERROR_OUT_OF_MEMORY; 259 memcpy(img + shdr->hash_size, ns_img + offs, shdr->img_size); 260 subkey = (void *)(img + shdr->hash_size); 261 digest = img; 262 263 if (crypto_hash_alloc_ctx(&ctx, TEE_DIGEST_HASH_TO_ALGO(shdr->algo))) { 264 res = TEE_ERROR_SECURITY; 265 goto out_mempool; 266 } 267 268 if (crypto_hash_init(ctx) || 269 crypto_hash_update(ctx, (const void *)shdr, sizeof(*shdr)) || 270 crypto_hash_update(ctx, (const void *)subkey, shdr->img_size) || 271 crypto_hash_final(ctx, digest, shdr->hash_size) || 272 memcmp(digest, SHDR_GET_HASH(shdr), shdr->hash_size)) { 273 res = TEE_ERROR_SECURITY; 274 goto out_ctx; 275 } 276 277 res = check_attrs(subkey, shdr->img_size); 278 if (res) 279 goto out_ctx; 280 281 if (subkey->max_depth >= max_depth) { 282 res = TEE_ERROR_SECURITY; 283 goto out_ctx; 284 } 285 if (next_uuid && memcmp(next_uuid, subkey->uuid, sizeof(TEE_UUID))) { 286 res = TEE_ERROR_SECURITY; 287 goto out_ctx; 288 } 289 290 key->max_depth = subkey->max_depth; 291 key->name_size = subkey->name_size; 292 memcpy(key->uuid, subkey->uuid, sizeof(TEE_UUID)); 293 if (ADD_OVERFLOW(key->name_size, offs + shdr->img_size, &end) || 294 end > ns_img_size) { 295 res = TEE_ERROR_SECURITY; 296 goto out_ctx; 297 } 298 res = calc_next_uuid(key->next_uuid, key->uuid, 299 ns_img + offs + shdr->img_size, key->name_size); 300 if (res) 301 goto out_ctx; 302 303 key->main_algo = TEE_ALG_GET_MAIN_ALG(subkey->algo); 304 switch (key->main_algo) { 305 case TEE_MAIN_ALGO_RSA: 306 res = load_rsa_key(subkey, &key->pub_key.rsa); 307 break; 308 default: 309 res = TEE_ERROR_SECURITY; 310 break; 311 } 312 313 out_ctx: 314 crypto_hash_free_ctx(ctx); 315 out_mempool: 316 mempool_free(mempool_default, img); 317 return res; 318 } 319 320 void shdr_free_pub_key(struct shdr_pub_key *key) 321 { 322 if (key) { 323 switch (key->main_algo) { 324 case TEE_MAIN_ALGO_RSA: 325 crypto_acipher_free_rsa_public_key(key->pub_key.rsa); 326 free(key->pub_key.rsa); 327 break; 328 default: 329 panic(); 330 } 331 } 332 } 333 334 TEE_Result shdr_verify_signature2(struct shdr_pub_key *key, 335 const struct shdr *shdr) 336 { 337 size_t hash_size = 0; 338 size_t hash_algo = 0; 339 340 if (shdr->magic != SHDR_MAGIC) 341 return TEE_ERROR_SECURITY; 342 343 if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != key->main_algo) 344 return TEE_ERROR_SECURITY; 345 346 hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo); 347 if (is_weak_hash_algo(hash_algo)) 348 return TEE_ERROR_SECURITY; 349 350 if (tee_alg_get_digest_size(hash_algo, &hash_size) || 351 hash_size != shdr->hash_size) 352 return TEE_ERROR_SECURITY; 353 354 switch (key->main_algo) { 355 case TEE_MAIN_ALGO_RSA: 356 if (crypto_acipher_rsassa_verify(shdr->algo, key->pub_key.rsa, 357 shdr->hash_size, 358 SHDR_GET_HASH(shdr), 359 shdr->hash_size, 360 SHDR_GET_SIG(shdr), 361 shdr->sig_size)) 362 return TEE_ERROR_SECURITY; 363 break; 364 default: 365 panic(); 366 } 367 368 return TEE_SUCCESS; 369 } 370