Skip to content

Commit

Permalink
[crypto] Add Operational Keystore for PSA crypto API (#23857)
Browse files Browse the repository at this point in the history
* Move some PSA structures to header

Signed-off-by: Damian Krolik <[email protected]>

* [crypto] Add Operational Keystore for PSA crypto API

Signed-off-by: Damian Krolik <[email protected]>

* Fix build

* Code review

* Code review

Signed-off-by: Damian Krolik <[email protected]>
  • Loading branch information
Damian-Nordic authored Dec 13, 2022
1 parent 64b2ca4 commit 12b1744
Show file tree
Hide file tree
Showing 9 changed files with 604 additions and 30 deletions.
7 changes: 6 additions & 1 deletion src/crypto/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ if (chip_crypto == "openssl") {
import("//build_overrides/mbedtls.gni")

source_set("cryptopal_psa") {
sources = [ "CHIPCryptoPALPSA.cpp" ]
sources = [
"CHIPCryptoPALPSA.cpp",
"CHIPCryptoPALPSA.h",
"PSAOperationalKeystore.cpp",
"PSAOperationalKeystore.h",
]
public_deps = [ ":public_headers" ]

external_mbedtls = current_os == "zephyr"
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/CHIPCryptoPAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ class P256Keypair : public P256KeypairBase
/** Release resources associated with this key pair */
void Clear();

private:
protected:
P256PublicKey mPublicKey;
mutable P256KeypairContext mKeypair;
bool mInitialized = false;
Expand Down
29 changes: 7 additions & 22 deletions src/crypto/CHIPCryptoPALPSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* PSA Crypto API based implementation of CHIP crypto primitives
*/

#include "CHIPCryptoPAL.h"
#include "CHIPCryptoPALPSA.h"

#include <lib/core/CHIPEncoding.h>
#include <lib/core/CHIPSafeCasts.h>
Expand Down Expand Up @@ -500,21 +500,6 @@ mbedtls_ecp_group_id MapECPGroupId(SupportedECPKeyTypes keyType)
}
}

struct PsaP256KeypairContext
{
psa_key_id_t key_id;
};

static inline PsaP256KeypairContext & to_keypair_ctx(P256KeypairContext & context)
{
return *SafePointerCast<PsaP256KeypairContext *>(&context);
}

static inline const PsaP256KeypairContext & to_const_keypair_ctx(const P256KeypairContext & context)
{
return *SafePointerCast<const PsaP256KeypairContext *>(&context);
}

CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_length, P256ECDSASignature & out_signature) const
{
VerifyOrReturnError(mInitialized, CHIP_ERROR_WELL_UNINITIALIZED);
Expand All @@ -523,7 +508,7 @@ CHIP_ERROR P256Keypair::ECDSA_sign_msg(const uint8_t * msg, const size_t msg_len
CHIP_ERROR error = CHIP_NO_ERROR;
psa_status_t status = PSA_SUCCESS;
size_t outputLen = 0;
const PsaP256KeypairContext & context = to_const_keypair_ctx(mKeypair);
const PSAP256KeypairContext & context = toConstPSAContext(mKeypair);

status = psa_sign_message(context.key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), msg, msg_length, out_signature.Bytes(),
out_signature.Capacity(), &outputLen);
Expand Down Expand Up @@ -600,7 +585,7 @@ CHIP_ERROR P256Keypair::ECDH_derive_secret(const P256PublicKey & remote_public_k

CHIP_ERROR error = CHIP_NO_ERROR;
psa_status_t status = PSA_SUCCESS;
const PsaP256KeypairContext & context = to_const_keypair_ctx(mKeypair);
const PSAP256KeypairContext & context = toConstPSAContext(mKeypair);
const size_t outputSize = (out_secret.Length() == 0) ? out_secret.Capacity() : out_secret.Length();
size_t outputLength;

Expand Down Expand Up @@ -653,7 +638,7 @@ CHIP_ERROR P256Keypair::Initialize(ECPKeyTarget key_target)
CHIP_ERROR error = CHIP_NO_ERROR;
psa_status_t status = PSA_SUCCESS;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
PsaP256KeypairContext & context = to_keypair_ctx(mKeypair);
PSAP256KeypairContext & context = toPSAContext(mKeypair);
size_t publicKeyLength = 0;

// Type based on ECC with the elliptic curve SECP256r1 -> PSA_ECC_FAMILY_SECP_R1
Expand Down Expand Up @@ -695,7 +680,7 @@ CHIP_ERROR P256Keypair::Serialize(P256SerializedKeypair & output) const
{
CHIP_ERROR error = CHIP_NO_ERROR;
psa_status_t status = PSA_SUCCESS;
const PsaP256KeypairContext & context = to_const_keypair_ctx(mKeypair);
const PSAP256KeypairContext & context = toConstPSAContext(mKeypair);
const size_t outputSize = output.Length() == 0 ? output.Capacity() : output.Length();
Encoding::BufferWriter bbuf(output, outputSize);
uint8_t privateKey[kP256_PrivateKey_Length];
Expand Down Expand Up @@ -723,7 +708,7 @@ CHIP_ERROR P256Keypair::Deserialize(P256SerializedKeypair & input)
CHIP_ERROR error = CHIP_NO_ERROR;
psa_status_t status = PSA_SUCCESS;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
PsaP256KeypairContext & context = to_keypair_ctx(mKeypair);
PSAP256KeypairContext & context = toPSAContext(mKeypair);
Encoding::BufferWriter bbuf(mPublicKey, mPublicKey.Length());

Clear();
Expand Down Expand Up @@ -751,7 +736,7 @@ void P256Keypair::Clear()
{
if (mInitialized)
{
PsaP256KeypairContext & context = to_keypair_ctx(mKeypair);
PSAP256KeypairContext & context = toPSAContext(mKeypair);
psa_destroy_key(context.key_id);
memset(&context, 0, sizeof(context));
mInitialized = false;
Expand Down
81 changes: 81 additions & 0 deletions src/crypto/CHIPCryptoPALPSA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "CHIPCryptoPAL.h"
#include <lib/core/DataModelTypes.h>
#include <lib/support/SafePointerCast.h>

#include <psa/crypto.h>

namespace chip {
namespace Crypto {

/**
* @def CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE
*
* @brief
* Base for PSA key identifier range used by Matter.
*
* Cryptographic keys stored in the PSA Internal Trusted Storage must have
* a user-assigned identifer from the range PSA_KEY_ID_USER_MIN to
* PSA_KEY_ID_USER_MAX. This option allows to override the base used to derive
* key identifiers used by Matter to avoid overlapping with other firmware
* components that also use PSA crypto API. The default value was selected
* not to interfere with OpenThread's default base that is 0x20000.
*
* Note that volatile keys like ephemeral keys used for ECDH have identifiers
* auto-assigned by the PSA backend.
*/
#ifndef CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE
#define CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE 0x30000
#endif // CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE

static_assert(CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE >= PSA_KEY_ID_USER_MIN &&
CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE <= PSA_KEY_ID_USER_MAX,
"PSA key ID base out of allowed range");

enum class KeyIdBase : psa_key_id_t
{
// Define key ID range for Node Operational Certificate private keys
Operational = CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE
};

constexpr psa_key_id_t MakeOperationalKeyId(FabricIndex fabricIndex)
{
return to_underlying(KeyIdBase::Operational) + static_cast<psa_key_id_t>(fabricIndex);
}

struct PSAP256KeypairContext
{
psa_key_id_t key_id;
};

static inline PSAP256KeypairContext & toPSAContext(P256KeypairContext & context)
{
return *SafePointerCast<PSAP256KeypairContext *>(&context);
}

static inline const PSAP256KeypairContext & toConstPSAContext(const P256KeypairContext & context)
{
return *SafePointerCast<const PSAP256KeypairContext *>(&context);
}

} // namespace Crypto
} // namespace chip
Loading

0 comments on commit 12b1744

Please sign in to comment.