1 /* 2 * Copyright (c) 2023-2024, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stddef.h> 9 #include <string.h> 10 11 /* mbed TLS headers */ 12 #include <mbedtls/md.h> 13 #include <mbedtls/memory_buffer_alloc.h> 14 #include <mbedtls/oid.h> 15 #include <mbedtls/platform.h> 16 #include <mbedtls/psa_util.h> 17 #include <mbedtls/x509.h> 18 #include <psa/crypto.h> 19 #include <psa/crypto_platform.h> 20 #include <psa/crypto_types.h> 21 #include <psa/crypto_values.h> 22 23 #include <common/debug.h> 24 #include <drivers/auth/crypto_mod.h> 25 #include <drivers/auth/mbedtls/mbedtls_common.h> 26 #include <plat/common/platform.h> 27 28 #define LIB_NAME "mbed TLS PSA" 29 30 /* Minimum required size for a buffer containing a raw EC signature when using 31 * a maximum curve size of 384 bits. 32 * This is calculated as 2 * (384 / 8). */ 33 #define ECDSA_SIG_BUFFER_SIZE 96U 34 35 /* Size of ASN.1 length and tag in bytes*/ 36 #define SIZE_OF_ASN1_LEN 1U 37 #define SIZE_OF_ASN1_TAG 1U 38 39 #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 40 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 41 /* 42 * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available 43 * so make sure that mbed TLS MD maximum size must be lesser than this. 44 */ 45 CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE, 46 assert_mbedtls_md_size_overflow); 47 48 #endif /* 49 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 50 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 51 */ 52 53 /* 54 * AlgorithmIdentifier ::= SEQUENCE { 55 * algorithm OBJECT IDENTIFIER, 56 * parameters ANY DEFINED BY algorithm OPTIONAL 57 * } 58 * 59 * SubjectPublicKeyInfo ::= SEQUENCE { 60 * algorithm AlgorithmIdentifier, 61 * subjectPublicKey BIT STRING 62 * } 63 * 64 * DigestInfo ::= SEQUENCE { 65 * digestAlgorithm AlgorithmIdentifier, 66 * digest OCTET STRING 67 * } 68 */ 69 70 /* 71 * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG 72 * mbedTLS config option) so we need to provide an implementation of 73 * mbedtls_psa_external_get_random(). Provide a fake one, since we do not 74 * actually have any external RNG and TF-A itself doesn't engage in 75 * cryptographic operations that demands randomness. 76 */ 77 psa_status_t mbedtls_psa_external_get_random( 78 mbedtls_psa_external_random_context_t *context, 79 uint8_t *output, size_t output_size, 80 size_t *output_length) 81 { 82 return PSA_ERROR_INSUFFICIENT_ENTROPY; 83 } 84 85 /* 86 * Initialize the library and export the descriptor 87 */ 88 static void init(void) 89 { 90 /* Initialize mbed TLS */ 91 mbedtls_init(); 92 93 /* Initialise PSA mbedTLS */ 94 psa_status_t status = psa_crypto_init(); 95 96 if (status != PSA_SUCCESS) { 97 ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status); 98 panic(); 99 } 100 101 INFO("PSA crypto initialized successfully!\n"); 102 } 103 104 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 105 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 106 107 /* 108 * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has 109 * advised that it's better to copy out the declaration than it would be to 110 * update to 3.5.2, where this function is exposed. 111 */ 112 int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, 113 const mbedtls_x509_buf *sig_params, 114 mbedtls_md_type_t *md_alg, 115 mbedtls_pk_type_t *pk_alg, 116 void **sig_opts); 117 118 /* 119 * This is a helper function which parses a SignatureAlgorithm OID. 120 * It extracts the pk algorithm and constructs a psa_algorithm_t object 121 * to be used by PSA calls. 122 */ 123 static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len, 124 mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg) 125 { 126 int rc; 127 mbedtls_md_type_t md_alg; 128 void *sig_opts = NULL; 129 mbedtls_asn1_buf sig_alg_oid, params; 130 unsigned char *p = (unsigned char *) sig_alg; 131 unsigned char *end = (unsigned char *) sig_alg + sig_alg_len; 132 133 rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, ¶ms); 134 if (rc != 0) { 135 rc = CRYPTO_ERR_SIGNATURE; 136 goto end; 137 } 138 139 rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, ¶ms, &md_alg, pk_alg, &sig_opts); 140 if (rc != 0) { 141 rc = CRYPTO_ERR_SIGNATURE; 142 goto end; 143 } 144 145 psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 146 147 switch (*pk_alg) { 148 case MBEDTLS_PK_RSASSA_PSS: 149 *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg); 150 rc = CRYPTO_SUCCESS; 151 break; 152 case MBEDTLS_PK_ECDSA: 153 *psa_alg = PSA_ALG_ECDSA(psa_md_alg); 154 rc = CRYPTO_SUCCESS; 155 break; 156 default: 157 *psa_alg = PSA_ALG_NONE; 158 rc = CRYPTO_ERR_SIGNATURE; 159 break; 160 } 161 162 end: 163 mbedtls_free(sig_opts); 164 return rc; 165 } 166 167 /* 168 * Helper functions for mbedtls PK contexts. 169 */ 170 static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized) 171 { 172 mbedtls_pk_init(pk); 173 *pk_initialized = true; 174 } 175 176 static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized) 177 { 178 if (*pk_initialized) { 179 mbedtls_pk_free(pk); 180 *pk_initialized = false; 181 } 182 } 183 184 /* 185 * Verify a signature. 186 * 187 * Parameters are passed using the DER encoding format following the ASN.1 188 * structures detailed above. 189 */ 190 static int verify_signature(void *data_ptr, unsigned int data_len, 191 void *sig_ptr, unsigned int sig_len, 192 void *sig_alg, unsigned int sig_alg_len, 193 void *pk_ptr, unsigned int pk_len) 194 { 195 unsigned char *p, *end; 196 mbedtls_pk_context pk; 197 bool pk_initialized = false; 198 int rc = CRYPTO_ERR_SIGNATURE; 199 psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED; 200 psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT; 201 psa_key_id_t psa_key_id; 202 mbedtls_pk_type_t pk_alg; 203 psa_algorithm_t psa_alg; 204 __unused unsigned char reformatted_sig[ECDSA_SIG_BUFFER_SIZE] = {0}; 205 unsigned char *local_sig_ptr; 206 size_t local_sig_len; 207 208 /* Load the key into the PSA key store. */ 209 initialize_pk_context(&pk, &pk_initialized); 210 211 p = (unsigned char *) pk_ptr; 212 end = p + pk_len; 213 rc = mbedtls_pk_parse_subpubkey(&p, end, &pk); 214 if (rc != 0) { 215 rc = CRYPTO_ERR_SIGNATURE; 216 goto end2; 217 } 218 219 rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE, &psa_key_attr); 220 if (rc != 0) { 221 rc = CRYPTO_ERR_SIGNATURE; 222 goto end2; 223 } 224 225 rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg); 226 if (rc != CRYPTO_SUCCESS) { 227 goto end2; 228 } 229 psa_set_key_algorithm(&psa_key_attr, psa_alg); 230 231 rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id); 232 if (rc != 0) { 233 rc = CRYPTO_ERR_SIGNATURE; 234 goto end2; 235 } 236 237 /* Optimize mbedtls heap usage by freeing the pk context now. */ 238 cleanup_pk_context(&pk, &pk_initialized); 239 240 /* Extract the signature from sig_ptr. */ 241 p = (unsigned char *) sig_ptr; 242 end = p + sig_len; 243 rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len); 244 if (rc != 0) { 245 rc = CRYPTO_ERR_SIGNATURE; 246 goto end1; 247 } 248 local_sig_ptr = p; 249 250 #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 251 TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 252 if (pk_alg == MBEDTLS_PK_ECDSA) { 253 /* Convert the DER ASN.1 signature to raw format. */ 254 size_t key_bits = psa_get_key_bits(&psa_key_attr); 255 256 rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len, 257 reformatted_sig, ECDSA_SIG_BUFFER_SIZE, 258 &local_sig_len); 259 if (rc != 0) { 260 rc = CRYPTO_ERR_SIGNATURE; 261 goto end1; 262 } 263 local_sig_ptr = reformatted_sig; 264 } 265 #endif /* 266 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 267 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 268 **/ 269 270 /* Verify the signature. */ 271 psa_status = psa_verify_message(psa_key_id, psa_alg, 272 data_ptr, data_len, 273 local_sig_ptr, local_sig_len); 274 if (psa_status == PSA_SUCCESS) { 275 /* The signature has been successfully verified. */ 276 rc = CRYPTO_SUCCESS; 277 } else { 278 rc = CRYPTO_ERR_SIGNATURE; 279 } 280 281 end1: 282 /* Destroy the key from the PSA subsystem. */ 283 psa_destroy_key(psa_key_id); 284 end2: 285 /* Free the pk context, if it is initialized. */ 286 cleanup_pk_context(&pk, &pk_initialized); 287 288 return rc; 289 } 290 291 /* 292 * Match a hash 293 * 294 * Digest info is passed in DER format following the ASN.1 structure detailed 295 * above. 296 */ 297 static int verify_hash(void *data_ptr, unsigned int data_len, 298 void *digest_info_ptr, unsigned int digest_info_len) 299 { 300 mbedtls_asn1_buf hash_oid, params; 301 mbedtls_md_type_t md_alg; 302 unsigned char *p, *end, *hash; 303 size_t len; 304 int rc; 305 psa_status_t status; 306 psa_algorithm_t psa_md_alg; 307 308 /* 309 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after 310 * it is allowed. This is necessary to support multiple hash 311 * algorithms. 312 */ 313 p = (unsigned char *)digest_info_ptr; 314 end = p + digest_info_len; 315 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 316 MBEDTLS_ASN1_SEQUENCE); 317 if (rc != 0) { 318 return CRYPTO_ERR_HASH; 319 } 320 321 end = p + len; 322 323 /* Get the hash algorithm */ 324 rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 325 if (rc != 0) { 326 return CRYPTO_ERR_HASH; 327 } 328 329 /* Hash should be octet string type and consume all bytes */ 330 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 331 if ((rc != 0) || ((size_t)(end - p) != len)) { 332 return CRYPTO_ERR_HASH; 333 } 334 hash = p; 335 336 rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 337 if (rc != 0) { 338 return CRYPTO_ERR_HASH; 339 } 340 341 /* convert the md_alg to psa_algo */ 342 psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 343 344 /* Length of hash must match the algorithm's size */ 345 if (len != PSA_HASH_LENGTH(psa_md_alg)) { 346 return CRYPTO_ERR_HASH; 347 } 348 349 /* 350 * Calculate Hash and compare it against the retrieved hash from 351 * the certificate (one shot API). 352 */ 353 status = psa_hash_compare(psa_md_alg, 354 data_ptr, (size_t)data_len, 355 (const uint8_t *)hash, len); 356 357 if (status != PSA_SUCCESS) { 358 return CRYPTO_ERR_HASH; 359 } 360 361 return CRYPTO_SUCCESS; 362 } 363 #endif /* 364 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 365 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 366 */ 367 368 #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 369 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 370 /* 371 * Map a generic crypto message digest algorithm to the corresponding macro used 372 * by Mbed TLS. 373 */ 374 static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo) 375 { 376 switch (algo) { 377 case CRYPTO_MD_SHA512: 378 return MBEDTLS_MD_SHA512; 379 case CRYPTO_MD_SHA384: 380 return MBEDTLS_MD_SHA384; 381 case CRYPTO_MD_SHA256: 382 return MBEDTLS_MD_SHA256; 383 default: 384 /* Invalid hash algorithm. */ 385 return MBEDTLS_MD_NONE; 386 } 387 } 388 389 /* 390 * Calculate a hash 391 * 392 * output points to the computed hash 393 */ 394 static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr, 395 unsigned int data_len, 396 unsigned char output[CRYPTO_MD_MAX_SIZE]) 397 { 398 size_t hash_length; 399 psa_status_t status; 400 psa_algorithm_t psa_md_alg; 401 402 /* convert the md_alg to psa_algo */ 403 psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo)); 404 405 /* 406 * Calculate the hash of the data, it is safe to pass the 407 * 'output' hash buffer pointer considering its size is always 408 * bigger than or equal to MBEDTLS_MD_MAX_SIZE. 409 */ 410 status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len, 411 (uint8_t *)output, CRYPTO_MD_MAX_SIZE, 412 &hash_length); 413 if (status != PSA_SUCCESS) { 414 return CRYPTO_ERR_HASH; 415 } 416 417 return CRYPTO_SUCCESS; 418 } 419 #endif /* 420 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 421 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 422 */ 423 424 #if TF_MBEDTLS_USE_AES_GCM 425 /* 426 * Stack based buffer allocation for decryption operation. It could 427 * be configured to balance stack usage vs execution speed. 428 */ 429 #define DEC_OP_BUF_SIZE 128 430 431 static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, 432 unsigned int key_len, const void *iv, 433 unsigned int iv_len, const void *tag, 434 unsigned int tag_len) 435 { 436 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 437 psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; 438 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 439 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; 440 unsigned char buf[DEC_OP_BUF_SIZE]; 441 unsigned char *pt = data_ptr; 442 size_t dec_len; 443 size_t output_length; 444 445 /* Load the key into the PSA key store. */ 446 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); 447 psa_set_key_algorithm(&attributes, PSA_ALG_GCM); 448 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); 449 450 psa_status = psa_import_key(&attributes, key, key_len, &key_id); 451 if (psa_status != PSA_SUCCESS) { 452 return CRYPTO_ERR_DECRYPTION; 453 } 454 455 /* Perform the decryption. */ 456 psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM); 457 if (psa_status != PSA_SUCCESS) { 458 goto err; 459 } 460 461 psa_status = psa_aead_set_nonce(&operation, iv, iv_len); 462 if (psa_status != PSA_SUCCESS) { 463 goto err; 464 } 465 466 while (len > 0) { 467 dec_len = MIN(sizeof(buf), len); 468 469 psa_status = psa_aead_update(&operation, pt, dec_len, buf, 470 sizeof(buf), &output_length); 471 if (psa_status != PSA_SUCCESS) { 472 goto err; 473 } 474 475 memcpy(pt, buf, output_length); 476 pt += output_length; 477 len -= dec_len; 478 } 479 480 /* Verify the tag. */ 481 psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len); 482 if (psa_status == PSA_SUCCESS) { 483 psa_destroy_key(key_id); 484 return CRYPTO_SUCCESS; 485 } 486 487 err: 488 psa_aead_abort(&operation); 489 psa_destroy_key(key_id); 490 return CRYPTO_ERR_DECRYPTION; 491 } 492 493 /* 494 * Authenticated decryption of an image 495 */ 496 static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, 497 size_t len, const void *key, unsigned int key_len, 498 unsigned int key_flags, const void *iv, 499 unsigned int iv_len, const void *tag, 500 unsigned int tag_len) 501 { 502 int rc; 503 504 assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); 505 506 switch (dec_algo) { 507 case CRYPTO_GCM_DECRYPT: 508 rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, 509 tag, tag_len); 510 if (rc != 0) 511 return rc; 512 break; 513 default: 514 return CRYPTO_ERR_DECRYPTION; 515 } 516 517 return CRYPTO_SUCCESS; 518 } 519 #endif /* TF_MBEDTLS_USE_AES_GCM */ 520 521 /* 522 * Register crypto library descriptor 523 */ 524 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 525 #if TF_MBEDTLS_USE_AES_GCM 526 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 527 auth_decrypt, NULL); 528 #else 529 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 530 NULL, NULL); 531 #endif 532 #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY 533 #if TF_MBEDTLS_USE_AES_GCM 534 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 535 auth_decrypt, NULL); 536 #else 537 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 538 NULL, NULL); 539 #endif 540 #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY 541 REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL); 542 #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 543