mbedtls_psa_crypto.c 14 KB

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