psa_crypto_mac.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /*
  2. * PSA MAC layer on top of Mbed TLS software crypto
  3. */
  4. /*
  5. * Copyright The Mbed TLS Contributors
  6. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  7. */
  8. #include "common.h"
  9. #if defined(MBEDTLS_PSA_CRYPTO_C)
  10. #include <psa/crypto.h>
  11. #include "psa_crypto_core.h"
  12. #include "psa_crypto_cipher.h"
  13. #include "psa_crypto_mac.h"
  14. #include <mbedtls/md.h>
  15. #include <mbedtls/error.h>
  16. #include "mbedtls/constant_time.h"
  17. #include <string.h>
  18. #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
  19. static psa_status_t psa_hmac_abort_internal(
  20. mbedtls_psa_hmac_operation_t *hmac)
  21. {
  22. mbedtls_platform_zeroize(hmac->opad, sizeof(hmac->opad));
  23. return psa_hash_abort(&hmac->hash_ctx);
  24. }
  25. static psa_status_t psa_hmac_setup_internal(
  26. mbedtls_psa_hmac_operation_t *hmac,
  27. const uint8_t *key,
  28. size_t key_length,
  29. psa_algorithm_t hash_alg)
  30. {
  31. uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
  32. size_t i;
  33. size_t hash_size = PSA_HASH_LENGTH(hash_alg);
  34. size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
  35. psa_status_t status;
  36. hmac->alg = hash_alg;
  37. /* Sanity checks on block_size, to guarantee that there won't be a buffer
  38. * overflow below. This should never trigger if the hash algorithm
  39. * is implemented correctly. */
  40. /* The size checks against the ipad and opad buffers cannot be written
  41. * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
  42. * because that triggers -Wlogical-op on GCC 7.3. */
  43. if (block_size > sizeof(ipad)) {
  44. return PSA_ERROR_NOT_SUPPORTED;
  45. }
  46. if (block_size > sizeof(hmac->opad)) {
  47. return PSA_ERROR_NOT_SUPPORTED;
  48. }
  49. if (block_size < hash_size) {
  50. return PSA_ERROR_NOT_SUPPORTED;
  51. }
  52. if (key_length > block_size) {
  53. status = psa_hash_compute(hash_alg, key, key_length,
  54. ipad, sizeof(ipad), &key_length);
  55. if (status != PSA_SUCCESS) {
  56. goto cleanup;
  57. }
  58. }
  59. /* A 0-length key is not commonly used in HMAC when used as a MAC,
  60. * but it is permitted. It is common when HMAC is used in HKDF, for
  61. * example. Don't call `memcpy` in the 0-length because `key` could be
  62. * an invalid pointer which would make the behavior undefined. */
  63. else if (key_length != 0) {
  64. memcpy(ipad, key, key_length);
  65. }
  66. /* ipad contains the key followed by garbage. Xor and fill with 0x36
  67. * to create the ipad value. */
  68. for (i = 0; i < key_length; i++) {
  69. ipad[i] ^= 0x36;
  70. }
  71. memset(ipad + key_length, 0x36, block_size - key_length);
  72. /* Copy the key material from ipad to opad, flipping the requisite bits,
  73. * and filling the rest of opad with the requisite constant. */
  74. for (i = 0; i < key_length; i++) {
  75. hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
  76. }
  77. memset(hmac->opad + key_length, 0x5C, block_size - key_length);
  78. status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
  79. if (status != PSA_SUCCESS) {
  80. goto cleanup;
  81. }
  82. status = psa_hash_update(&hmac->hash_ctx, ipad, block_size);
  83. cleanup:
  84. mbedtls_platform_zeroize(ipad, sizeof(ipad));
  85. return status;
  86. }
  87. static psa_status_t psa_hmac_update_internal(
  88. mbedtls_psa_hmac_operation_t *hmac,
  89. const uint8_t *data,
  90. size_t data_length)
  91. {
  92. return psa_hash_update(&hmac->hash_ctx, data, data_length);
  93. }
  94. static psa_status_t psa_hmac_finish_internal(
  95. mbedtls_psa_hmac_operation_t *hmac,
  96. uint8_t *mac,
  97. size_t mac_size)
  98. {
  99. uint8_t tmp[PSA_HASH_MAX_SIZE];
  100. psa_algorithm_t hash_alg = hmac->alg;
  101. size_t hash_size = 0;
  102. size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
  103. psa_status_t status;
  104. status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
  105. if (status != PSA_SUCCESS) {
  106. return status;
  107. }
  108. /* From here on, tmp needs to be wiped. */
  109. status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
  110. if (status != PSA_SUCCESS) {
  111. goto exit;
  112. }
  113. status = psa_hash_update(&hmac->hash_ctx, hmac->opad, block_size);
  114. if (status != PSA_SUCCESS) {
  115. goto exit;
  116. }
  117. status = psa_hash_update(&hmac->hash_ctx, tmp, hash_size);
  118. if (status != PSA_SUCCESS) {
  119. goto exit;
  120. }
  121. status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
  122. if (status != PSA_SUCCESS) {
  123. goto exit;
  124. }
  125. memcpy(mac, tmp, mac_size);
  126. exit:
  127. mbedtls_platform_zeroize(tmp, hash_size);
  128. return status;
  129. }
  130. #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
  131. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
  132. static psa_status_t cmac_setup(mbedtls_psa_mac_operation_t *operation,
  133. const psa_key_attributes_t *attributes,
  134. const uint8_t *key_buffer)
  135. {
  136. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  137. #if defined(PSA_WANT_KEY_TYPE_DES)
  138. /* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept
  139. * to do CMAC with pure DES, so return NOT_SUPPORTED here. */
  140. if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES &&
  141. (psa_get_key_bits(attributes) == 64 ||
  142. psa_get_key_bits(attributes) == 128)) {
  143. return PSA_ERROR_NOT_SUPPORTED;
  144. }
  145. #endif
  146. const mbedtls_cipher_info_t *cipher_info =
  147. mbedtls_cipher_info_from_psa(
  148. PSA_ALG_CMAC,
  149. psa_get_key_type(attributes),
  150. psa_get_key_bits(attributes),
  151. NULL);
  152. if (cipher_info == NULL) {
  153. return PSA_ERROR_NOT_SUPPORTED;
  154. }
  155. ret = mbedtls_cipher_setup(&operation->ctx.cmac, cipher_info);
  156. if (ret != 0) {
  157. goto exit;
  158. }
  159. ret = mbedtls_cipher_cmac_starts(&operation->ctx.cmac,
  160. key_buffer,
  161. psa_get_key_bits(attributes));
  162. exit:
  163. return mbedtls_to_psa_error(ret);
  164. }
  165. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
  166. #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \
  167. defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
  168. /* Initialize this driver's MAC operation structure. Once this function has been
  169. * called, mbedtls_psa_mac_abort can run and will do the right thing. */
  170. static psa_status_t mac_init(
  171. mbedtls_psa_mac_operation_t *operation,
  172. psa_algorithm_t alg)
  173. {
  174. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  175. operation->alg = alg;
  176. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
  177. if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
  178. mbedtls_cipher_init(&operation->ctx.cmac);
  179. status = PSA_SUCCESS;
  180. } else
  181. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
  182. #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
  183. if (PSA_ALG_IS_HMAC(operation->alg)) {
  184. /* We'll set up the hash operation later in psa_hmac_setup_internal. */
  185. operation->ctx.hmac.alg = 0;
  186. status = PSA_SUCCESS;
  187. } else
  188. #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
  189. {
  190. (void) operation;
  191. status = PSA_ERROR_NOT_SUPPORTED;
  192. }
  193. if (status != PSA_SUCCESS) {
  194. memset(operation, 0, sizeof(*operation));
  195. }
  196. return status;
  197. }
  198. psa_status_t mbedtls_psa_mac_abort(mbedtls_psa_mac_operation_t *operation)
  199. {
  200. if (operation->alg == 0) {
  201. /* The object has (apparently) been initialized but it is not
  202. * in use. It's ok to call abort on such an object, and there's
  203. * nothing to do. */
  204. return PSA_SUCCESS;
  205. } else
  206. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
  207. if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
  208. mbedtls_cipher_free(&operation->ctx.cmac);
  209. } else
  210. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
  211. #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
  212. if (PSA_ALG_IS_HMAC(operation->alg)) {
  213. psa_hmac_abort_internal(&operation->ctx.hmac);
  214. } else
  215. #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
  216. {
  217. /* Sanity check (shouldn't happen: operation->alg should
  218. * always have been initialized to a valid value). */
  219. goto bad_state;
  220. }
  221. operation->alg = 0;
  222. return PSA_SUCCESS;
  223. bad_state:
  224. /* If abort is called on an uninitialized object, we can't trust
  225. * anything. Wipe the object in case it contains confidential data.
  226. * This may result in a memory leak if a pointer gets overwritten,
  227. * but it's too late to do anything about this. */
  228. memset(operation, 0, sizeof(*operation));
  229. return PSA_ERROR_BAD_STATE;
  230. }
  231. static psa_status_t psa_mac_setup(mbedtls_psa_mac_operation_t *operation,
  232. const psa_key_attributes_t *attributes,
  233. const uint8_t *key_buffer,
  234. size_t key_buffer_size,
  235. psa_algorithm_t alg)
  236. {
  237. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  238. /* A context must be freshly initialized before it can be set up. */
  239. if (operation->alg != 0) {
  240. return PSA_ERROR_BAD_STATE;
  241. }
  242. status = mac_init(operation, alg);
  243. if (status != PSA_SUCCESS) {
  244. return status;
  245. }
  246. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
  247. if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) {
  248. /* Key buffer size for CMAC is dictated by the key bits set on the
  249. * attributes, and previously validated by the core on key import. */
  250. (void) key_buffer_size;
  251. status = cmac_setup(operation, attributes, key_buffer);
  252. } else
  253. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
  254. #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
  255. if (PSA_ALG_IS_HMAC(alg)) {
  256. status = psa_hmac_setup_internal(&operation->ctx.hmac,
  257. key_buffer,
  258. key_buffer_size,
  259. PSA_ALG_HMAC_GET_HASH(alg));
  260. } else
  261. #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
  262. {
  263. (void) attributes;
  264. (void) key_buffer;
  265. (void) key_buffer_size;
  266. status = PSA_ERROR_NOT_SUPPORTED;
  267. }
  268. if (status != PSA_SUCCESS) {
  269. mbedtls_psa_mac_abort(operation);
  270. }
  271. return status;
  272. }
  273. psa_status_t mbedtls_psa_mac_sign_setup(
  274. mbedtls_psa_mac_operation_t *operation,
  275. const psa_key_attributes_t *attributes,
  276. const uint8_t *key_buffer,
  277. size_t key_buffer_size,
  278. psa_algorithm_t alg)
  279. {
  280. return psa_mac_setup(operation, attributes,
  281. key_buffer, key_buffer_size, alg);
  282. }
  283. psa_status_t mbedtls_psa_mac_verify_setup(
  284. mbedtls_psa_mac_operation_t *operation,
  285. const psa_key_attributes_t *attributes,
  286. const uint8_t *key_buffer,
  287. size_t key_buffer_size,
  288. psa_algorithm_t alg)
  289. {
  290. return psa_mac_setup(operation, attributes,
  291. key_buffer, key_buffer_size, alg);
  292. }
  293. psa_status_t mbedtls_psa_mac_update(
  294. mbedtls_psa_mac_operation_t *operation,
  295. const uint8_t *input,
  296. size_t input_length)
  297. {
  298. if (operation->alg == 0) {
  299. return PSA_ERROR_BAD_STATE;
  300. }
  301. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
  302. if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
  303. return mbedtls_to_psa_error(
  304. mbedtls_cipher_cmac_update(&operation->ctx.cmac,
  305. input, input_length));
  306. } else
  307. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
  308. #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
  309. if (PSA_ALG_IS_HMAC(operation->alg)) {
  310. return psa_hmac_update_internal(&operation->ctx.hmac,
  311. input, input_length);
  312. } else
  313. #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
  314. {
  315. /* This shouldn't happen if `operation` was initialized by
  316. * a setup function. */
  317. (void) input;
  318. (void) input_length;
  319. return PSA_ERROR_BAD_STATE;
  320. }
  321. }
  322. static psa_status_t psa_mac_finish_internal(
  323. mbedtls_psa_mac_operation_t *operation,
  324. uint8_t *mac, size_t mac_size)
  325. {
  326. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
  327. if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
  328. uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
  329. int ret = mbedtls_cipher_cmac_finish(&operation->ctx.cmac, tmp);
  330. if (ret == 0) {
  331. memcpy(mac, tmp, mac_size);
  332. }
  333. mbedtls_platform_zeroize(tmp, sizeof(tmp));
  334. return mbedtls_to_psa_error(ret);
  335. } else
  336. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
  337. #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
  338. if (PSA_ALG_IS_HMAC(operation->alg)) {
  339. return psa_hmac_finish_internal(&operation->ctx.hmac,
  340. mac, mac_size);
  341. } else
  342. #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
  343. {
  344. /* This shouldn't happen if `operation` was initialized by
  345. * a setup function. */
  346. (void) operation;
  347. (void) mac;
  348. (void) mac_size;
  349. return PSA_ERROR_BAD_STATE;
  350. }
  351. }
  352. psa_status_t mbedtls_psa_mac_sign_finish(
  353. mbedtls_psa_mac_operation_t *operation,
  354. uint8_t *mac,
  355. size_t mac_size,
  356. size_t *mac_length)
  357. {
  358. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  359. if (operation->alg == 0) {
  360. return PSA_ERROR_BAD_STATE;
  361. }
  362. status = psa_mac_finish_internal(operation, mac, mac_size);
  363. if (status == PSA_SUCCESS) {
  364. *mac_length = mac_size;
  365. }
  366. return status;
  367. }
  368. psa_status_t mbedtls_psa_mac_verify_finish(
  369. mbedtls_psa_mac_operation_t *operation,
  370. const uint8_t *mac,
  371. size_t mac_length)
  372. {
  373. uint8_t actual_mac[PSA_MAC_MAX_SIZE];
  374. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  375. if (operation->alg == 0) {
  376. return PSA_ERROR_BAD_STATE;
  377. }
  378. /* Consistency check: requested MAC length fits our local buffer */
  379. if (mac_length > sizeof(actual_mac)) {
  380. return PSA_ERROR_INVALID_ARGUMENT;
  381. }
  382. status = psa_mac_finish_internal(operation, actual_mac, mac_length);
  383. if (status != PSA_SUCCESS) {
  384. goto cleanup;
  385. }
  386. if (mbedtls_ct_memcmp(mac, actual_mac, mac_length) != 0) {
  387. status = PSA_ERROR_INVALID_SIGNATURE;
  388. }
  389. cleanup:
  390. mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
  391. return status;
  392. }
  393. psa_status_t mbedtls_psa_mac_compute(
  394. const psa_key_attributes_t *attributes,
  395. const uint8_t *key_buffer,
  396. size_t key_buffer_size,
  397. psa_algorithm_t alg,
  398. const uint8_t *input,
  399. size_t input_length,
  400. uint8_t *mac,
  401. size_t mac_size,
  402. size_t *mac_length)
  403. {
  404. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  405. mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
  406. status = psa_mac_setup(&operation,
  407. attributes, key_buffer, key_buffer_size,
  408. alg);
  409. if (status != PSA_SUCCESS) {
  410. goto exit;
  411. }
  412. if (input_length > 0) {
  413. status = mbedtls_psa_mac_update(&operation, input, input_length);
  414. if (status != PSA_SUCCESS) {
  415. goto exit;
  416. }
  417. }
  418. status = psa_mac_finish_internal(&operation, mac, mac_size);
  419. if (status == PSA_SUCCESS) {
  420. *mac_length = mac_size;
  421. }
  422. exit:
  423. mbedtls_psa_mac_abort(&operation);
  424. return status;
  425. }
  426. #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || MBEDTLS_PSA_BUILTIN_ALG_CMAC */
  427. #endif /* MBEDTLS_PSA_CRYPTO_C */