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(const struct shdr *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 23 if (img_size < sizeof(struct shdr)) 24 return NULL; 25 26 shdr_size = SHDR_GET_SIZE(img); 27 if (img_size < shdr_size) 28 return NULL; 29 30 if (ADD_OVERFLOW(img_va, shdr_size, &tmp)) 31 return NULL; 32 33 shdr = malloc(shdr_size); 34 if (!shdr) 35 return NULL; 36 memcpy(shdr, img, shdr_size); 37 38 /* Check that the data wasn't modified before the copy was completed */ 39 if (shdr_size != SHDR_GET_SIZE(shdr)) { 40 free(shdr); 41 return NULL; 42 } 43 44 return shdr; 45 } 46 47 TEE_Result shdr_verify_signature(const struct shdr *shdr) 48 { 49 struct rsa_public_key key; 50 TEE_Result res; 51 uint32_t e = TEE_U32_TO_BIG_ENDIAN(ta_pub_key_exponent); 52 size_t hash_size; 53 54 if (shdr->magic != SHDR_MAGIC) 55 return TEE_ERROR_SECURITY; 56 57 if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != TEE_MAIN_ALGO_RSA) 58 return TEE_ERROR_SECURITY; 59 60 res = tee_hash_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(shdr->algo), 61 &hash_size); 62 if (res) 63 return TEE_ERROR_SECURITY; 64 if (hash_size != shdr->hash_size) 65 return TEE_ERROR_SECURITY; 66 67 res = crypto_acipher_alloc_rsa_public_key(&key, shdr->sig_size); 68 if (res) 69 return TEE_ERROR_SECURITY; 70 71 res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e); 72 if (res) 73 goto out; 74 res = crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size, 75 key.n); 76 if (res) 77 goto out; 78 79 res = crypto_acipher_rsassa_verify(shdr->algo, &key, -1, 80 SHDR_GET_HASH(shdr), shdr->hash_size, 81 SHDR_GET_SIG(shdr), shdr->sig_size); 82 out: 83 crypto_acipher_free_rsa_public_key(&key); 84 if (res) 85 return TEE_ERROR_SECURITY; 86 return TEE_SUCCESS; 87 } 88