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