1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2015-2017, Linaro Limited 4 */ 5 6 #include <crypto/crypto.h> 7 #include <signed_hdr.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <ta_pub_key.h> 11 #include <tee_api_types.h> 12 #include <tee/tee_cryp_utl.h> 13 #include <utee_defines.h> 14 #include <util.h> 15 16 struct shdr *shdr_alloc_and_copy(size_t offs, const void *img, size_t img_size) 17 { 18 size_t shdr_size; 19 struct shdr *shdr; 20 vaddr_t img_va = (vaddr_t)img; 21 vaddr_t tmp = 0; 22 size_t end = 0; 23 24 if (ADD_OVERFLOW(offs, sizeof(struct shdr), &end) || end > img_size) 25 return NULL; 26 27 shdr_size = SHDR_GET_SIZE((const struct shdr *)(img_va + offs)); 28 if (ADD_OVERFLOW(offs, shdr_size, &end) || end > img_size) 29 return NULL; 30 31 if (ADD_OVERFLOW(img_va, shdr_size, &tmp)) 32 return NULL; 33 34 shdr = malloc(shdr_size); 35 if (!shdr) 36 return NULL; 37 memcpy(shdr, (const uint8_t *)img + offs, shdr_size); 38 39 /* Check that the data wasn't modified before the copy was completed */ 40 if (shdr_size != SHDR_GET_SIZE(shdr)) { 41 free(shdr); 42 return NULL; 43 } 44 45 return shdr; 46 } 47 48 TEE_Result shdr_verify_signature(const struct shdr *shdr) 49 { 50 struct rsa_public_key key; 51 TEE_Result res; 52 uint32_t e = TEE_U32_TO_BIG_ENDIAN(ta_pub_key_exponent); 53 size_t hash_size; 54 55 if (shdr->magic != SHDR_MAGIC) 56 return TEE_ERROR_SECURITY; 57 58 if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != TEE_MAIN_ALGO_RSA) 59 return TEE_ERROR_SECURITY; 60 61 res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(shdr->algo), 62 &hash_size); 63 if (res) 64 return TEE_ERROR_SECURITY; 65 if (hash_size != shdr->hash_size) 66 return TEE_ERROR_SECURITY; 67 68 res = crypto_acipher_alloc_rsa_public_key(&key, 69 ta_pub_key_modulus_size * 8); 70 if (res) 71 return TEE_ERROR_SECURITY; 72 73 res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e); 74 if (res) 75 goto out; 76 res = crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size, 77 key.n); 78 if (res) 79 goto out; 80 81 res = crypto_acipher_rsassa_verify(shdr->algo, &key, shdr->hash_size, 82 SHDR_GET_HASH(shdr), shdr->hash_size, 83 SHDR_GET_SIG(shdr), shdr->sig_size); 84 out: 85 crypto_acipher_free_rsa_public_key(&key); 86 if (res) 87 return TEE_ERROR_SECURITY; 88 return TEE_SUCCESS; 89 } 90