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

Update SPAKE2p pairing code to match spec #4166

Merged
merged 6 commits into from
Dec 12, 2020
Merged
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
20 changes: 12 additions & 8 deletions src/crypto/CHIPCryptoPAL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ Spake2p::Spake2p(size_t _fe_size, size_t _point_size, size_t _hash_size)
tempbn = nullptr;
}

CHIP_ERROR Spake2p::Init(const uint8_t * context, size_t context_len)
CHIP_ERROR Spake2p::Init(const Hash_SHA256_stream * context)
{
CHIP_ERROR error = CHIP_ERROR_INTERNAL;
state = CHIP_SPAKE2P_STATE::PREINIT;

error = InitImpl();
error = InitImpl(context);
VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);

error = PointLoad(spake2p_M_p256, sizeof(spake2p_M_p256), M);
Expand All @@ -96,9 +96,6 @@ CHIP_ERROR Spake2p::Init(const uint8_t * context, size_t context_len)
error = PointLoad(spake2p_N_p256, sizeof(spake2p_N_p256), N);
VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);

error = InternalHash(context, context_len);
VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);

state = CHIP_SPAKE2P_STATE::INIT;
error = CHIP_NO_ERROR;
exit:
Expand Down Expand Up @@ -387,12 +384,19 @@ CHIP_ERROR Spake2p::GetKeys(uint8_t * out, size_t * out_len)
return error;
}

CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitImpl()
CHIP_ERROR Spake2p_P256_SHA256_HKDF_HMAC::InitImpl(const Hash_SHA256_stream * context)
{
CHIP_ERROR error = CHIP_ERROR_INTERNAL;

error = sha256_hash_ctx.Begin();
VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
if (context != nullptr)
{
sha256_hash_ctx = (*context);
pan-apple marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
error = sha256_hash_ctx.Begin();
VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
}

error = InitInternal();
VerifyOrExit(error == CHIP_NO_ERROR, error = CHIP_ERROR_INTERNAL);
Expand Down
15 changes: 8 additions & 7 deletions src/crypto/CHIPCryptoPAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ CHIP_ERROR Hash_SHA256(const uint8_t * data, size_t data_length, uint8_t * out_b

/**
* @brief A class that defines stream based implementation of SHA-256 hash
* It's expected that the object of this class can be safely copied.
* All implementations must check for std::is_trivially_copyable.
**/

struct HashSHA256OpaqueContext
Expand Down Expand Up @@ -456,14 +458,13 @@ class Spake2p
/**
* @brief Initialize Spake2+ with some context specific information.
*
* @param context The context is arbitrary but should include information about the
* protocol being run, contain the transcript for negotiation, include
* the PKBDF parameters, etc.
* @param context_len The length of the context.
* @param context The spake2p session will bootstrap from this hash context.
* If the provided context pointer is null, the spake2p session will bootstrap
* from a blank hash context.
*
* @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
**/
CHIP_ERROR Init(const uint8_t * context, size_t context_len);
CHIP_ERROR Init(const Hash_SHA256_stream * context);

/**
* @brief Start the Spake2+ process as a verifier (i.e. an accessory being provisioned).
Expand Down Expand Up @@ -716,7 +717,7 @@ class Spake2p
*
* @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
**/
virtual CHIP_ERROR InitImpl() = 0;
virtual CHIP_ERROR InitImpl(const Hash_SHA256_stream * context) = 0;

/**
* @brief Hash in_len bytes of in into the internal hash context.
Expand Down Expand Up @@ -828,7 +829,7 @@ class Spake2p_P256_SHA256_HKDF_HMAC : public Spake2p
CHIP_ERROR ComputeL(uint8_t * Lout, size_t * L_len, const uint8_t * w1in, size_t w1in_len) override;

protected:
CHIP_ERROR InitImpl() override;
CHIP_ERROR InitImpl(const Hash_SHA256_stream * context) override;
CHIP_ERROR Hash(const uint8_t * in, size_t in_len) override;
CHIP_ERROR HashFinalize(uint8_t * out) override;
CHIP_ERROR KDF(const uint8_t * secret, size_t secret_length, const uint8_t * salt, size_t salt_length, const uint8_t * info,
Expand Down
5 changes: 4 additions & 1 deletion src/crypto/CHIPCryptoPALOpenSSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include "CHIPCryptoPAL.h"

#include <type_traits>

#include <openssl/bn.h>
#include <openssl/conf.h>
#include <openssl/ec.h>
Expand Down Expand Up @@ -298,7 +300,8 @@ Hash_SHA256_stream::~Hash_SHA256_stream() {}

static inline SHA256_CTX * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context)
{
nlSTATIC_ASSERT_PRINT(sizeof(HashSHA256OpaqueContext) >= sizeof(SHA256_CTX), "Need more memory for SHA256 Context");
static_assert(sizeof(HashSHA256OpaqueContext) >= sizeof(SHA256_CTX), "Need more memory for SHA256 Context");
static_assert(std::is_trivially_copyable<SHA256_CTX>(), "SHA256_CTX values must copyable");
return reinterpret_cast<SHA256_CTX *>(context->mOpaque);
}

Expand Down
5 changes: 4 additions & 1 deletion src/crypto/CHIPCryptoPALmbedTLS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include "CHIPCryptoPAL.h"

#include <type_traits>

#include <mbedtls/bignum.h>
#include <mbedtls/ccm.h>
#include <mbedtls/ctr_drbg.h>
Expand Down Expand Up @@ -192,7 +194,8 @@ Hash_SHA256_stream::~Hash_SHA256_stream(void) {}

static inline mbedtls_sha256_context * to_inner_hash_sha256_context(HashSHA256OpaqueContext * context)
{
nlSTATIC_ASSERT_PRINT(sizeof(context->mOpaque) >= sizeof(mbedtls_sha256_context), "Need more memory for SHA256 Context");
static_assert(sizeof(context->mOpaque) >= sizeof(mbedtls_sha256_context), "Need more memory for SHA256 Context");
static_assert(std::is_trivially_copyable<mbedtls_sha256_context>(), "mbedtls_sha256_context values must copyable");
return reinterpret_cast<mbedtls_sha256_context *>(context->mOpaque);
}

Expand Down
26 changes: 17 additions & 9 deletions src/crypto/tests/CHIPCryptoPALTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ static void TestSPAKE2P_spake2p_FEMul(nlTestSuite * inSuite, void * inContext)
const struct spake2p_fe_mul_tv * vector = fe_mul_tvs[vectorIndex];

Spake2p_P256_SHA256_HKDF_HMAC spake2p;
CHIP_ERROR err = spake2p.Init(nullptr, 0);
CHIP_ERROR err = spake2p.Init(nullptr);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = spake2p.FELoad(vector->fe1, vector->fe1_len, spake2p.w0);
Expand Down Expand Up @@ -1022,7 +1022,7 @@ static void TestSPAKE2P_spake2p_FELoadWrite(nlTestSuite * inSuite, void * inCont
const struct spake2p_fe_rw_tv * vector = fe_rw_tvs[vectorIndex];

Spake2p_P256_SHA256_HKDF_HMAC spake2p;
CHIP_ERROR err = spake2p.Init(nullptr, 0);
CHIP_ERROR err = spake2p.Init(nullptr);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = spake2p.FELoad(vector->fe_in, vector->fe_in_len, spake2p.w0);
Expand All @@ -1049,7 +1049,7 @@ static void TestSPAKE2P_spake2p_Mac(nlTestSuite * inSuite, void * inContext)
const struct spake2p_hmac_tv * vector = hmac_tvs[vectorIndex];

Spake2p_P256_SHA256_HKDF_HMAC spake2p;
CHIP_ERROR err = spake2p.Init(nullptr, 0);
CHIP_ERROR err = spake2p.Init(nullptr);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = spake2p.Mac(vector->key, vector->key_len, vector->input, vector->input_len, mac);
Expand Down Expand Up @@ -1079,7 +1079,7 @@ static void TestSPAKE2P_spake2p_PointMul(nlTestSuite * inSuite, void * inContext
const struct spake2p_point_mul_tv * vector = point_mul_tvs[vectorIndex];

Spake2p_P256_SHA256_HKDF_HMAC spake2p;
CHIP_ERROR err = spake2p.Init(nullptr, 0);
CHIP_ERROR err = spake2p.Init(nullptr);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = spake2p.PointLoad(vector->point, vector->point_len, spake2p.L);
Expand Down Expand Up @@ -1115,7 +1115,7 @@ static void TestSPAKE2P_spake2p_PointMulAdd(nlTestSuite * inSuite, void * inCont
const struct spake2p_point_muladd_tv * vector = point_muladd_tvs[vectorIndex];

Spake2p_P256_SHA256_HKDF_HMAC spake2p;
CHIP_ERROR err = spake2p.Init(nullptr, 0);
CHIP_ERROR err = spake2p.Init(nullptr);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = spake2p.PointLoad(vector->point1, vector->point1_len, spake2p.X);
Expand Down Expand Up @@ -1157,7 +1157,7 @@ static void TestSPAKE2P_spake2p_PointLoadWrite(nlTestSuite * inSuite, void * inC
const struct spake2p_point_rw_tv * vector = point_rw_tvs[vectorIndex];

Spake2p_P256_SHA256_HKDF_HMAC spake2p;
CHIP_ERROR err = spake2p.Init(nullptr, 0);
CHIP_ERROR err = spake2p.Init(nullptr);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = spake2p.PointLoad(vector->point, vector->point_len, spake2p.L);
Expand All @@ -1183,7 +1183,7 @@ static void TestSPAKE2P_spake2p_PointIsValid(nlTestSuite * inSuite, void * inCon
const struct spake2p_point_valid_tv * vector = point_valid_tvs[vectorIndex];

Spake2p_P256_SHA256_HKDF_HMAC spake2p;
CHIP_ERROR err = spake2p.Init(nullptr, 0);
CHIP_ERROR err = spake2p.Init(nullptr);
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

err = spake2p.PointLoad(vector->point, vector->point_len, spake2p.L);
Expand Down Expand Up @@ -1255,8 +1255,16 @@ static void TestSPAKE2P_RFC(nlTestSuite * inSuite, void * inContext)
Test_Spake2p_P256_SHA256_HKDF_HMAC Verifier;
Test_Spake2p_P256_SHA256_HKDF_HMAC Prover;

Hash_SHA256_stream hashContext;

error = hashContext.Begin();
NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR);

error = hashContext.AddData(vector->context, vector->context_len);
NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR);

// First start the prover
error = Prover.Init(vector->context, vector->context_len);
error = Prover.Init(&hashContext);
NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR);

error = Prover.BeginProver(vector->prover_identity, vector->prover_identity_len, vector->verifier_identity,
Expand All @@ -1275,7 +1283,7 @@ static void TestSPAKE2P_RFC(nlTestSuite * inSuite, void * inContext)
NL_TEST_ASSERT(inSuite, memcmp(X, vector->X, vector->X_len) == 0);

// Start up the verifier
error = Verifier.Init(vector->context, vector->context_len);
error = Verifier.Init(&hashContext);
NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR);

// First pre-compute L (accessories with dynamic setup codes will do this)
Expand Down
Loading