mbedtls_crypto.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /*
  2. * Copyright (c) 2015-2024, Arm Limited and Contributors. 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/gcm.h>
  11. #include <mbedtls/md.h>
  12. #include <mbedtls/memory_buffer_alloc.h>
  13. #include <mbedtls/oid.h>
  14. #include <mbedtls/platform.h>
  15. #include <mbedtls/version.h>
  16. #include <mbedtls/x509.h>
  17. #include <common/debug.h>
  18. #include <drivers/auth/crypto_mod.h>
  19. #include <drivers/auth/mbedtls/mbedtls_common.h>
  20. #include <plat/common/platform.h>
  21. #define LIB_NAME "mbed TLS"
  22. #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
  23. CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
  24. /*
  25. * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
  26. * so make sure that mbed TLS MD maximum size must be lesser than this.
  27. */
  28. CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
  29. assert_mbedtls_md_size_overflow);
  30. #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
  31. CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
  32. /*
  33. * AlgorithmIdentifier ::= SEQUENCE {
  34. * algorithm OBJECT IDENTIFIER,
  35. * parameters ANY DEFINED BY algorithm OPTIONAL
  36. * }
  37. *
  38. * SubjectPublicKeyInfo ::= SEQUENCE {
  39. * algorithm AlgorithmIdentifier,
  40. * subjectPublicKey BIT STRING
  41. * }
  42. *
  43. * DigestInfo ::= SEQUENCE {
  44. * digestAlgorithm AlgorithmIdentifier,
  45. * digest OCTET STRING
  46. * }
  47. */
  48. /*
  49. * Initialize the library and export the descriptor
  50. */
  51. static void init(void)
  52. {
  53. /* Initialize mbed TLS */
  54. mbedtls_init();
  55. }
  56. #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
  57. CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
  58. /*
  59. * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
  60. * advised that it's better to copy out the declaration than it would be to
  61. * update to 3.5.2, where this function is exposed.
  62. */
  63. int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
  64. const mbedtls_x509_buf *sig_params,
  65. mbedtls_md_type_t *md_alg,
  66. mbedtls_pk_type_t *pk_alg,
  67. void **sig_opts);
  68. /*
  69. * Verify a signature.
  70. *
  71. * Parameters are passed using the DER encoding format following the ASN.1
  72. * structures detailed above.
  73. */
  74. static int verify_signature(void *data_ptr, unsigned int data_len,
  75. void *sig_ptr, unsigned int sig_len,
  76. void *sig_alg, unsigned int sig_alg_len,
  77. void *pk_ptr, unsigned int pk_len)
  78. {
  79. mbedtls_asn1_buf sig_oid, sig_params;
  80. mbedtls_asn1_buf signature;
  81. mbedtls_md_type_t md_alg;
  82. mbedtls_pk_type_t pk_alg;
  83. mbedtls_pk_context pk = {0};
  84. int rc;
  85. void *sig_opts = NULL;
  86. const mbedtls_md_info_t *md_info;
  87. unsigned char *p, *end;
  88. unsigned char hash[MBEDTLS_MD_MAX_SIZE];
  89. /* Get pointers to signature OID and parameters */
  90. p = (unsigned char *)sig_alg;
  91. end = (unsigned char *)(p + sig_alg_len);
  92. rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params);
  93. if (rc != 0) {
  94. return CRYPTO_ERR_SIGNATURE;
  95. }
  96. /* Get the actual signature algorithm (MD + PK) */
  97. rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts);
  98. if (rc != 0) {
  99. return CRYPTO_ERR_SIGNATURE;
  100. }
  101. /* Parse the public key */
  102. mbedtls_pk_init(&pk);
  103. p = (unsigned char *)pk_ptr;
  104. end = (unsigned char *)(p + pk_len);
  105. rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
  106. if (rc != 0) {
  107. rc = CRYPTO_ERR_SIGNATURE;
  108. goto end2;
  109. }
  110. /* Get the signature (bitstring) */
  111. p = (unsigned char *)sig_ptr;
  112. end = (unsigned char *)(p + sig_len);
  113. signature.tag = *p;
  114. rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
  115. if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
  116. rc = CRYPTO_ERR_SIGNATURE;
  117. goto end1;
  118. }
  119. signature.p = p;
  120. /* Calculate the hash of the data */
  121. md_info = mbedtls_md_info_from_type(md_alg);
  122. if (md_info == NULL) {
  123. rc = CRYPTO_ERR_SIGNATURE;
  124. goto end1;
  125. }
  126. p = (unsigned char *)data_ptr;
  127. rc = mbedtls_md(md_info, p, data_len, hash);
  128. if (rc != 0) {
  129. rc = CRYPTO_ERR_SIGNATURE;
  130. goto end1;
  131. }
  132. /* Verify the signature */
  133. rc = mbedtls_pk_verify_ext(pk_alg, sig_opts, &pk, md_alg, hash,
  134. mbedtls_md_get_size(md_info),
  135. signature.p, signature.len);
  136. if (rc != 0) {
  137. rc = CRYPTO_ERR_SIGNATURE;
  138. goto end1;
  139. }
  140. /* Signature verification success */
  141. rc = CRYPTO_SUCCESS;
  142. end1:
  143. mbedtls_pk_free(&pk);
  144. end2:
  145. mbedtls_free(sig_opts);
  146. return rc;
  147. }
  148. /*
  149. * Match a hash
  150. *
  151. * Digest info is passed in DER format following the ASN.1 structure detailed
  152. * above.
  153. */
  154. static int verify_hash(void *data_ptr, unsigned int data_len,
  155. void *digest_info_ptr, unsigned int digest_info_len)
  156. {
  157. mbedtls_asn1_buf hash_oid, params;
  158. mbedtls_md_type_t md_alg;
  159. const mbedtls_md_info_t *md_info;
  160. unsigned char *p, *end, *hash;
  161. unsigned char data_hash[MBEDTLS_MD_MAX_SIZE];
  162. size_t len;
  163. int rc;
  164. /*
  165. * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
  166. * it is allowed. This is necessary to support multiple hash
  167. * algorithms.
  168. */
  169. p = (unsigned char *)digest_info_ptr;
  170. end = p + digest_info_len;
  171. rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  172. MBEDTLS_ASN1_SEQUENCE);
  173. if (rc != 0) {
  174. return CRYPTO_ERR_HASH;
  175. }
  176. end = p + len;
  177. /* Get the hash algorithm */
  178. rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
  179. if (rc != 0) {
  180. return CRYPTO_ERR_HASH;
  181. }
  182. rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
  183. if (rc != 0) {
  184. return CRYPTO_ERR_HASH;
  185. }
  186. md_info = mbedtls_md_info_from_type(md_alg);
  187. if (md_info == NULL) {
  188. return CRYPTO_ERR_HASH;
  189. }
  190. /* Hash should be octet string type and consume all bytes */
  191. rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
  192. if ((rc != 0) || ((size_t)(end - p) != len)) {
  193. return CRYPTO_ERR_HASH;
  194. }
  195. /* Length of hash must match the algorithm's size */
  196. if (len != mbedtls_md_get_size(md_info)) {
  197. return CRYPTO_ERR_HASH;
  198. }
  199. hash = p;
  200. /* Calculate the hash of the data */
  201. p = (unsigned char *)data_ptr;
  202. rc = mbedtls_md(md_info, p, data_len, data_hash);
  203. if (rc != 0) {
  204. return CRYPTO_ERR_HASH;
  205. }
  206. /* Compare values */
  207. rc = memcmp(data_hash, hash, mbedtls_md_get_size(md_info));
  208. if (rc != 0) {
  209. return CRYPTO_ERR_HASH;
  210. }
  211. return CRYPTO_SUCCESS;
  212. }
  213. #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
  214. CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
  215. #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
  216. CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
  217. /*
  218. * Map a generic crypto message digest algorithm to the corresponding macro used
  219. * by Mbed TLS.
  220. */
  221. static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
  222. {
  223. switch (algo) {
  224. case CRYPTO_MD_SHA512:
  225. return MBEDTLS_MD_SHA512;
  226. case CRYPTO_MD_SHA384:
  227. return MBEDTLS_MD_SHA384;
  228. case CRYPTO_MD_SHA256:
  229. return MBEDTLS_MD_SHA256;
  230. default:
  231. /* Invalid hash algorithm. */
  232. return MBEDTLS_MD_NONE;
  233. }
  234. }
  235. /*
  236. * Calculate a hash
  237. *
  238. * output points to the computed hash
  239. */
  240. static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
  241. unsigned int data_len,
  242. unsigned char output[CRYPTO_MD_MAX_SIZE])
  243. {
  244. const mbedtls_md_info_t *md_info;
  245. int rc;
  246. md_info = mbedtls_md_info_from_type(md_type(md_algo));
  247. if (md_info == NULL) {
  248. return CRYPTO_ERR_HASH;
  249. }
  250. /*
  251. * Calculate the hash of the data, it is safe to pass the
  252. * 'output' hash buffer pointer considering its size is always
  253. * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
  254. */
  255. rc = mbedtls_md(md_info, data_ptr, data_len, output);
  256. if (rc != 0) {
  257. return CRYPTO_ERR_HASH;
  258. }
  259. return CRYPTO_SUCCESS;
  260. }
  261. #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
  262. CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
  263. #if TF_MBEDTLS_USE_AES_GCM
  264. /*
  265. * Stack based buffer allocation for decryption operation. It could
  266. * be configured to balance stack usage vs execution speed.
  267. */
  268. #define DEC_OP_BUF_SIZE 128
  269. static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
  270. unsigned int key_len, const void *iv,
  271. unsigned int iv_len, const void *tag,
  272. unsigned int tag_len)
  273. {
  274. mbedtls_gcm_context ctx;
  275. mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
  276. unsigned char buf[DEC_OP_BUF_SIZE];
  277. unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
  278. unsigned char *pt = data_ptr;
  279. size_t dec_len;
  280. int diff, i, rc;
  281. size_t output_length __unused;
  282. mbedtls_gcm_init(&ctx);
  283. rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
  284. if (rc != 0) {
  285. rc = CRYPTO_ERR_DECRYPTION;
  286. goto exit_gcm;
  287. }
  288. #if (MBEDTLS_VERSION_MAJOR < 3)
  289. rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
  290. #else
  291. rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len);
  292. #endif
  293. if (rc != 0) {
  294. rc = CRYPTO_ERR_DECRYPTION;
  295. goto exit_gcm;
  296. }
  297. while (len > 0) {
  298. dec_len = MIN(sizeof(buf), len);
  299. #if (MBEDTLS_VERSION_MAJOR < 3)
  300. rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
  301. #else
  302. rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length);
  303. #endif
  304. if (rc != 0) {
  305. rc = CRYPTO_ERR_DECRYPTION;
  306. goto exit_gcm;
  307. }
  308. memcpy(pt, buf, dec_len);
  309. pt += dec_len;
  310. len -= dec_len;
  311. }
  312. #if (MBEDTLS_VERSION_MAJOR < 3)
  313. rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
  314. #else
  315. rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf));
  316. #endif
  317. if (rc != 0) {
  318. rc = CRYPTO_ERR_DECRYPTION;
  319. goto exit_gcm;
  320. }
  321. /* Check tag in "constant-time" */
  322. for (diff = 0, i = 0; i < tag_len; i++)
  323. diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
  324. if (diff != 0) {
  325. rc = CRYPTO_ERR_DECRYPTION;
  326. goto exit_gcm;
  327. }
  328. /* GCM decryption success */
  329. rc = CRYPTO_SUCCESS;
  330. exit_gcm:
  331. mbedtls_gcm_free(&ctx);
  332. return rc;
  333. }
  334. /*
  335. * Authenticated decryption of an image
  336. */
  337. static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
  338. size_t len, const void *key, unsigned int key_len,
  339. unsigned int key_flags, const void *iv,
  340. unsigned int iv_len, const void *tag,
  341. unsigned int tag_len)
  342. {
  343. int rc;
  344. assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
  345. switch (dec_algo) {
  346. case CRYPTO_GCM_DECRYPT:
  347. rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
  348. tag, tag_len);
  349. if (rc != 0)
  350. return rc;
  351. break;
  352. default:
  353. return CRYPTO_ERR_DECRYPTION;
  354. }
  355. return CRYPTO_SUCCESS;
  356. }
  357. #endif /* TF_MBEDTLS_USE_AES_GCM */
  358. /*
  359. * Register crypto library descriptor
  360. */
  361. #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
  362. #if TF_MBEDTLS_USE_AES_GCM
  363. REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
  364. auth_decrypt, NULL);
  365. #else
  366. REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
  367. NULL, NULL);
  368. #endif
  369. #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
  370. #if TF_MBEDTLS_USE_AES_GCM
  371. REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
  372. auth_decrypt, NULL);
  373. #else
  374. REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
  375. NULL, NULL);
  376. #endif
  377. #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
  378. REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL);
  379. #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */