|
19 | 19 | #include <mbedtls/asn1.h>
|
20 | 20 | #endif
|
21 | 21 |
|
| 22 | +#if defined(CONFIG_OPENTHREAD_FTD) && defined(CONFIG_PSA_WANT_ALG_CMAC) && \ |
| 23 | + !defined(CONFIG_BUILD_WITH_TFM) |
| 24 | +#include <zephyr/sys/util.h> |
| 25 | +#include <zephyr/sys/byteorder.h> |
| 26 | +#include <mbedtls/cmac.h> |
| 27 | +#endif |
| 28 | + |
22 | 29 | static otError psaToOtError(psa_status_t aStatus)
|
23 | 30 | {
|
24 | 31 | switch (aStatus) {
|
@@ -604,3 +611,86 @@ otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)
|
604 | 611 | }
|
605 | 612 |
|
606 | 613 | #endif /* #if CONFIG_OPENTHREAD_ECDSA */
|
| 614 | + |
| 615 | +#if defined(CONFIG_OPENTHREAD_FTD) && defined(CONFIG_PSA_WANT_ALG_CMAC) && \ |
| 616 | + !defined(CONFIG_BUILD_WITH_TFM) |
| 617 | + |
| 618 | +otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword, uint16_t aPasswordLen, |
| 619 | + const uint8_t *aSalt, uint16_t aSaltLen, |
| 620 | + uint32_t aIterationCounter, uint16_t aKeyLen, uint8_t *aKey) |
| 621 | +{ |
| 622 | + /* |
| 623 | + * This is a fallback for legacy MbedTLS implementation for PBKDF2 generation, |
| 624 | + * as PSA support for these operations is not yet available. |
| 625 | + * Openthread requires platform to implement PBKDF2 generation if PSA Crypto API is used. |
| 626 | + */ |
| 627 | + const size_t block_size = MBEDTLS_CMAC_MAX_BLOCK_SIZE; |
| 628 | + uint8_t prf_input[OT_CRYPTO_PBDKF2_MAX_SALT_SIZE + sizeof(uint32_t)]; |
| 629 | + uint32_t prf_one[block_size / sizeof(uint32_t)]; |
| 630 | + uint32_t prf_two[block_size / sizeof(uint32_t)]; |
| 631 | + uint32_t key_block[block_size / sizeof(uint32_t)]; |
| 632 | + uint32_t block_counter = 0; |
| 633 | + uint8_t *key = aKey; |
| 634 | + uint16_t key_len = aKeyLen; |
| 635 | + uint16_t use_len = 0; |
| 636 | + int ret; |
| 637 | + |
| 638 | + __ASSERT_NO_MSG(aSaltLen <= sizeof(prf_input)); |
| 639 | + memcpy(prf_input, aSalt, aSaltLen); |
| 640 | + __ASSERT_NO_MSG(aIterationCounter % 2 == 0); |
| 641 | + aIterationCounter /= 2; |
| 642 | + |
| 643 | + while (key_len) { |
| 644 | + block_counter++; |
| 645 | + sys_put_be32(block_counter, &prf_input[aSaltLen]); |
| 646 | + |
| 647 | + /* Calculate U_1 */ |
| 648 | + ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, (const uint8_t *)prf_input, |
| 649 | + aSaltLen + sizeof(uint32_t), (uint8_t *)key_block); |
| 650 | + if (ret != 0) { |
| 651 | + return OT_ERROR_FAILED; |
| 652 | + } |
| 653 | + |
| 654 | + /* Calculate U_2 */ |
| 655 | + ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, (const uint8_t *)key_block, |
| 656 | + block_size, (uint8_t *)prf_one); |
| 657 | + if (ret != 0) { |
| 658 | + return OT_ERROR_FAILED; |
| 659 | + } |
| 660 | + |
| 661 | + for (uint32_t j = 0; j < block_size / sizeof(uint32_t); j++) { |
| 662 | + key_block[j] ^= prf_one[j]; |
| 663 | + } |
| 664 | + |
| 665 | + for (uint32_t i = 1; i < aIterationCounter; i++) { |
| 666 | + /* Calculate U_{2 * i - 1} */ |
| 667 | + ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, |
| 668 | + (const uint8_t *)prf_one, |
| 669 | + block_size, (uint8_t *)prf_two); |
| 670 | + if (ret != 0) { |
| 671 | + return OT_ERROR_FAILED; |
| 672 | + } |
| 673 | + |
| 674 | + /* Calculate U_{2 * i} */ |
| 675 | + ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, |
| 676 | + (const uint8_t *)prf_two, |
| 677 | + block_size, (uint8_t *)prf_one); |
| 678 | + if (ret != 0) { |
| 679 | + return OT_ERROR_FAILED; |
| 680 | + } |
| 681 | + |
| 682 | + for (uint32_t j = 0; j < block_size / sizeof(uint32_t); j++) { |
| 683 | + key_block[j] ^= prf_one[j] ^ prf_two[j]; |
| 684 | + } |
| 685 | + } |
| 686 | + |
| 687 | + use_len = MIN(key_len, (uint16_t)block_size); |
| 688 | + memcpy(key, key_block, use_len); |
| 689 | + key += use_len; |
| 690 | + key_len -= use_len; |
| 691 | + } |
| 692 | + |
| 693 | + return OT_ERROR_NONE; |
| 694 | +} |
| 695 | + |
| 696 | +#endif /* #if CONFIG_OPENTHREAD_FTD && CONFIG_PSA_WANT_ALG_CMAC && !CONFIG_BUILD_WITH_TFM */ |
0 commit comments