Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[crypto] implement otPlatCryptoPbkdf2GenerateKey() #746

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ot-efr32.slce
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
id: ot-efr32
version: 0.0.1
description: "ot-efr32 extension for Gecko SDK Suite"
label: "Silicon Labs Matter"
label: "Silicon Labs OpenThread"
sdk:
id: gecko_sdk
version: 4.2.1
version: 4.3.2
component_path:
- path: slc/component
10 changes: 10 additions & 0 deletions slc/component/crypto_pbkdf2_generate_key.slcc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
id: crypto_pbkdf2_generate_key
label: Crypto PBKDF2 Key Generation
package: OpenThread
category: OpenThread
quality: production
description: Generates a PBKDF2 key using mbedtls
provides:
- name: crypto_pbkdf2_generate_key
source:
- path: src/src/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ category: OpenThread Examples
quality: production

component:
- id: crypto_pbkdf2_generate_key
from: ot-efr32
- id: ot_platform_abstraction_core
- id: ot_psa_crypto
- id: ot_thirdparty
Expand Down Expand Up @@ -53,3 +55,10 @@ configuration:
define:
- name: OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
value: 1

sdk:
id: gecko_sdk
version: 4.3.2
sdk_extension:
- id: ot-efr32
version: 0.0.1
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ category: OpenThread Examples
quality: production

component:
- id: crypto_pbkdf2_generate_key
from: ot-efr32
- id: ot_platform_abstraction_core
- id: ot_psa_crypto
- id: ot_thirdparty
Expand Down Expand Up @@ -49,3 +51,10 @@ configuration:
condition: [freertos]
- name: SL_STACK_SIZE
value: 4608

sdk:
id: gecko_sdk
version: 4.3.2
sdk_extension:
- id: ot-efr32
version: 0.0.1
9 changes: 9 additions & 0 deletions src/platform_projects/openthread-efr32-soc-with-buttons.slcp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ category: OpenThread Examples
quality: production

component:
- id: crypto_pbkdf2_generate_key
from: ot-efr32
- id: ot_platform_abstraction_core
- id: ot_psa_crypto
- id: ot_thirdparty
Expand Down Expand Up @@ -48,3 +50,10 @@ configuration:
condition: [freertos]
- name: SL_STACK_SIZE
value: 4608

sdk:
id: gecko_sdk
version: 4.3.2
sdk_extension:
- id: ot-efr32
version: 0.0.1
9 changes: 9 additions & 0 deletions src/platform_projects/openthread-efr32-soc.slcp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ category: OpenThread Examples
quality: production

component:
- id: crypto_pbkdf2_generate_key
from: ot-efr32
- id: ot_platform_abstraction_core
- id: ot_psa_crypto
- id: ot_thirdparty
Expand Down Expand Up @@ -35,3 +37,10 @@ configuration:
condition: [freertos]
- name: SL_STACK_SIZE
value: 4608

sdk:
id: gecko_sdk
version: 4.3.2
sdk_extension:
- id: ot-efr32
version: 0.0.1
113 changes: 113 additions & 0 deletions src/src/crypto.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@


#include <string.h>

#include <mbedtls/cmac.h>
#include <mbedtls/version.h>

#include <openthread/platform/crypto.h>

#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/error.hpp"
#include "common/num_utils.hpp"
#include "crypto/mbedtls.hpp"

using namespace ot;
using namespace Crypto;

otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
uint16_t aPasswordLen,
const uint8_t *aSalt,
uint16_t aSaltLen,
uint32_t aIterationCounter,
uint16_t aKeyLen,
uint8_t *aKey)
{
#if (MBEDTLS_VERSION_NUMBER >= 0x03050000)
const size_t kBlockSize = MBEDTLS_CMAC_MAX_BLOCK_SIZE;
#else
const size_t kBlockSize = MBEDTLS_CIPHER_BLKSIZE_MAX;
#endif
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;
Error error = kErrorNone;
int ret;

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
ret = mbedtls_aes_cmac_prf_128(aPassword,
aPasswordLen,
prfInput,
aSaltLen + 4,
reinterpret_cast<uint8_t *>(keyBlock));
VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));

// Calculate U_2
ret = mbedtls_aes_cmac_prf_128(aPassword,
aPasswordLen,
reinterpret_cast<const uint8_t *>(keyBlock),
kBlockSize,
reinterpret_cast<uint8_t *>(prfOne));
VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));

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}
ret = mbedtls_aes_cmac_prf_128(aPassword,
aPasswordLen,
reinterpret_cast<const uint8_t *>(prfOne),
kBlockSize,
reinterpret_cast<uint8_t *>(prfTwo));
VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
// Calculate U_{2 * i}
ret = mbedtls_aes_cmac_prf_128(aPassword,
aPasswordLen,
reinterpret_cast<const uint8_t *>(prfTwo),
kBlockSize,
reinterpret_cast<uint8_t *>(prfOne));
VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));

for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
{
keyBlock[j] ^= prfOne[j] ^ prfTwo[j];
}
}

useLen = Min(keyLen, static_cast<uint16_t>(kBlockSize));
memcpy(key, keyBlock, useLen);
key += useLen;
keyLen -= useLen;
}

exit:
return error;
}