[crypto] move Pskc generation to platform API (#8468)

This commit is contained in:
Eduardo Montoya
2022-12-09 22:05:06 -08:00
committed by GitHub
parent 507d1b7971
commit 35f51e2b17
10 changed files with 111 additions and 216 deletions
-1
View File
@@ -257,7 +257,6 @@ LOCAL_SRC_FILES := \
src/core/crypto/hkdf_sha256.cpp \
src/core/crypto/hmac_sha256.cpp \
src/core/crypto/mbedtls.cpp \
src/core/crypto/pbkdf2_cmac.cpp \
src/core/crypto/sha256.cpp \
src/core/crypto/storage.cpp \
src/core/diags/factory_diags.cpp \
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (266)
#define OPENTHREAD_API_VERSION (267)
/**
* @addtogroup api-instance
+26
View File
@@ -219,6 +219,12 @@ struct otPlatCryptoEcdsaSignature
typedef struct otPlatCryptoEcdsaSignature otPlatCryptoEcdsaSignature;
/**
* Max PBKDF2 SALT length: salt prefix (6) + extended panid (8) + network name (16)
*
*/
#define OT_CRYPTO_PBDKF2_MAX_SALT_SIZE 30
/**
* Initialize the Crypto module.
*
@@ -644,6 +650,26 @@ otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
const otPlatCryptoSha256Hash *aHash,
const otPlatCryptoEcdsaSignature *aSignature);
/**
* Perform PKCS#5 PBKDF2 using CMAC (AES-CMAC-PRF-128).
*
* @param[in] aPassword Password to use when generating key.
* @param[in] aPasswordLen Length of password.
* @param[in] aSalt Salt to use when generating key.
* @param[in] aSaltLen Length of salt.
* @param[in] aIterationCounter Iteration count.
* @param[in] aKeyLen Length of generated key in bytes.
* @param[out] aKey A pointer to the generated key.
*
*/
void otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
uint16_t aPasswordLen,
const uint8_t *aSalt,
uint16_t aSaltLen,
uint32_t aIterationCounter,
uint16_t aKeyLen,
uint8_t *aKey);
/**
* @}
*
-2
View File
@@ -469,8 +469,6 @@ openthread_core_files = [
"crypto/hmac_sha256.hpp",
"crypto/mbedtls.cpp",
"crypto/mbedtls.hpp",
"crypto/pbkdf2_cmac.cpp",
"crypto/pbkdf2_cmac.hpp",
"crypto/sha256.cpp",
"crypto/sha256.hpp",
"crypto/storage.cpp",
-1
View File
@@ -124,7 +124,6 @@ set(COMMON_SOURCES
crypto/hkdf_sha256.cpp
crypto/hmac_sha256.cpp
crypto/mbedtls.cpp
crypto/pbkdf2_cmac.cpp
crypto/sha256.cpp
crypto/storage.cpp
diags/factory_diags.cpp
-2
View File
@@ -214,7 +214,6 @@ SOURCES_COMMON = \
crypto/hkdf_sha256.cpp \
crypto/hmac_sha256.cpp \
crypto/mbedtls.cpp \
crypto/pbkdf2_cmac.cpp \
crypto/sha256.cpp \
crypto/storage.cpp \
diags/factory_diags.cpp \
@@ -529,7 +528,6 @@ HEADERS_COMMON = \
crypto/hkdf_sha256.hpp \
crypto/hmac_sha256.hpp \
crypto/mbedtls.hpp \
crypto/pbkdf2_cmac.hpp \
crypto/sha256.hpp \
crypto/storage.hpp \
diags/factory_diags.hpp \
+81
View File
@@ -32,7 +32,10 @@
#include "openthread-core-config.h"
#include <string.h>
#include <mbedtls/aes.h>
#include <mbedtls/cmac.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/ecdsa.h>
#include <mbedtls/entropy.h>
@@ -660,3 +663,81 @@ exit:
#endif // #if !OPENTHREAD_RADIO
#endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
//---------------------------------------------------------------------------------------------------------------------
// APIs to be used in "hybrid" mode by every OPENTHREAD_CONFIG_CRYPTO_LIB variant until full PSA support is ready
#if OPENTHREAD_FTD
OT_TOOL_WEAK void otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
uint16_t aPasswordLen,
const uint8_t *aSalt,
uint16_t aSaltLen,
uint32_t aIterationCounter,
uint16_t aKeyLen,
uint8_t *aKey)
{
const size_t kBlockSize = MBEDTLS_CIPHER_BLKSIZE_MAX;
uint8_t prfInput[OT_CRYPTO_PBDKF2_MAX_SALT_SIZE + 4]; // Salt || INT(), for U1 calculation
long prfOne[kBlockSize / sizeof(long)];
long prfTwo[kBlockSize / sizeof(long)];
long keyBlock[kBlockSize / sizeof(long)];
uint32_t blockCounter = 0;
uint8_t *key = aKey;
uint16_t keyLen = aKeyLen;
uint16_t useLen = 0;
OT_ASSERT(aSaltLen <= sizeof(prfInput));
memcpy(prfInput, aSalt, aSaltLen);
OT_ASSERT(aIterationCounter % 2 == 0);
aIterationCounter /= 2;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// limit iterations to avoid OSS-Fuzz timeouts
aIterationCounter = 2;
#endif
while (keyLen)
{
++blockCounter;
prfInput[aSaltLen + 0] = static_cast<uint8_t>(blockCounter >> 24);
prfInput[aSaltLen + 1] = static_cast<uint8_t>(blockCounter >> 16);
prfInput[aSaltLen + 2] = static_cast<uint8_t>(blockCounter >> 8);
prfInput[aSaltLen + 3] = static_cast<uint8_t>(blockCounter);
// Calculate U_1
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, prfInput, aSaltLen + 4,
reinterpret_cast<uint8_t *>(keyBlock));
// Calculate U_2
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(keyBlock), kBlockSize,
reinterpret_cast<uint8_t *>(prfOne));
for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
{
keyBlock[j] ^= prfOne[j];
}
for (uint32_t i = 1; i < aIterationCounter; ++i)
{
// Calculate U_{2 * i - 1}
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfOne), kBlockSize,
reinterpret_cast<uint8_t *>(prfTwo));
// Calculate U_{2 * i}
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfTwo), kBlockSize,
reinterpret_cast<uint8_t *>(prfOne));
for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
{
keyBlock[j] ^= prfOne[j] ^ prfTwo[j];
}
}
useLen = (keyLen < kBlockSize) ? keyLen : kBlockSize;
memcpy(key, keyBlock, useLen);
key += useLen;
keyLen -= useLen;
}
}
#endif // #if OPENTHREAD_FTD
-121
View File
@@ -1,121 +0,0 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements PBKDF2 using AES-CMAC-PRF-128
*/
#include "pbkdf2_cmac.hpp"
#include <mbedtls/cmac.h>
#include <string.h>
#include "common/debug.hpp"
namespace ot {
namespace Crypto {
namespace Pbkdf2 {
#if OPENTHREAD_FTD
void GenerateKey(const uint8_t *aPassword,
uint16_t aPasswordLen,
const uint8_t *aSalt,
uint16_t aSaltLen,
uint32_t aIterationCounter,
uint16_t aKeyLen,
uint8_t *aKey)
{
const size_t kBlockSize = MBEDTLS_CIPHER_BLKSIZE_MAX;
uint8_t prfInput[kMaxSaltLength + 4]; // Salt || INT(), for U1 calculation
long prfOne[kBlockSize / sizeof(long)];
long prfTwo[kBlockSize / sizeof(long)];
long keyBlock[kBlockSize / sizeof(long)];
uint32_t blockCounter = 0;
uint8_t *key = aKey;
uint16_t keyLen = aKeyLen;
uint16_t useLen = 0;
memcpy(prfInput, aSalt, aSaltLen);
OT_ASSERT(aIterationCounter % 2 == 0);
aIterationCounter /= 2;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// limit iterations to avoid OSS-Fuzz timeouts
aIterationCounter = 2;
#endif
while (keyLen)
{
++blockCounter;
prfInput[aSaltLen + 0] = static_cast<uint8_t>(blockCounter >> 24);
prfInput[aSaltLen + 1] = static_cast<uint8_t>(blockCounter >> 16);
prfInput[aSaltLen + 2] = static_cast<uint8_t>(blockCounter >> 8);
prfInput[aSaltLen + 3] = static_cast<uint8_t>(blockCounter);
// Calculate U_1
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, prfInput, aSaltLen + 4,
reinterpret_cast<uint8_t *>(keyBlock));
// Calculate U_2
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(keyBlock), kBlockSize,
reinterpret_cast<uint8_t *>(prfOne));
for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
{
keyBlock[j] ^= prfOne[j];
}
for (uint32_t i = 1; i < aIterationCounter; ++i)
{
// Calculate U_{2 * i - 1}
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfOne), kBlockSize,
reinterpret_cast<uint8_t *>(prfTwo));
// Calculate U_{2 * i}
mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfTwo), kBlockSize,
reinterpret_cast<uint8_t *>(prfOne));
for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
{
keyBlock[j] ^= prfOne[j] ^ prfTwo[j];
}
}
useLen = (keyLen < kBlockSize) ? keyLen : kBlockSize;
memcpy(key, keyBlock, useLen);
key += useLen;
keyLen -= useLen;
}
}
#endif // OPENTHREAD_FTD
} // namespace Pbkdf2
} // namespace Crypto
} // namespace ot
-84
View File
@@ -1,84 +0,0 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file includes definitions for performing Password-Based Key Derivation Function 2 (PBKDF2) using CMAC.
*/
#ifndef PBKDF2_CMAC_HPP_
#define PBKDF2_CMAC_HPP_
#include "openthread-core-config.h"
#include <stdint.h>
namespace ot {
namespace Crypto {
namespace Pbkdf2 {
/**
* @addtogroup core-security
*
* @{
*
*/
constexpr uint16_t kMaxSaltLength = 30; ///< Max SALT length: salt prefix (6) + extended panid (8) + network name (16)
/**
* This function performs PKCS#5 PBKDF2 using CMAC (AES-CMAC-PRF-128).
*
* @param[in] aPassword Password to use when generating key.
* @param[in] aPasswordLen Length of password.
* @param[in] aSalt Salt to use when generating key.
* @param[in] aSaltLen Length of salt.
* @param[in] aIterationCounter Iteration count.
* @param[in] aKeyLen Length of generated key in bytes.
* @param[out] aKey A pointer to the generated key.
*
*/
void GenerateKey(const uint8_t *aPassword,
uint16_t aPasswordLen,
const uint8_t *aSalt,
uint16_t aSaltLen,
uint32_t aIterationCounter,
uint16_t aKeyLen,
uint8_t *aKey);
/**
* @}
*
*/
} // namespace Pbkdf2
} // namespace Crypto
} // namespace ot
#endif // PBKDF2_CMAC_HPP_
+3 -4
View File
@@ -37,7 +37,6 @@
#include "common/debug.hpp"
#include "common/locator_getters.hpp"
#include "common/string.hpp"
#include "crypto/pbkdf2_cmac.hpp"
#include "crypto/sha256.hpp"
#include "mac/mac_types.hpp"
#include "thread/thread_netif.hpp"
@@ -324,7 +323,7 @@ Error GeneratePskc(const char *aPassPhrase,
{
Error error = kErrorNone;
const char saltPrefix[] = "Thread";
uint8_t salt[Crypto::Pbkdf2::kMaxSaltLength];
uint8_t salt[OT_CRYPTO_PBDKF2_MAX_SALT_SIZE];
uint16_t saltLen = 0;
uint16_t passphraseLen;
uint8_t networkNameLen;
@@ -349,8 +348,8 @@ Error GeneratePskc(const char *aPassPhrase,
memcpy(salt + saltLen, aNetworkName.GetAsCString(), networkNameLen);
saltLen += networkNameLen;
Crypto::Pbkdf2::GenerateKey(reinterpret_cast<const uint8_t *>(aPassPhrase), passphraseLen, salt, saltLen, 16384,
OT_PSKC_MAX_SIZE, aPskc.m8);
otPlatCryptoPbkdf2GenerateKey(reinterpret_cast<const uint8_t *>(aPassPhrase), passphraseLen, salt, saltLen, 16384,
OT_PSKC_MAX_SIZE, aPskc.m8);
exit:
return error;