psa_crypto_mac.c 15 KB

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