1fb7ef469SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2064663e8SJens Wiklander /* 3c34d0d91SJens Wiklander * Copyright (c) 2015-2022, Linaro Limited 4064663e8SJens Wiklander */ 5064663e8SJens Wiklander 6064663e8SJens Wiklander #include <crypto/crypto.h> 7c34d0d91SJens Wiklander #include <kernel/panic.h> 8c34d0d91SJens Wiklander #include <mempool.h> 9064663e8SJens Wiklander #include <signed_hdr.h> 10064663e8SJens Wiklander #include <stdlib.h> 11064663e8SJens Wiklander #include <string.h> 12064663e8SJens Wiklander #include <ta_pub_key.h> 13064663e8SJens Wiklander #include <tee_api_types.h> 14064663e8SJens Wiklander #include <tee/tee_cryp_utl.h> 15c34d0d91SJens Wiklander #include <tee/uuid.h> 16064663e8SJens Wiklander #include <utee_defines.h> 17062765e4SJerome Forissier #include <util.h> 18064663e8SJens Wiklander 19ec1aa4faSJens Wiklander struct shdr *shdr_alloc_and_copy(size_t offs, const void *img, size_t img_size) 20064663e8SJens Wiklander { 21064663e8SJens Wiklander size_t shdr_size; 22064663e8SJens Wiklander struct shdr *shdr; 23062765e4SJerome Forissier vaddr_t img_va = (vaddr_t)img; 24062765e4SJerome Forissier vaddr_t tmp = 0; 25ec1aa4faSJens Wiklander size_t end = 0; 26064663e8SJens Wiklander 27ec1aa4faSJens Wiklander if (ADD_OVERFLOW(offs, sizeof(struct shdr), &end) || end > img_size) 284ca9e426SJoakim Bech return NULL; 294ca9e426SJoakim Bech 30ec1aa4faSJens Wiklander shdr_size = SHDR_GET_SIZE((const struct shdr *)(img_va + offs)); 31ec1aa4faSJens Wiklander if (ADD_OVERFLOW(offs, shdr_size, &end) || end > img_size) 324ca9e426SJoakim Bech return NULL; 33064663e8SJens Wiklander 34062765e4SJerome Forissier if (ADD_OVERFLOW(img_va, shdr_size, &tmp)) 35062765e4SJerome Forissier return NULL; 36062765e4SJerome Forissier 37064663e8SJens Wiklander shdr = malloc(shdr_size); 38064663e8SJens Wiklander if (!shdr) 39064663e8SJens Wiklander return NULL; 40ec1aa4faSJens Wiklander memcpy(shdr, (const uint8_t *)img + offs, shdr_size); 41064663e8SJens Wiklander 42064663e8SJens Wiklander /* Check that the data wasn't modified before the copy was completed */ 43064663e8SJens Wiklander if (shdr_size != SHDR_GET_SIZE(shdr)) { 44064663e8SJens Wiklander free(shdr); 45064663e8SJens Wiklander return NULL; 46064663e8SJens Wiklander } 47064663e8SJens Wiklander 48064663e8SJens Wiklander return shdr; 49064663e8SJens Wiklander } 50064663e8SJens Wiklander 51*bef7d11dSJens Wiklander static bool is_weak_hash_algo(uint32_t algo) 52*bef7d11dSJens Wiklander { 53*bef7d11dSJens Wiklander return algo == TEE_ALG_MD5 || algo == TEE_ALG_SHA1 || 54*bef7d11dSJens Wiklander algo == TEE_ALG_MD5SHA1; 55*bef7d11dSJens Wiklander } 56*bef7d11dSJens Wiklander 57064663e8SJens Wiklander TEE_Result shdr_verify_signature(const struct shdr *shdr) 58064663e8SJens Wiklander { 59*bef7d11dSJens Wiklander struct rsa_public_key key = { }; 60*bef7d11dSJens Wiklander TEE_Result res = TEE_SUCCESS; 61064663e8SJens Wiklander uint32_t e = TEE_U32_TO_BIG_ENDIAN(ta_pub_key_exponent); 62*bef7d11dSJens Wiklander size_t hash_size = 0; 63*bef7d11dSJens Wiklander size_t hash_algo = 0; 64064663e8SJens Wiklander 65064663e8SJens Wiklander if (shdr->magic != SHDR_MAGIC) 66064663e8SJens Wiklander return TEE_ERROR_SECURITY; 67064663e8SJens Wiklander 68064663e8SJens Wiklander if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != TEE_MAIN_ALGO_RSA) 69064663e8SJens Wiklander return TEE_ERROR_SECURITY; 70064663e8SJens Wiklander 71*bef7d11dSJens Wiklander hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo); 72*bef7d11dSJens Wiklander if (is_weak_hash_algo(hash_algo)) 73*bef7d11dSJens Wiklander return TEE_ERROR_SECURITY; 74*bef7d11dSJens Wiklander 75*bef7d11dSJens Wiklander res = tee_alg_get_digest_size(hash_algo, &hash_size); 76064663e8SJens Wiklander if (res) 77064663e8SJens Wiklander return TEE_ERROR_SECURITY; 78064663e8SJens Wiklander if (hash_size != shdr->hash_size) 79064663e8SJens Wiklander return TEE_ERROR_SECURITY; 80064663e8SJens Wiklander 8144c8e3cbSCedric Neveux res = crypto_acipher_alloc_rsa_public_key(&key, 8244c8e3cbSCedric Neveux ta_pub_key_modulus_size * 8); 83064663e8SJens Wiklander if (res) 84064663e8SJens Wiklander return TEE_ERROR_SECURITY; 85064663e8SJens Wiklander 86064663e8SJens Wiklander res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e); 87064663e8SJens Wiklander if (res) 88064663e8SJens Wiklander goto out; 89064663e8SJens Wiklander res = crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size, 90064663e8SJens Wiklander key.n); 91064663e8SJens Wiklander if (res) 92064663e8SJens Wiklander goto out; 93064663e8SJens Wiklander 942139aa8cSJens Wiklander res = crypto_acipher_rsassa_verify(shdr->algo, &key, shdr->hash_size, 95064663e8SJens Wiklander SHDR_GET_HASH(shdr), shdr->hash_size, 96064663e8SJens Wiklander SHDR_GET_SIG(shdr), shdr->sig_size); 97064663e8SJens Wiklander out: 98064663e8SJens Wiklander crypto_acipher_free_rsa_public_key(&key); 99064663e8SJens Wiklander if (res) 100064663e8SJens Wiklander return TEE_ERROR_SECURITY; 101064663e8SJens Wiklander return TEE_SUCCESS; 102064663e8SJens Wiklander } 103c34d0d91SJens Wiklander 104c34d0d91SJens Wiklander static const struct shdr_subkey_attr * 105c34d0d91SJens Wiklander find_attr(const struct shdr_subkey *subkey, uint32_t id) 106c34d0d91SJens Wiklander { 107c34d0d91SJens Wiklander size_t n = 0; 108c34d0d91SJens Wiklander 109c34d0d91SJens Wiklander for (n = 0; n < subkey->attr_count; n++) 110c34d0d91SJens Wiklander if (subkey->attrs[n].id == id) 111c34d0d91SJens Wiklander return subkey->attrs + n; 112c34d0d91SJens Wiklander 113c34d0d91SJens Wiklander return NULL; 114c34d0d91SJens Wiklander } 115c34d0d91SJens Wiklander 116c34d0d91SJens Wiklander static TEE_Result load_rsa_key(const struct shdr_subkey *subkey, 117c34d0d91SJens Wiklander struct rsa_public_key **key_pp) 118c34d0d91SJens Wiklander { 119c34d0d91SJens Wiklander const uint8_t *base = (const uint8_t *)subkey; 120c34d0d91SJens Wiklander const struct shdr_subkey_attr *pub_exp = NULL; 121c34d0d91SJens Wiklander const struct shdr_subkey_attr *modulus = NULL; 122c34d0d91SJens Wiklander struct rsa_public_key *key = NULL; 123c34d0d91SJens Wiklander TEE_Result res = TEE_SUCCESS; 124c34d0d91SJens Wiklander 125c34d0d91SJens Wiklander pub_exp = find_attr(subkey, TEE_ATTR_RSA_PUBLIC_EXPONENT); 126c34d0d91SJens Wiklander if (!pub_exp) 127c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 128c34d0d91SJens Wiklander modulus = find_attr(subkey, TEE_ATTR_RSA_MODULUS); 129c34d0d91SJens Wiklander if (!modulus) 130c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 131c34d0d91SJens Wiklander 132c34d0d91SJens Wiklander key = calloc(1, sizeof(*key)); 133c34d0d91SJens Wiklander if (!key) 134c34d0d91SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 135c34d0d91SJens Wiklander res = crypto_acipher_alloc_rsa_public_key(key, modulus->size * 8); 136c34d0d91SJens Wiklander if (res) 137c34d0d91SJens Wiklander goto err_key; 138c34d0d91SJens Wiklander 139c34d0d91SJens Wiklander res = crypto_bignum_bin2bn(base + pub_exp->offs, pub_exp->size, key->e); 140c34d0d91SJens Wiklander if (res) 141c34d0d91SJens Wiklander goto err; 142c34d0d91SJens Wiklander res = crypto_bignum_bin2bn(base + modulus->offs, modulus->size, key->n); 143c34d0d91SJens Wiklander if (res) 144c34d0d91SJens Wiklander goto err; 145c34d0d91SJens Wiklander 146c34d0d91SJens Wiklander *key_pp = key; 147c34d0d91SJens Wiklander return TEE_SUCCESS; 148c34d0d91SJens Wiklander err: 149c34d0d91SJens Wiklander crypto_acipher_free_rsa_public_key(key); 150c34d0d91SJens Wiklander err_key: 151c34d0d91SJens Wiklander free(key); 152c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 153c34d0d91SJens Wiklander } 154c34d0d91SJens Wiklander 155c34d0d91SJens Wiklander static TEE_Result check_attrs(const struct shdr_subkey *subkey, size_t img_size) 156c34d0d91SJens Wiklander { 157c34d0d91SJens Wiklander const struct shdr_subkey_attr *attrs = subkey->attrs; 158c34d0d91SJens Wiklander size_t end = 0; 159c34d0d91SJens Wiklander size_t n = 0; 160c34d0d91SJens Wiklander 161c34d0d91SJens Wiklander if (MUL_OVERFLOW(subkey->attr_count, sizeof(*attrs), &end) || 162c34d0d91SJens Wiklander ADD_OVERFLOW(end, sizeof(*subkey), &end) || 163c34d0d91SJens Wiklander end > img_size) 164c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 165c34d0d91SJens Wiklander 166c34d0d91SJens Wiklander for (n = 0; n < subkey->attr_count; n++) 167c34d0d91SJens Wiklander if (ADD_OVERFLOW(attrs[n].offs, attrs[n].size, &end) || 168c34d0d91SJens Wiklander end > img_size) 169c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 170c34d0d91SJens Wiklander 171c34d0d91SJens Wiklander return TEE_SUCCESS; 172c34d0d91SJens Wiklander } 173c34d0d91SJens Wiklander 174c34d0d91SJens Wiklander static TEE_Result calc_next_uuid(uint8_t uuid[sizeof(TEE_UUID)], 175c34d0d91SJens Wiklander const uint8_t my_uuid[sizeof(TEE_UUID)], 176c34d0d91SJens Wiklander const void *ns_name, size_t name_size) 177c34d0d91SJens Wiklander { 178c34d0d91SJens Wiklander TEE_Result res = TEE_ERROR_SECURITY; 179c34d0d91SJens Wiklander void *ctx = NULL; 180c34d0d91SJens Wiklander struct { 181c34d0d91SJens Wiklander uint8_t digest[TEE_SHA1_HASH_SIZE]; 182c34d0d91SJens Wiklander TEE_UUID uuid; 183c34d0d91SJens Wiklander char name_str[]; 184c34d0d91SJens Wiklander } *tmp = NULL; 185c34d0d91SJens Wiklander 186c34d0d91SJens Wiklander if (!name_size) { 187c34d0d91SJens Wiklander memcpy(uuid, my_uuid, sizeof(TEE_UUID)); 188c34d0d91SJens Wiklander return TEE_SUCCESS; 189c34d0d91SJens Wiklander } 190c34d0d91SJens Wiklander 191c34d0d91SJens Wiklander /* 192c34d0d91SJens Wiklander * RFC 4122 requires a SHA-1 digest for UUID v5. Use SHA-512 193c34d0d91SJens Wiklander * instead for better collision resistance. 194c34d0d91SJens Wiklander */ 195c34d0d91SJens Wiklander if (crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA512)) 196c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 197c34d0d91SJens Wiklander 198c34d0d91SJens Wiklander tmp = mempool_alloc(mempool_default, sizeof(*tmp) + name_size); 199c34d0d91SJens Wiklander if (!tmp) 200c34d0d91SJens Wiklander goto out_ctx; 201c34d0d91SJens Wiklander memcpy(tmp->name_str, ns_name, name_size); 202c34d0d91SJens Wiklander 203c34d0d91SJens Wiklander if (crypto_hash_init(ctx) || 204c34d0d91SJens Wiklander crypto_hash_update(ctx, my_uuid, sizeof(TEE_UUID)) || 205c34d0d91SJens Wiklander crypto_hash_update(ctx, (const void *)tmp->name_str, 206c34d0d91SJens Wiklander strnlen(tmp->name_str, name_size)) || 207c34d0d91SJens Wiklander crypto_hash_final(ctx, tmp->digest, sizeof(tmp->digest))) 208c34d0d91SJens Wiklander goto out_mempool; 209c34d0d91SJens Wiklander 210c34d0d91SJens Wiklander tee_uuid_from_octets(&tmp->uuid, tmp->digest); 211c34d0d91SJens Wiklander /* 212c34d0d91SJens Wiklander * Set the four most significant bits (bits 12 through 15) of the 213c34d0d91SJens Wiklander * time_hi_and_version field to 5. 214c34d0d91SJens Wiklander */ 215c34d0d91SJens Wiklander tmp->uuid.timeHiAndVersion &= ~SHIFT_U32(0xf, 12); 216c34d0d91SJens Wiklander tmp->uuid.timeHiAndVersion |= SHIFT_U32(5, 12); 217c34d0d91SJens Wiklander /* 218c34d0d91SJens Wiklander * Set the two most significant bits (bits 6 and 7) of the 219c34d0d91SJens Wiklander * clock_seq_hi_and_reserved to zero and one, respectively. 220c34d0d91SJens Wiklander */ 221c34d0d91SJens Wiklander tmp->uuid.clockSeqAndNode[0] &= ~BIT(6); 222c34d0d91SJens Wiklander tmp->uuid.clockSeqAndNode[0] |= BIT(7); 223c34d0d91SJens Wiklander 224c34d0d91SJens Wiklander tee_uuid_to_octets(uuid, &tmp->uuid); 225c34d0d91SJens Wiklander res = TEE_SUCCESS; 226c34d0d91SJens Wiklander 227c34d0d91SJens Wiklander out_mempool: 228c34d0d91SJens Wiklander mempool_free(mempool_default, tmp); 229c34d0d91SJens Wiklander out_ctx: 230c34d0d91SJens Wiklander crypto_hash_free_ctx(ctx); 231c34d0d91SJens Wiklander 232c34d0d91SJens Wiklander return res; 233c34d0d91SJens Wiklander } 234c34d0d91SJens Wiklander 235c34d0d91SJens Wiklander TEE_Result shdr_load_pub_key(const struct shdr *shdr, size_t offs, 236c34d0d91SJens Wiklander const uint8_t *ns_img, size_t ns_img_size, 237c34d0d91SJens Wiklander const uint8_t next_uuid[sizeof(TEE_UUID)], 238c34d0d91SJens Wiklander uint32_t max_depth, struct shdr_pub_key *key) 239c34d0d91SJens Wiklander { 240c34d0d91SJens Wiklander struct shdr_subkey *subkey = NULL; 241c34d0d91SJens Wiklander TEE_Result res = TEE_SUCCESS; 242c34d0d91SJens Wiklander void *digest = NULL; 243c34d0d91SJens Wiklander uint8_t *img = NULL; 244c34d0d91SJens Wiklander void *ctx = NULL; 245c34d0d91SJens Wiklander size_t end = 0; 246c34d0d91SJens Wiklander 247c34d0d91SJens Wiklander if (shdr->img_type != SHDR_SUBKEY) 248c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 249c34d0d91SJens Wiklander 250c34d0d91SJens Wiklander if (shdr->img_size < sizeof(*subkey)) 251c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 252c34d0d91SJens Wiklander 253c34d0d91SJens Wiklander if (ADD_OVERFLOW(shdr->img_size, offs, &end) || end > ns_img_size) 254c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 255c34d0d91SJens Wiklander 256c34d0d91SJens Wiklander img = mempool_alloc(mempool_default, shdr->img_size + shdr->hash_size); 257c34d0d91SJens Wiklander if (!img) 258c34d0d91SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 259c34d0d91SJens Wiklander memcpy(img + shdr->hash_size, ns_img + offs, shdr->img_size); 260c34d0d91SJens Wiklander subkey = (void *)(img + shdr->hash_size); 261c34d0d91SJens Wiklander digest = img; 262c34d0d91SJens Wiklander 263c34d0d91SJens Wiklander if (crypto_hash_alloc_ctx(&ctx, TEE_DIGEST_HASH_TO_ALGO(shdr->algo))) { 264c34d0d91SJens Wiklander res = TEE_ERROR_SECURITY; 265c34d0d91SJens Wiklander goto out_mempool; 266c34d0d91SJens Wiklander } 267c34d0d91SJens Wiklander 268c34d0d91SJens Wiklander if (crypto_hash_init(ctx) || 269c34d0d91SJens Wiklander crypto_hash_update(ctx, (const void *)shdr, sizeof(*shdr)) || 270c34d0d91SJens Wiklander crypto_hash_update(ctx, (const void *)subkey, shdr->img_size) || 271c34d0d91SJens Wiklander crypto_hash_final(ctx, digest, shdr->hash_size) || 272c34d0d91SJens Wiklander memcmp(digest, SHDR_GET_HASH(shdr), shdr->hash_size)) { 273c34d0d91SJens Wiklander res = TEE_ERROR_SECURITY; 274c34d0d91SJens Wiklander goto out_ctx; 275c34d0d91SJens Wiklander } 276c34d0d91SJens Wiklander 277c34d0d91SJens Wiklander res = check_attrs(subkey, shdr->img_size); 278c34d0d91SJens Wiklander if (res) 279c34d0d91SJens Wiklander goto out_ctx; 280c34d0d91SJens Wiklander 281c34d0d91SJens Wiklander if (subkey->max_depth >= max_depth) { 282c34d0d91SJens Wiklander res = TEE_ERROR_SECURITY; 283c34d0d91SJens Wiklander goto out_ctx; 284c34d0d91SJens Wiklander } 285c34d0d91SJens Wiklander if (next_uuid && memcmp(next_uuid, subkey->uuid, sizeof(TEE_UUID))) { 286c34d0d91SJens Wiklander res = TEE_ERROR_SECURITY; 287c34d0d91SJens Wiklander goto out_ctx; 288c34d0d91SJens Wiklander } 289c34d0d91SJens Wiklander 290c34d0d91SJens Wiklander key->max_depth = subkey->max_depth; 291c34d0d91SJens Wiklander key->name_size = subkey->name_size; 292c34d0d91SJens Wiklander memcpy(key->uuid, subkey->uuid, sizeof(TEE_UUID)); 293c34d0d91SJens Wiklander if (ADD_OVERFLOW(key->name_size, offs + shdr->img_size, &end) || 294c34d0d91SJens Wiklander end > ns_img_size) { 295c34d0d91SJens Wiklander res = TEE_ERROR_SECURITY; 296c34d0d91SJens Wiklander goto out_ctx; 297c34d0d91SJens Wiklander } 298c34d0d91SJens Wiklander res = calc_next_uuid(key->next_uuid, key->uuid, 299c34d0d91SJens Wiklander ns_img + offs + shdr->img_size, key->name_size); 300c34d0d91SJens Wiklander if (res) 301c34d0d91SJens Wiklander goto out_ctx; 302c34d0d91SJens Wiklander 303c34d0d91SJens Wiklander key->main_algo = TEE_ALG_GET_MAIN_ALG(subkey->algo); 304c34d0d91SJens Wiklander switch (key->main_algo) { 305c34d0d91SJens Wiklander case TEE_MAIN_ALGO_RSA: 306c34d0d91SJens Wiklander res = load_rsa_key(subkey, &key->pub_key.rsa); 307c34d0d91SJens Wiklander break; 308c34d0d91SJens Wiklander default: 309c34d0d91SJens Wiklander res = TEE_ERROR_SECURITY; 310c34d0d91SJens Wiklander break; 311c34d0d91SJens Wiklander } 312c34d0d91SJens Wiklander 313c34d0d91SJens Wiklander out_ctx: 314c34d0d91SJens Wiklander crypto_hash_free_ctx(ctx); 315c34d0d91SJens Wiklander out_mempool: 316c34d0d91SJens Wiklander mempool_free(mempool_default, img); 317c34d0d91SJens Wiklander return res; 318c34d0d91SJens Wiklander } 319c34d0d91SJens Wiklander 320c34d0d91SJens Wiklander void shdr_free_pub_key(struct shdr_pub_key *key) 321c34d0d91SJens Wiklander { 322c34d0d91SJens Wiklander if (key) { 323c34d0d91SJens Wiklander switch (key->main_algo) { 324c34d0d91SJens Wiklander case TEE_MAIN_ALGO_RSA: 325c34d0d91SJens Wiklander crypto_acipher_free_rsa_public_key(key->pub_key.rsa); 326c34d0d91SJens Wiklander free(key->pub_key.rsa); 327c34d0d91SJens Wiklander break; 328c34d0d91SJens Wiklander default: 329c34d0d91SJens Wiklander panic(); 330c34d0d91SJens Wiklander } 331c34d0d91SJens Wiklander } 332c34d0d91SJens Wiklander } 333c34d0d91SJens Wiklander 334c34d0d91SJens Wiklander TEE_Result shdr_verify_signature2(struct shdr_pub_key *key, 335c34d0d91SJens Wiklander const struct shdr *shdr) 336c34d0d91SJens Wiklander { 337c34d0d91SJens Wiklander size_t hash_size = 0; 338*bef7d11dSJens Wiklander size_t hash_algo = 0; 339c34d0d91SJens Wiklander 340c34d0d91SJens Wiklander if (shdr->magic != SHDR_MAGIC) 341c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 342c34d0d91SJens Wiklander 343c34d0d91SJens Wiklander if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != key->main_algo) 344c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 345c34d0d91SJens Wiklander 346*bef7d11dSJens Wiklander hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo); 347*bef7d11dSJens Wiklander if (is_weak_hash_algo(hash_algo)) 348*bef7d11dSJens Wiklander return TEE_ERROR_SECURITY; 349*bef7d11dSJens Wiklander 350*bef7d11dSJens Wiklander if (tee_alg_get_digest_size(hash_algo, &hash_size) || 351c34d0d91SJens Wiklander hash_size != shdr->hash_size) 352c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 353c34d0d91SJens Wiklander 354c34d0d91SJens Wiklander switch (key->main_algo) { 355c34d0d91SJens Wiklander case TEE_MAIN_ALGO_RSA: 356c34d0d91SJens Wiklander if (crypto_acipher_rsassa_verify(shdr->algo, key->pub_key.rsa, 357c34d0d91SJens Wiklander shdr->hash_size, 358c34d0d91SJens Wiklander SHDR_GET_HASH(shdr), 359c34d0d91SJens Wiklander shdr->hash_size, 360c34d0d91SJens Wiklander SHDR_GET_SIG(shdr), 361c34d0d91SJens Wiklander shdr->sig_size)) 362c34d0d91SJens Wiklander return TEE_ERROR_SECURITY; 363c34d0d91SJens Wiklander break; 364c34d0d91SJens Wiklander default: 365c34d0d91SJens Wiklander panic(); 366c34d0d91SJens Wiklander } 367c34d0d91SJens Wiklander 368c34d0d91SJens Wiklander return TEE_SUCCESS; 369c34d0d91SJens Wiklander } 370