Skip to content

Commit

Permalink
DEBUG IN PROGRESS: PSA symmetric keys.
Browse files Browse the repository at this point in the history
  • Loading branch information
rcasallas-silabs committed Aug 10, 2023
1 parent 931b383 commit 8dc703a
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 202 deletions.
11 changes: 9 additions & 2 deletions src/crypto/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,20 @@ static_library("crypto") {

if (chip_crypto == "psa") {
sources += [
"PSAKeyDerivation.cpp",
"PSAKeyDerivation.h",
"PSASessionKeystore.cpp",
"PSASessionKeystore.h",
]
} else {
sources += [
"RawKeySessionKeystore.cpp",
"RawKeySessionKeystore.h",
"PSAKeyDerivation.cpp",
"PSAKeyDerivation.h",
"PSASessionKeystore.cpp",
"PSASessionKeystore.h",

# "RawKeySessionKeystore.cpp",
# "RawKeySessionKeystore.h",
]
}

Expand Down
48 changes: 1 addition & 47 deletions src/crypto/CHIPCryptoPALPSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

#include "CHIPCryptoPALPSA.h"
#include "PSAKeyDerivation.h"

#include <lib/core/CHIPEncoding.h>
#include <lib/core/CHIPSafeCasts.h>
Expand Down Expand Up @@ -305,53 +306,6 @@ void Hash_SHA256_stream::Clear()
psa_hash_abort(toHashOperation(&mContext));
}

CHIP_ERROR PsaKdf::Init(psa_algorithm_t algorithm, const ByteSpan & secret, const ByteSpan & salt, const ByteSpan & info)
{
psa_status_t status = PSA_SUCCESS;
psa_key_attributes_t attrs = PSA_KEY_ATTRIBUTES_INIT;

psa_set_key_type(&attrs, PSA_KEY_TYPE_DERIVE);
psa_set_key_algorithm(&attrs, PSA_ALG_HKDF(PSA_ALG_SHA_256));
psa_set_key_usage_flags(&attrs, PSA_KEY_USAGE_DERIVE);

status = psa_import_key(&attrs, secret.data(), secret.size(), &mSecretKeyId);
psa_reset_key_attributes(&attrs);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

status = psa_key_derivation_setup(&mOperation, algorithm);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

if (salt.size() > 0)
{
status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_SALT, salt.data(), salt.size());
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);
}

status = psa_key_derivation_input_key(&mOperation, PSA_KEY_DERIVATION_INPUT_SECRET, mSecretKeyId);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_INFO, info.data(), info.size());
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

return CHIP_NO_ERROR;
}

CHIP_ERROR PsaKdf::DeriveBytes(const MutableByteSpan & output)
{
psa_status_t status = psa_key_derivation_output_bytes(&mOperation, output.data(), output.size());
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

return CHIP_NO_ERROR;
}

CHIP_ERROR PsaKdf::DeriveKey(const psa_key_attributes_t & attributes, psa_key_id_t & keyId)
{
psa_status_t status = psa_key_derivation_output_key(&attributes, &mOperation, &keyId);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

return CHIP_NO_ERROR;
}

CHIP_ERROR HKDF_sha::HKDF_SHA256(const uint8_t * secret, const size_t secret_length, const uint8_t * salt, const size_t salt_length,
const uint8_t * info, const size_t info_length, uint8_t * out_buffer, size_t out_length)
{
Expand Down
49 changes: 0 additions & 49 deletions src/crypto/CHIPCryptoPALPSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,54 +94,5 @@ inline const PsaP256KeypairContext & ToConstPsaContext(const P256KeypairContext
return *SafePointerCast<const PsaP256KeypairContext *>(&context);
}

/**
* @brief Wrapper for PSA key derivation API.
*/
class PsaKdf
{
public:
~PsaKdf()
{
psa_key_derivation_abort(&mOperation);
psa_destroy_key(mSecretKeyId);
}

/**
* @brief Initializes the key derivation operation.
*/
CHIP_ERROR Init(psa_algorithm_t algorithm, const ByteSpan & secret, const ByteSpan & salt, const ByteSpan & info);

/**
* @brief Derives raw key material from the operation.
*
* This method together with @p DeriveKeys can be called multiple times to
* derive several keys.
*
* @param[out] output Span that provides location and length for the derived key material.
*
* @retval CHIP_NO_ERROR On success.
* @retval CHIP_ERROR_INTERNAL On PSA crypto API error.
*/
CHIP_ERROR DeriveBytes(const MutableByteSpan & output);

/**
* @brief Derives a key from the operation.
*
* This method together with @p DeriveBytes can be called multiple times to
* derive several keys.
*
* @param[in] attributes Attributes of the derived key.
* @param[out] keyId PSA key ID of the derived key.
*
* @retval CHIP_NO_ERROR On success.
* @retval CHIP_ERROR_INTERNAL On PSA crypto API error.
*/
CHIP_ERROR DeriveKey(const psa_key_attributes_t & attributes, psa_key_id_t & keyId);

private:
psa_key_id_t mSecretKeyId = 0;
psa_key_derivation_operation_t mOperation = PSA_KEY_DERIVATION_OPERATION_INIT;
};

} // namespace Crypto
} // namespace chip
16 changes: 8 additions & 8 deletions src/crypto/DefaultSessionKeystore.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
#include <crypto/CryptoBuildConfig.h>
#endif

#if CHIP_CRYPTO_PSA
// #if CHIP_CRYPTO_PSA
#include <crypto/PSASessionKeystore.h>
#else
#include <crypto/RawKeySessionKeystore.h>
#endif
// #else
// #include <crypto/RawKeySessionKeystore.h>
// #endif

namespace chip {
namespace Crypto {
Expand All @@ -34,11 +34,11 @@ namespace Crypto {
// when the PSA crypto backend is used, AES encryption/decryption function assume that the input
// key handle carries a key reference instead of raw key material, so PSASessionKeystore must be
// used instead of RawKeySessionKeystore to initialize the key handle.
#if CHIP_CRYPTO_PSA
// #if CHIP_CRYPTO_PSA
using DefaultSessionKeystore = PSASessionKeystore;
#else
using DefaultSessionKeystore = RawKeySessionKeystore;
#endif
// #else
// using DefaultSessionKeystore = RawKeySessionKeystore;
// #endif

} // namespace Crypto
} // namespace chip
54 changes: 54 additions & 0 deletions src/crypto/PSAKeyDerivation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "PSAKeyDerivation.h"

namespace chip {
namespace Crypto {

CHIP_ERROR PsaKdf::Init(psa_algorithm_t algorithm, const ByteSpan & secret, const ByteSpan & salt, const ByteSpan & info)
{
psa_status_t status = PSA_SUCCESS;
psa_key_attributes_t attrs = PSA_KEY_ATTRIBUTES_INIT;

psa_set_key_type(&attrs, PSA_KEY_TYPE_DERIVE);
psa_set_key_algorithm(&attrs, PSA_ALG_HKDF(PSA_ALG_SHA_256));
psa_set_key_usage_flags(&attrs, PSA_KEY_USAGE_DERIVE);

status = psa_import_key(&attrs, secret.data(), secret.size(), &mSecretKeyId);
psa_reset_key_attributes(&attrs);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

status = psa_key_derivation_setup(&mOperation, algorithm);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

if (salt.size() > 0)
{
status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_SALT, salt.data(), salt.size());
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);
}

status = psa_key_derivation_input_key(&mOperation, PSA_KEY_DERIVATION_INPUT_SECRET, mSecretKeyId);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_INFO, info.data(), info.size());
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

return CHIP_NO_ERROR;
}

CHIP_ERROR PsaKdf::DeriveBytes(const MutableByteSpan & output)
{
psa_status_t status = psa_key_derivation_output_bytes(&mOperation, output.data(), output.size());
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

return CHIP_NO_ERROR;
}

CHIP_ERROR PsaKdf::DeriveKey(const psa_key_attributes_t & attributes, psa_key_id_t & keyId)
{
psa_status_t status = psa_key_derivation_output_key(&attributes, &mOperation, &keyId);
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);

return CHIP_NO_ERROR;
}

} // namespace Crypto
} // namespace chip
67 changes: 67 additions & 0 deletions src/crypto/PSAKeyDerivation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

#pragma once

#include <lib/core/DataModelTypes.h>
#include <lib/core/CHIPError.h>
// #include <lib/core/CHIPVendorIdentifiers.hpp>
// #include <lib/core/Optional.h>
// #include <lib/support/CodeUtils.h>
// #include <lib/support/SafePointerCast.h>
#include <lib/support/Span.h>
#include <psa/crypto.h>


namespace chip {
namespace Crypto {

/**
* @brief Wrapper for PSA key derivation API.
*/
class PsaKdf
{
public:
~PsaKdf()
{
psa_key_derivation_abort(&mOperation);
psa_destroy_key(mSecretKeyId);
}

/**
* @brief Initializes the key derivation operation.
*/
CHIP_ERROR Init(psa_algorithm_t algorithm, const ByteSpan & secret, const ByteSpan & salt, const ByteSpan & info);

/**
* @brief Derives raw key material from the operation.
*
* This method together with @p DeriveKeys can be called multiple times to
* derive several keys.
*
* @param[out] output Span that provides location and length for the derived key material.
*
* @retval CHIP_NO_ERROR On success.
* @retval CHIP_ERROR_INTERNAL On PSA crypto API error.
*/
CHIP_ERROR DeriveBytes(const MutableByteSpan & output);

/**
* @brief Derives a key from the operation.
*
* This method together with @p DeriveBytes can be called multiple times to
* derive several keys.
*
* @param[in] attributes Attributes of the derived key.
* @param[out] keyId PSA key ID of the derived key.
*
* @retval CHIP_NO_ERROR On success.
* @retval CHIP_ERROR_INTERNAL On PSA crypto API error.
*/
CHIP_ERROR DeriveKey(const psa_key_attributes_t & attributes, psa_key_id_t & keyId);

private:
psa_key_id_t mSecretKeyId = 0;
psa_key_derivation_operation_t mOperation = PSA_KEY_DERIVATION_OPERATION_INIT;
};

} // namespace Crypto
} // namespace chip
23 changes: 20 additions & 3 deletions src/crypto/PSASessionKeystore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

#include "PSASessionKeystore.h"
#include "PSAKeyDerivation.h"

#include <crypto/CHIPCryptoPALPSA.h>

Expand All @@ -35,7 +36,7 @@ class AesKeyAttributes

psa_set_key_type(&mAttrs, PSA_KEY_TYPE_AES);
psa_set_key_algorithm(&mAttrs, kAlgorithm);
psa_set_key_usage_flags(&mAttrs, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_usage_flags(&mAttrs, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT);
psa_set_key_bits(&mAttrs, CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES * 8);
}

Expand All @@ -51,6 +52,8 @@ class AesKeyAttributes

CHIP_ERROR PSASessionKeystore::CreateKey(const Aes128KeyByteArray & keyMaterial, Aes128KeyHandle & key)
{
Progress::Debug("◇ PSASessionKeystore::CreateKey, key:%04x", (unsigned)key.As<psa_key_id_t>());

// Destroy the old key if already allocated
psa_destroy_key(key.As<psa_key_id_t>());

Expand All @@ -65,6 +68,8 @@ CHIP_ERROR PSASessionKeystore::DeriveKey(const P256ECDHDerivedSecret & secret, c
Aes128KeyHandle & key)
{
PsaKdf kdf;

Progress::Debug("◇ PSASessionKeystore::DeriveKey, key:%04x", (unsigned)key.As<psa_key_id_t>());
ReturnErrorOnFailure(kdf.Init(PSA_ALG_HKDF(PSA_ALG_SHA_256), secret.Span(), salt, info));

AesKeyAttributes attrs;
Expand All @@ -77,15 +82,26 @@ CHIP_ERROR PSASessionKeystore::DeriveSessionKeys(const ByteSpan & secret, const
AttestationChallenge & attestationChallenge)
{
PsaKdf kdf;
ReturnErrorOnFailure(kdf.Init(PSA_ALG_HKDF(PSA_ALG_SHA_256), secret, salt, info));

CHIP_ERROR error;
AesKeyAttributes attrs;
uint8_t i2r[sizeof(Aes128KeyByteArray)];
uint8_t r2i[sizeof(Aes128KeyByteArray)];
size_t key_len = 0;
psa_status_t stat1 = 0;
psa_status_t stat2 = 0;

ReturnErrorOnFailure(kdf.Init(PSA_ALG_HKDF(PSA_ALG_SHA_256), secret, salt, info));

SuccessOrExit(error = kdf.DeriveKey(attrs.Get(), i2rKey.AsMutable<psa_key_id_t>()));
SuccessOrExit(error = kdf.DeriveKey(attrs.Get(), r2iKey.AsMutable<psa_key_id_t>()));
SuccessOrExit(error = kdf.DeriveBytes(MutableByteSpan(attestationChallenge.Bytes(), AttestationChallenge::Capacity())));

stat1 = psa_export_key(i2rKey.As<psa_key_id_t>(), i2r, sizeof(i2r), &key_len);
stat2 = psa_export_key(r2iKey.As<psa_key_id_t>(), r2i, sizeof(r2i), &key_len);

Progress::Debug("◇ PSASessionKeystore::DeriveSessionKeys, I2R:%04x [%02x %02x] !%d, R2I:%04x [%02x %02x] !%d",
(unsigned)i2rKey.As<psa_key_id_t>(), i2r[0], i2r[1], stat1, (unsigned)r2iKey.As<psa_key_id_t>(), r2i[0], r2i[1], stat2);

exit:
if (error != CHIP_NO_ERROR)
{
Expand All @@ -100,6 +116,7 @@ void PSASessionKeystore::DestroyKey(Aes128KeyHandle & key)
{
auto & keyId = key.AsMutable<psa_key_id_t>();

Progress::Debug("◇ PSASessionKeystore::DestroyKey, key:%04x", (unsigned)key.As<psa_key_id_t>());
psa_destroy_key(keyId);
keyId = 0;
}
Expand Down
Loading

0 comments on commit 8dc703a

Please sign in to comment.