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