From 0f780b40ab87a8d007cf9a9b8a9f0f5b6c27210d Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Wed, 22 Apr 2020 16:42:11 -0700 Subject: [PATCH 1/9] Missing openSSL based ECDH implementation #420 --- .vscode/launch.json | 2 +- scripts/tests/openssl_tests.sh | 2 +- src/crypto/CHIPCryptoPAL.h | 14 +++ src/crypto/CHIPCryptoPALOpenSSL.cpp | 152 ++++++++++++++++++++++++- src/crypto/tests/CHIPCryptoPALTest.cpp | 84 +++++++++++++- 5 files changed, 249 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d58a5a1e1a84cc..db4eaa8aa3001a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -48,7 +48,7 @@ "name": "CHIP openSSL Tests", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/default/src/crypto/tests/TestOpenSSLCrypto", + "program": "${workspaceFolder}/build/default/src/crypto/tests/TestCryptoPAL", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/scripts/tests/openssl_tests.sh b/scripts/tests/openssl_tests.sh index 961c20ed02e5b7..dd2f302798ebb5 100755 --- a/scripts/tests/openssl_tests.sh +++ b/scripts/tests/openssl_tests.sh @@ -1,3 +1,3 @@ #!/bin/bash -make -C build/default/src/crypto/ && make -C build/default/src/crypto/tests/ check +make -C build/default/src/crypto/ && make -C build/default/src/crypto/tests/ TestCryptoPAL diff --git a/src/crypto/CHIPCryptoPAL.h b/src/crypto/CHIPCryptoPAL.h index 63b291ea4e8ee4..fdb0f1c28bf262 100644 --- a/src/crypto/CHIPCryptoPAL.h +++ b/src/crypto/CHIPCryptoPAL.h @@ -30,6 +30,7 @@ namespace chip { namespace Crypto { const size_t kMax_ECDSA_Signature_Length = 72; +const size_t kMax_ECDH_Secret_Length = 64; /** * @brief A function that implements 256-bit AES-CCM encryption @@ -162,6 +163,19 @@ CHIP_ERROR ECDSA_sign_msg(const unsigned char * msg, const size_t msg_length, co CHIP_ERROR ECDSA_validate_msg_signature(const unsigned char * msg, const size_t msg_length, const unsigned char * public_key, const size_t public_key_length, const unsigned char * signature, const size_t signature_length); + +/** @brief A function to derive a shared secret using ECDH + * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel + * @param remote_public_key_length Length of remote_public_key + * @param local_private_key Local private key + * @param local_private_key_length Length of private_key_length + * @param out_secret Buffer to write out secret into + * @param out_secret_length Length of out_secret + * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise + **/ +CHIP_ERROR ECDH_derive_secret(const unsigned char * remote_public_key, const size_t remote_public_key_length, + const unsigned char * local_private_key, const size_t local_private_key_length, + unsigned char * out_secret, size_t & out_secret_length); } // namespace Crypto } // namespace chip diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index a8b627428d10e7..fddd7df749214e 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -331,7 +331,7 @@ CHIP_ERROR chip::Crypto::ECDSA_sign_msg(const unsigned char * msg, const size_t size_t & out_signature_length) { ERR_clear_error(); - static_assert(kMax_ECDSA_Signature_Length >= 72, "ECDSA signature buffer length is too short"); + static_assert(kMax_ECDSA_Signature_Length >= 33, "ECDSA signature buffer length is too short"); CHIP_ERROR error = CHIP_NO_ERROR; int result = 0; @@ -420,6 +420,11 @@ CHIP_ERROR chip::Crypto::ECDSA_sign_msg(const unsigned char * msg, const size_t free(_hexKey); } + if (pvt_key != NULL) + { + BN_free(pvt_key); + } + return error; } @@ -518,3 +523,148 @@ CHIP_ERROR chip::Crypto::ECDSA_validate_msg_signature(const unsigned char * msg, } return error; } + +// helper function to populate octet key into EVP_PKEY out_evp_pkey. Caller must free out_evp_pkey +static CHIP_ERROR _create_evp_key_from_binary_key(const unsigned char * key, const size_t key_length, EVP_PKEY ** out_evp_pkey, + EC_GROUP * group, bool isPrivateKey) +{ + + CHIP_ERROR error = CHIP_NO_ERROR; + BIGNUM * big_num_key = NULL; + EC_KEY * ec_key = NULL; + int result = -1; + EC_POINT * point = NULL; + + VerifyOrExit(key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(*out_evp_pkey == NULL, error = CHIP_ERROR_INVALID_ARGUMENT); + + ec_key = EC_KEY_new_by_curve_name(_nidForCurve(ECName::P256v1)); + VerifyOrExit(ec_key != NULL, error = CHIP_ERROR_INTERNAL); + + big_num_key = BN_bin2bn(key, key_length, NULL); + VerifyOrExit(big_num_key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); + + if (isPrivateKey) + { + result = EC_KEY_set_private_key(ec_key, big_num_key); + } + else + { + point = EC_POINT_bn2point(group, big_num_key, point, NULL); + VerifyOrExit(point != NULL, error = CHIP_ERROR_INTERNAL); + result = EC_KEY_set_public_key(ec_key, point); + } + + VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL); + + *out_evp_pkey = EVP_PKEY_new(); + VerifyOrExit(*out_evp_pkey != NULL, error = CHIP_ERROR_INTERNAL); + + result = EVP_PKEY_set1_EC_KEY(*out_evp_pkey, ec_key); + VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL); + +exit: + if (big_num_key) + { + BN_free(big_num_key); + big_num_key = NULL; + } + + if (ec_key != NULL) + { + EC_KEY_free(ec_key); + ec_key = NULL; + } + + if (error != CHIP_NO_ERROR && *out_evp_pkey) + { + EVP_PKEY_free(*out_evp_pkey); + out_evp_pkey = NULL; + } + + if (point != NULL) + { + EC_POINT_free(point); + point = NULL; + } + + return error; +} + +CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_key, const size_t remote_public_key_length, + const unsigned char * local_private_key, const size_t local_private_key_length, + unsigned char * out_secret, size_t & out_secret_length) +{ + static_assert(kMax_ECDH_Secret_Length >= 64, "ECDH shared secret is too short"); + ERR_clear_error(); + CHIP_ERROR error = CHIP_NO_ERROR; + int result = -1; + EVP_PKEY * local_key = NULL; + EVP_PKEY * remote_key = NULL; + + EVP_PKEY_CTX * context = NULL; + EC_GROUP * group = NULL; + size_t out_buf_length = 0; + + static_assert(kMax_ECDH_Secret_Length >= 32); + VerifyOrExit(remote_public_key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(remote_public_key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(local_private_key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(local_private_key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(out_secret != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(out_secret_length >= kMax_ECDH_Secret_Length, error = CHIP_ERROR_INVALID_ARGUMENT); + + group = EC_GROUP_new_by_curve_name(_nidForCurve(ECName::P256v1)); + VerifyOrExit(group != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); + + error = _create_evp_key_from_binary_key(local_private_key, local_private_key_length, &local_key, group, true); + VerifyOrExit(error == CHIP_NO_ERROR, + error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key + + error = _create_evp_key_from_binary_key(remote_public_key, remote_public_key_length, &remote_key, group, false); + VerifyOrExit(error == CHIP_NO_ERROR, + error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key + + context = EVP_PKEY_CTX_new(local_key, NULL); + VerifyOrExit(context != NULL, error = CHIP_ERROR_INTERNAL); + + result = EVP_PKEY_derive_init(context); + VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL); + + result = EVP_PKEY_derive_set_peer(context, remote_key); + VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL); + + out_buf_length = out_secret_length; + result = EVP_PKEY_derive(context, out_secret, &out_buf_length); + VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL); + VerifyOrExit(out_secret_length >= out_buf_length, error = CHIP_ERROR_INTERNAL); + out_secret_length = out_buf_length; + +exit: + if (local_key != NULL) + { + EVP_PKEY_free(local_key); + local_key = NULL; + } + + if (remote_key != NULL) + { + EVP_PKEY_free(remote_key); + remote_key = NULL; + } + + if (context != NULL) + { + EVP_PKEY_CTX_free(context); + context = NULL; + } + + if (group != NULL) + { + EC_GROUP_free(group); + group = NULL; + } + _logSSLError(); + return error; +} diff --git a/src/crypto/tests/CHIPCryptoPALTest.cpp b/src/crypto/tests/CHIPCryptoPALTest.cpp index 989ed17c9a2291..82a6e484409771 100644 --- a/src/crypto/tests/CHIPCryptoPALTest.cpp +++ b/src/crypto/tests/CHIPCryptoPALTest.cpp @@ -460,6 +460,86 @@ static void TestECDSA_ValidationInvalidParam(nlTestSuite * inSuite, void * inCon validation_error = CHIP_NO_ERROR; } +static void TestECDH(nlTestSuite * inSuite, void * inContext) +{ + unsigned char private_key1[] = { + 0xc6, 0x1a, 0x2f, 0x89, 0x36, 0x67, 0x2b, 0x26, 0x12, 0x47, 0x4f, 0x11, 0x0e, 0x34, 0x15, 0x81, + 0x81, 0x12, 0xfc, 0x36, 0xeb, 0x65, 0x61, 0x07, 0xaa, 0x63, 0xe8, 0xc5, 0x22, 0xac, 0x52, 0xa1 + }; + + const unsigned char public_key1[] = { 0x04, 0xe2, 0x07, 0x64, 0xff, 0x6f, 0x6a, 0x91, 0xd9, 0xc2, 0xc3, 0x0a, 0xc4, + 0x3c, 0x56, 0x4b, 0x42, 0x8a, 0xf3, 0xb4, 0x49, 0x29, 0x39, 0x95, 0xa2, 0xf7, + 0x02, 0x8c, 0xa5, 0xce, 0xf3, 0xc9, 0xca, 0x24, 0xc5, 0xd4, 0x5c, 0x60, 0x79, + 0x48, 0x30, 0x3c, 0x53, 0x86, 0xd9, 0x23, 0xe6, 0x61, 0x1f, 0x5a, 0x3d, 0xdf, + 0x9f, 0xdc, 0x35, 0xea, 0xd0, 0xde, 0x16, 0x7e, 0x64, 0xde, 0x7f, 0x3c, 0xa6 }; + + const unsigned char private_key2[] = { 0x00, 0xd1, 0x90, 0xd9, 0xb3, 0x95, 0x1c, 0x5f, 0xa4, 0xe7, 0x47, + 0x92, 0x5b, 0x0a, 0xa9, 0xa7, 0xc1, 0x1c, 0xe7, 0x06, 0x10, 0xe2, + 0xdd, 0x16, 0x41, 0x52, 0x55, 0xb7, 0xb8, 0x80, 0x8d, 0x87, 0xa1 }; + + const unsigned char public_key2[] = { 0x04, 0x30, 0x77, 0x2c, 0xe7, 0xd4, 0x0a, 0xf2, 0xf3, 0x19, 0xbd, 0xfb, 0x1f, + 0xcc, 0x88, 0xd9, 0x83, 0x25, 0x89, 0xf2, 0x09, 0xf3, 0xab, 0xe4, 0x33, 0xb6, + 0x7a, 0xff, 0x73, 0x3b, 0x01, 0x35, 0x34, 0x92, 0x73, 0x14, 0x59, 0x0b, 0xbd, + 0x44, 0x72, 0x1b, 0xcd, 0xb9, 0x02, 0x53, 0xd9, 0xaf, 0xcc, 0x1a, 0xcd, 0xae, + 0xe8, 0x87, 0x2e, 0x52, 0x3b, 0x98, 0xf0, 0xa1, 0x88, 0x4a, 0xe3, 0x03, 0x75 }; + + unsigned char out_secret1[kMax_ECDH_Secret_Length] = { 0 }; + size_t out_size1 = sizeof(out_secret1); + + unsigned char out_secret2[kMax_ECDH_Secret_Length] = { 1 }; + size_t out_size2 = sizeof(out_secret2); + CHIP_ERROR error = CHIP_NO_ERROR; + NL_TEST_ASSERT(inSuite, memcmp(out_secret1, out_secret2, out_size1) != 0); // Validate that buffers are indeed different. + + error = ECDH_derive_secret(public_key1, sizeof(public_key1), private_key2, sizeof(private_key2), out_secret1, out_size1); + NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR); + + error = ECDH_derive_secret(public_key2, sizeof(public_key2), private_key1, sizeof(private_key1), out_secret2, out_size2); + NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR); + + bool signature_lengths_match = out_size1 == out_size2; + NL_TEST_ASSERT(inSuite, signature_lengths_match); + + bool signatures_match = (memcmp(out_secret1, out_secret2, out_size1) == 0); + NL_TEST_ASSERT(inSuite, signatures_match); +} + +static void TestECDH_InvalidParams(nlTestSuite * inSuite, void * inContext) +{ + unsigned char private_key1[] = { + 0xc6, 0x1a, 0x2f, 0x89, 0x36, 0x67, 0x2b, 0x26, 0x12, 0x47, 0x4f, 0x11, 0x0e, 0x34, 0x15, 0x81, + 0x81, 0x12, 0xfc, 0x36, 0xeb, 0x65, 0x61, 0x07, 0xaa, 0x63, 0xe8, 0xc5, 0x22, 0xac, 0x52, 0xa1 + }; + + const unsigned char public_key2[] = { 0x04, 0x30, 0x77, 0x2c, 0xe7, 0xd4, 0x0a, 0xf2, 0xf3, 0x19, 0xbd, 0xfb, 0x1f, + 0xcc, 0x88, 0xd9, 0x83, 0x25, 0x89, 0xf2, 0x09, 0xf3, 0xab, 0xe4, 0x33, 0xb6, + 0x7a, 0xff, 0x73, 0x3b, 0x01, 0x35, 0x34, 0x92, 0x73, 0x14, 0x59, 0x0b, 0xbd, + 0x44, 0x72, 0x1b, 0xcd, 0xb9, 0x02, 0x53, 0xd9, 0xaf, 0xcc, 0x1a, 0xcd, 0xae, + 0xe8, 0x87, 0x2e, 0x52, 0x3b, 0x98, 0xf0, 0xa1, 0x88, 0x4a, 0xe3, 0x03, 0x75 }; + + unsigned char out_secret[kMax_ECDH_Secret_Length] = { 0 }; + size_t out_size = sizeof(out_secret); + + CHIP_ERROR error = ECDH_derive_secret(NULL, sizeof(public_key2), private_key1, sizeof(private_key1), out_secret, out_size); + NL_TEST_ASSERT(inSuite, error == CHIP_ERROR_INVALID_ARGUMENT); + + error = ECDH_derive_secret(public_key2, 0, private_key1, sizeof(private_key1), out_secret, out_size); + NL_TEST_ASSERT(inSuite, error == CHIP_ERROR_INVALID_ARGUMENT); + + error = ECDH_derive_secret(public_key2, sizeof(public_key2), NULL, sizeof(private_key1), out_secret, out_size); + NL_TEST_ASSERT(inSuite, error == CHIP_ERROR_INVALID_ARGUMENT); + + error = ECDH_derive_secret(public_key2, sizeof(public_key2), private_key1, 0, out_secret, out_size); + NL_TEST_ASSERT(inSuite, error == CHIP_ERROR_INVALID_ARGUMENT); + + error = ECDH_derive_secret(public_key2, sizeof(public_key2), private_key1, sizeof(private_key1), NULL, out_size); + NL_TEST_ASSERT(inSuite, error == CHIP_ERROR_INVALID_ARGUMENT); + + size_t bad_size = 0; + error = ECDH_derive_secret(public_key2, sizeof(public_key2), private_key1, sizeof(private_key1), out_secret, bad_size); + NL_TEST_ASSERT(inSuite, error == CHIP_ERROR_INVALID_ARGUMENT); +} + namespace chip { namespace Logging { void Log(uint8_t module, uint8_t category, const char * format, ...) @@ -488,12 +568,12 @@ static const nlTest sTests[] = { NL_TEST_DEF("Test decrypting invalid key", TestAES_CCM_256DecryptInvalidKey), NL_TEST_DEF("Test decrypting invalid IV", TestAES_CCM_256DecryptInvalidIVLen), NL_TEST_DEF("Test decrypting invalid vectors", TestAES_CCM_256DecryptInvalidTestVectors), + NL_TEST_DEF("Test ECDH derive shared secret", TestECDH), + NL_TEST_DEF("Test ECDH invalid params", TestECDH_InvalidParams), #endif NL_TEST_DEF("Test ECDSA signing and validation using SHA256", TestECDSA_Signing_SHA256), NL_TEST_DEF("Test ECDSA signature validation fail - Different msg", TestECDSA_ValidationFailsDifferentMessage), NL_TEST_DEF("Test ECDSA signature validation fail - Different signature", TestECDSA_ValidationFailIncorrectSignature), - NL_TEST_DEF("Test ECDSA sign msg invalid parameters", TestECDSA_SigningInvalidParams), - NL_TEST_DEF("Test ECDSA signature validation invalid parameters", TestECDSA_ValidationInvalidParam), NL_TEST_DEF("Test HKDF SHA 256", TestHKDF_SHA256), NL_TEST_DEF("Test DRBG invalid inputs", TestDRBG_InvalidInputs), NL_TEST_DEF("Test DRBG output", TestDRBG_Output), From 5f70d5a1e33a28882fec2b01660dca56592f5b24 Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Fri, 24 Apr 2020 08:44:49 -0700 Subject: [PATCH 2/9] Fix typo --- src/crypto/CHIPCryptoPALOpenSSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index fddd7df749214e..d7dfb37fe2d1a8 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -331,7 +331,7 @@ CHIP_ERROR chip::Crypto::ECDSA_sign_msg(const unsigned char * msg, const size_t size_t & out_signature_length) { ERR_clear_error(); - static_assert(kMax_ECDSA_Signature_Length >= 33, "ECDSA signature buffer length is too short"); + static_assert(kMax_ECDSA_Signature_Length >= 72, "ECDSA signature buffer length is too short"); CHIP_ERROR error = CHIP_NO_ERROR; int result = 0; From 7967ac5d148eb00032d265eb216a165cc81df04a Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Fri, 24 Apr 2020 08:52:20 -0700 Subject: [PATCH 3/9] Consolidate static_asserts into one place --- src/crypto/CHIPCryptoPALOpenSSL.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index d7dfb37fe2d1a8..fea274923fd560 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -35,6 +35,8 @@ #define kKeyLengthInBits 256 + + enum class DigestType { SHA256 @@ -47,6 +49,9 @@ enum class ECName using namespace chip::Crypto; +static_assert(kMax_ECDH_Secret_Length >= 64, "ECDH shared secret is too short"); +static_assert(kMax_ECDSA_Signature_Length >= 72, "ECDSA signature buffer length is too short"); + static int _nidForCurve(ECName name) { switch (name) @@ -331,7 +336,7 @@ CHIP_ERROR chip::Crypto::ECDSA_sign_msg(const unsigned char * msg, const size_t size_t & out_signature_length) { ERR_clear_error(); - static_assert(kMax_ECDSA_Signature_Length >= 72, "ECDSA signature buffer length is too short"); + CHIP_ERROR error = CHIP_NO_ERROR; int result = 0; @@ -596,7 +601,6 @@ CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_ const unsigned char * local_private_key, const size_t local_private_key_length, unsigned char * out_secret, size_t & out_secret_length) { - static_assert(kMax_ECDH_Secret_Length >= 64, "ECDH shared secret is too short"); ERR_clear_error(); CHIP_ERROR error = CHIP_NO_ERROR; int result = -1; @@ -607,7 +611,6 @@ CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_ EC_GROUP * group = NULL; size_t out_buf_length = 0; - static_assert(kMax_ECDH_Secret_Length >= 32); VerifyOrExit(remote_public_key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(remote_public_key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(local_private_key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); From d39f5fcfc84296e05f0f65e699a08adee1a92c5d Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Fri, 24 Apr 2020 08:55:55 -0700 Subject: [PATCH 4/9] Rename helper method --- src/crypto/CHIPCryptoPALOpenSSL.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index fea274923fd560..d691e1d378d585 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -530,7 +530,7 @@ CHIP_ERROR chip::Crypto::ECDSA_validate_msg_signature(const unsigned char * msg, } // helper function to populate octet key into EVP_PKEY out_evp_pkey. Caller must free out_evp_pkey -static CHIP_ERROR _create_evp_key_from_binary_key(const unsigned char * key, const size_t key_length, EVP_PKEY ** out_evp_pkey, +static CHIP_ERROR _create_evp_key_from_binary_p256_key(const unsigned char * key, const size_t key_length, EVP_PKEY ** out_evp_pkey, EC_GROUP * group, bool isPrivateKey) { @@ -621,11 +621,11 @@ CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_ group = EC_GROUP_new_by_curve_name(_nidForCurve(ECName::P256v1)); VerifyOrExit(group != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); - error = _create_evp_key_from_binary_key(local_private_key, local_private_key_length, &local_key, group, true); + error = _create_evp_key_from_binary_p256_key(local_private_key, local_private_key_length, &local_key, group, true); VerifyOrExit(error == CHIP_NO_ERROR, error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key - error = _create_evp_key_from_binary_key(remote_public_key, remote_public_key_length, &remote_key, group, false); + error = _create_evp_key_from_binary_p256_key(remote_public_key, remote_public_key_length, &remote_key, group, false); VerifyOrExit(error == CHIP_NO_ERROR, error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key From 125133de778f994cf2fb9d016ebcc2a40a311591 Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Fri, 24 Apr 2020 16:41:42 -0700 Subject: [PATCH 5/9] Clean up helper method. Improve documentation --- src/crypto/CHIPCryptoPAL.h | 6 ++++-- src/crypto/CHIPCryptoPALOpenSSL.cpp | 31 +++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/crypto/CHIPCryptoPAL.h b/src/crypto/CHIPCryptoPAL.h index fdb0f1c28bf262..baeca596e093b1 100644 --- a/src/crypto/CHIPCryptoPAL.h +++ b/src/crypto/CHIPCryptoPAL.h @@ -165,9 +165,11 @@ CHIP_ERROR ECDSA_validate_msg_signature(const unsigned char * msg, const size_t const size_t signature_length); /** @brief A function to derive a shared secret using ECDH - * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel + * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is ASN.1 DER encoded as padded big-endian field elements as + *described in SEC 1: Elliptic Curve Cryptography [https://www.secg.org/sec1-v2.pdf] * @param remote_public_key_length Length of remote_public_key - * @param local_private_key Local private key + * @param local_private_key Local private key. local_private_key is ASN.1 DER encoded as padded big-endian field elements as + *described in SEC 1: Elliptic Curve Cryptography [https://www.secg.org/sec1-v2.pdf] * @param local_private_key_length Length of private_key_length * @param out_secret Buffer to write out secret into * @param out_secret_length Length of out_secret diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index d691e1d378d585..65f725ae2d2ddd 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -35,8 +35,6 @@ #define kKeyLengthInBits 256 - - enum class DigestType { SHA256 @@ -336,7 +334,6 @@ CHIP_ERROR chip::Crypto::ECDSA_sign_msg(const unsigned char * msg, const size_t size_t & out_signature_length) { ERR_clear_error(); - CHIP_ERROR error = CHIP_NO_ERROR; int result = 0; @@ -531,7 +528,7 @@ CHIP_ERROR chip::Crypto::ECDSA_validate_msg_signature(const unsigned char * msg, // helper function to populate octet key into EVP_PKEY out_evp_pkey. Caller must free out_evp_pkey static CHIP_ERROR _create_evp_key_from_binary_p256_key(const unsigned char * key, const size_t key_length, EVP_PKEY ** out_evp_pkey, - EC_GROUP * group, bool isPrivateKey) + bool isPrivateKey) { CHIP_ERROR error = CHIP_NO_ERROR; @@ -539,12 +536,17 @@ static CHIP_ERROR _create_evp_key_from_binary_p256_key(const unsigned char * key EC_KEY * ec_key = NULL; int result = -1; EC_POINT * point = NULL; + EC_GROUP * group = NULL; + int nid = NID_undef; VerifyOrExit(key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(*out_evp_pkey == NULL, error = CHIP_ERROR_INVALID_ARGUMENT); - ec_key = EC_KEY_new_by_curve_name(_nidForCurve(ECName::P256v1)); + nid = _nidForCurve(ECName::P256v1); + VerifyOrExit(nid != NID_undef, error = CHIP_ERROR_INTERNAL); + + ec_key = EC_KEY_new_by_curve_name(nid); VerifyOrExit(ec_key != NULL, error = CHIP_ERROR_INTERNAL); big_num_key = BN_bin2bn(key, key_length, NULL); @@ -556,8 +558,15 @@ static CHIP_ERROR _create_evp_key_from_binary_p256_key(const unsigned char * key } else { - point = EC_POINT_bn2point(group, big_num_key, point, NULL); + group = EC_GROUP_new_by_curve_name(nid); + VerifyOrExit(group != NULL, error = CHIP_ERROR_INTERNAL); + + point = EC_POINT_new(group); VerifyOrExit(point != NULL, error = CHIP_ERROR_INTERNAL); + + result = EC_POINT_oct2point(group, point, key, key_length, NULL); + VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL); + result = EC_KEY_set_public_key(ec_key, point); } @@ -594,6 +603,12 @@ static CHIP_ERROR _create_evp_key_from_binary_p256_key(const unsigned char * key point = NULL; } + if (group != NULL) + { + EC_GROUP_free(group); + group = NULL; + } + return error; } @@ -621,11 +636,11 @@ CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_ group = EC_GROUP_new_by_curve_name(_nidForCurve(ECName::P256v1)); VerifyOrExit(group != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); - error = _create_evp_key_from_binary_p256_key(local_private_key, local_private_key_length, &local_key, group, true); + error = _create_evp_key_from_binary_p256_key(local_private_key, local_private_key_length, &local_key, true); VerifyOrExit(error == CHIP_NO_ERROR, error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key - error = _create_evp_key_from_binary_p256_key(remote_public_key, remote_public_key_length, &remote_key, group, false); + error = _create_evp_key_from_binary_p256_key(remote_public_key, remote_public_key_length, &remote_key, false); VerifyOrExit(error == CHIP_NO_ERROR, error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key From 9b8df9dc94e1314d7978376325630aab6bc4a5b4 Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Fri, 24 Apr 2020 16:48:26 -0700 Subject: [PATCH 6/9] Add test accidentally deleted during rebase --- src/crypto/tests/CHIPCryptoPALTest.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/crypto/tests/CHIPCryptoPALTest.cpp b/src/crypto/tests/CHIPCryptoPALTest.cpp index 82a6e484409771..bff8455740b515 100644 --- a/src/crypto/tests/CHIPCryptoPALTest.cpp +++ b/src/crypto/tests/CHIPCryptoPALTest.cpp @@ -574,6 +574,8 @@ static const nlTest sTests[] = { NL_TEST_DEF("Test ECDSA signing and validation using SHA256", TestECDSA_Signing_SHA256), NL_TEST_DEF("Test ECDSA signature validation fail - Different msg", TestECDSA_ValidationFailsDifferentMessage), NL_TEST_DEF("Test ECDSA signature validation fail - Different signature", TestECDSA_ValidationFailIncorrectSignature), + NL_TEST_DEF("Test ECDSA sign msg invalid parameters", TestECDSA_SigningInvalidParams), + NL_TEST_DEF("Test ECDSA signature validation invalid parameters", TestECDSA_ValidationInvalidParam), NL_TEST_DEF("Test HKDF SHA 256", TestHKDF_SHA256), NL_TEST_DEF("Test DRBG invalid inputs", TestDRBG_InvalidInputs), NL_TEST_DEF("Test DRBG output", TestDRBG_Output), From 8b378e3af4fb6256dbecf2e38a5a6554cd507bed Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Fri, 24 Apr 2020 16:54:16 -0700 Subject: [PATCH 7/9] Fix formatting --- src/crypto/CHIPCryptoPAL.h | 5 +++-- src/crypto/CHIPCryptoPALOpenSSL.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/crypto/CHIPCryptoPAL.h b/src/crypto/CHIPCryptoPAL.h index baeca596e093b1..90201bdc7d4e0e 100644 --- a/src/crypto/CHIPCryptoPAL.h +++ b/src/crypto/CHIPCryptoPAL.h @@ -165,8 +165,9 @@ CHIP_ERROR ECDSA_validate_msg_signature(const unsigned char * msg, const size_t const size_t signature_length); /** @brief A function to derive a shared secret using ECDH - * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is ASN.1 DER encoded as padded big-endian field elements as - *described in SEC 1: Elliptic Curve Cryptography [https://www.secg.org/sec1-v2.pdf] + * @param remote_public_key Public key of remote peer with which we are trying to establish secure channel. remote_public_key is + *ASN.1 DER encoded as padded big-endian field elements as described in SEC 1: Elliptic Curve Cryptography + *[https://www.secg.org/sec1-v2.pdf] * @param remote_public_key_length Length of remote_public_key * @param local_private_key Local private key. local_private_key is ASN.1 DER encoded as padded big-endian field elements as *described in SEC 1: Elliptic Curve Cryptography [https://www.secg.org/sec1-v2.pdf] diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index 65f725ae2d2ddd..f49b4b45daf2e4 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -537,7 +537,7 @@ static CHIP_ERROR _create_evp_key_from_binary_p256_key(const unsigned char * key int result = -1; EC_POINT * point = NULL; EC_GROUP * group = NULL; - int nid = NID_undef; + int nid = NID_undef; VerifyOrExit(key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(key_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT); @@ -560,13 +560,13 @@ static CHIP_ERROR _create_evp_key_from_binary_p256_key(const unsigned char * key { group = EC_GROUP_new_by_curve_name(nid); VerifyOrExit(group != NULL, error = CHIP_ERROR_INTERNAL); - + point = EC_POINT_new(group); VerifyOrExit(point != NULL, error = CHIP_ERROR_INTERNAL); - + result = EC_POINT_oct2point(group, point, key, key_length, NULL); VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL); - + result = EC_KEY_set_public_key(ec_key, point); } From 47b828aa31d681e817a0578e2459c359d3c92c9d Mon Sep 17 00:00:00 2001 From: Bhaskar Sarma Date: Mon, 27 Apr 2020 15:27:04 -0700 Subject: [PATCH 8/9] PR Feedack + add test vectors --- src/crypto/CHIPCryptoPAL.h | 2 +- src/crypto/CHIPCryptoPALOpenSSL.cpp | 15 +-- src/crypto/tests/CHIPCryptoPALTest.cpp | 27 +++++- src/crypto/tests/ECDH_P256_test_vectors.h | 111 ++++++++++++++++++++++ src/crypto/tests/Makefile.am | 1 + 5 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 src/crypto/tests/ECDH_P256_test_vectors.h diff --git a/src/crypto/CHIPCryptoPAL.h b/src/crypto/CHIPCryptoPAL.h index 90201bdc7d4e0e..eb2af18bf29167 100644 --- a/src/crypto/CHIPCryptoPAL.h +++ b/src/crypto/CHIPCryptoPAL.h @@ -172,7 +172,7 @@ CHIP_ERROR ECDSA_validate_msg_signature(const unsigned char * msg, const size_t * @param local_private_key Local private key. local_private_key is ASN.1 DER encoded as padded big-endian field elements as *described in SEC 1: Elliptic Curve Cryptography [https://www.secg.org/sec1-v2.pdf] * @param local_private_key_length Length of private_key_length - * @param out_secret Buffer to write out secret into + * @param out_secret Buffer to write out secret into. This is a byte array representing the x coordinate of the shared secret. * @param out_secret_length Length of out_secret * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index f49b4b45daf2e4..8b058ae7f5d6ad 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -623,7 +623,6 @@ CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_ EVP_PKEY * remote_key = NULL; EVP_PKEY_CTX * context = NULL; - EC_GROUP * group = NULL; size_t out_buf_length = 0; VerifyOrExit(remote_public_key != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); @@ -633,16 +632,11 @@ CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_ VerifyOrExit(out_secret != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); VerifyOrExit(out_secret_length >= kMax_ECDH_Secret_Length, error = CHIP_ERROR_INVALID_ARGUMENT); - group = EC_GROUP_new_by_curve_name(_nidForCurve(ECName::P256v1)); - VerifyOrExit(group != NULL, error = CHIP_ERROR_INVALID_ARGUMENT); - error = _create_evp_key_from_binary_p256_key(local_private_key, local_private_key_length, &local_key, true); - VerifyOrExit(error == CHIP_NO_ERROR, - error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key + SuccessOrExit(error); error = _create_evp_key_from_binary_p256_key(remote_public_key, remote_public_key_length, &remote_key, false); - VerifyOrExit(error == CHIP_NO_ERROR, - error = error); // error = error because we just want to pass back the error from _create_evp_key_from_binary_key + SuccessOrExit(error); context = EVP_PKEY_CTX_new(local_key, NULL); VerifyOrExit(context != NULL, error = CHIP_ERROR_INTERNAL); @@ -678,11 +672,6 @@ CHIP_ERROR chip::Crypto::ECDH_derive_secret(const unsigned char * remote_public_ context = NULL; } - if (group != NULL) - { - EC_GROUP_free(group); - group = NULL; - } _logSSLError(); return error; } diff --git a/src/crypto/tests/CHIPCryptoPALTest.cpp b/src/crypto/tests/CHIPCryptoPALTest.cpp index bff8455740b515..d243e7708b7275 100644 --- a/src/crypto/tests/CHIPCryptoPALTest.cpp +++ b/src/crypto/tests/CHIPCryptoPALTest.cpp @@ -17,6 +17,7 @@ #include "CHIPCryptoPAL.h" #include "AES_CCM_256_test_vectors.h" +#include "ECDH_P256_test_vectors.h" #include "HKDF_SHA256_test_vectors.h" #include @@ -460,7 +461,7 @@ static void TestECDSA_ValidationInvalidParam(nlTestSuite * inSuite, void * inCon validation_error = CHIP_NO_ERROR; } -static void TestECDH(nlTestSuite * inSuite, void * inContext) +static void TestECDH_EstablishSecret(nlTestSuite * inSuite, void * inContext) { unsigned char private_key1[] = { 0xc6, 0x1a, 0x2f, 0x89, 0x36, 0x67, 0x2b, 0x26, 0x12, 0x47, 0x4f, 0x11, 0x0e, 0x34, 0x15, 0x81, @@ -540,6 +541,27 @@ static void TestECDH_InvalidParams(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, error == CHIP_ERROR_INVALID_ARGUMENT); } +static void TestECDH_SampleInputVectors(nlTestSuite * inSuite, void * inContext) +{ + + size_t numOfTestsExecuted = 0; + for (numOfTestsExecuted = 0; numOfTestsExecuted < ArraySize(ecdh_test_vectors); numOfTestsExecuted++) + { + unsigned char out_secret[kMax_ECDH_Secret_Length] = {0}; + size_t out_secret_length = sizeof(out_secret); + ECDH_P256_test_vector v = ecdh_test_vectors[numOfTestsExecuted]; + CHIP_ERROR error = ECDH_derive_secret(v.remote_pub_key, v.remote_pub_key_length, + v.local_pvt_key, v.local_pvt_key_length, out_secret, out_secret_length); + NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR); + if (error == CHIP_NO_ERROR) + { + int result = memcmp(out_secret, v.shared_secret, out_secret_length) == 0; + NL_TEST_ASSERT(inSuite, result == true); + } + } + NL_TEST_ASSERT(inSuite, numOfTestsExecuted > 0); +} + namespace chip { namespace Logging { void Log(uint8_t module, uint8_t category, const char * format, ...) @@ -568,8 +590,9 @@ static const nlTest sTests[] = { NL_TEST_DEF("Test decrypting invalid key", TestAES_CCM_256DecryptInvalidKey), NL_TEST_DEF("Test decrypting invalid IV", TestAES_CCM_256DecryptInvalidIVLen), NL_TEST_DEF("Test decrypting invalid vectors", TestAES_CCM_256DecryptInvalidTestVectors), - NL_TEST_DEF("Test ECDH derive shared secret", TestECDH), + NL_TEST_DEF("Test ECDH derive shared secret", TestECDH_EstablishSecret), NL_TEST_DEF("Test ECDH invalid params", TestECDH_InvalidParams), + NL_TEST_DEF("Test ECDH sample vectors", TestECDH_SampleInputVectors), #endif NL_TEST_DEF("Test ECDSA signing and validation using SHA256", TestECDSA_Signing_SHA256), NL_TEST_DEF("Test ECDSA signature validation fail - Different msg", TestECDSA_ValidationFailsDifferentMessage), diff --git a/src/crypto/tests/ECDH_P256_test_vectors.h b/src/crypto/tests/ECDH_P256_test_vectors.h new file mode 100644 index 00000000000000..05d7d00569b811 --- /dev/null +++ b/src/crypto/tests/ECDH_P256_test_vectors.h @@ -0,0 +1,111 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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. + */ + +/** + * @file - This file contains ECDH P256 test vectors. + */ + +#ifndef _ECDH_P256_TEST_VECTORS_H_ +#define _ECDH_P256_TEST_VECTORS_H_ + +typedef struct ECDH_P256_test_vector +{ + const unsigned char * local_pvt_key; + const size_t local_pvt_key_length; + const unsigned char * remote_pub_key; + const size_t remote_pub_key_length; + const unsigned char * shared_secret; + const size_t shared_secret_length; + +} ECDH_P256_test_vector; + +const unsigned char local_private_key1[] = { 0x7d, 0x7d, 0xc5, 0xf7, 0x1e, 0xb2, 0x9d, 0xda, 0xf8, 0x0d, 0x62, + 0x14, 0x63, 0x2e, 0xea, 0xe0, 0x3d, 0x90, 0x58, 0xaf, 0x1f, 0xb6, + 0xd2, 0x2e, 0xd8, 0x0b, 0xad, 0xb6, 0x2b, 0xc1, 0xa5, 0x34 }; + +const unsigned char remote_public_key1[] = { 0x04, 0x70, 0x0c, 0x48, 0xf7, 0x7f, 0x56, 0x58, 0x4c, 0x5c, 0xc6, 0x32, 0xca, + 0x65, 0x64, 0x0d, 0xb9, 0x1b, 0x6b, 0xac, 0xce, 0x3a, 0x4d, 0xf6, 0xb4, 0x2c, + 0xe7, 0xcc, 0x83, 0x88, 0x33, 0xd2, 0x87, 0xdb, 0x71, 0xe5, 0x09, 0xe3, 0xfd, + 0x9b, 0x06, 0x0d, 0xdb, 0x20, 0xba, 0x5c, 0x51, 0xdc, 0xc5, 0x94, 0x8d, 0x46, + 0xfb, 0xf6, 0x40, 0xdf, 0xe0, 0x44, 0x17, 0x82, 0xca, 0xb8, 0x5f, 0xa4, 0xac }; + +const unsigned char shared_secret1[] = { 0x46, 0xfc, 0x62, 0x10, 0x64, 0x20, 0xff, 0x01, 0x2e, 0x54, 0xa4, + 0x34, 0xfb, 0xdd, 0x2d, 0x25, 0xcc, 0xc5, 0x85, 0x20, 0x60, 0x56, + 0x1e, 0x68, 0x04, 0x0d, 0xd7, 0x77, 0x89, 0x97, 0xbd, 0x7b }; + +ECDH_P256_test_vector ecdh_v1 = { .local_pvt_key = local_private_key1, + .local_pvt_key_length = sizeof(local_private_key1), + .remote_pub_key = remote_public_key1, + .remote_pub_key_length = sizeof(remote_public_key1), + .shared_secret = shared_secret1, + .shared_secret_length = sizeof(shared_secret1) }; + +const unsigned char local_private_key2[] = { 0x00, 0xf5, 0xf8, 0xe0, 0x17, 0x46, 0x10, 0xa6, 0x61, 0x27, 0x79, + 0x79, 0xb5, 0x8c, 0xe5, 0xc9, 0x0f, 0xee, 0x6c, 0x9b, 0x3b, 0xb3, + 0x46, 0xa9, 0x0a, 0x71, 0x96, 0x25, 0x5e, 0x40, 0xb1, 0x32, 0xef }; + +const unsigned char remote_public_key2[] = { 0x04, 0x33, 0xe8, 0x20, 0x92, 0xa0, 0xf1, 0xfb, 0x38, 0xf5, 0x64, 0x9d, 0x58, + 0x67, 0xfb, 0xa2, 0x8b, 0x50, 0x31, 0x72, 0xb7, 0x03, 0x55, 0x74, 0xbf, 0x8e, + 0x5b, 0x71, 0x00, 0xa3, 0x05, 0x27, 0x92, 0xf2, 0xcf, 0x6b, 0x60, 0x1e, 0x0a, + 0x05, 0x94, 0x5e, 0x33, 0x55, 0x50, 0xbf, 0x64, 0x8d, 0x78, 0x2f, 0x46, 0x18, + 0x6c, 0x77, 0x2c, 0x0f, 0x20, 0xd3, 0xcd, 0x0d, 0x6b, 0x8c, 0xa1, 0x4b, 0x2f }; + +const unsigned char shared_secret2[] = { 0x66, 0x4e, 0x45, 0xd5, 0xbb, 0xa4, 0xac, 0x93, 0x1c, 0xd6, 0x5d, + 0x52, 0x01, 0x7e, 0x4b, 0xe9, 0xb1, 0x9a, 0x51, 0x5f, 0x66, 0x9b, + 0xea, 0x47, 0x03, 0x54, 0x2a, 0x2c, 0x52, 0x5c, 0xd3, 0xd3 }; + +ECDH_P256_test_vector ecdh_v2 = { .local_pvt_key = local_private_key2, + .local_pvt_key_length = sizeof(local_private_key2), + .remote_pub_key = remote_public_key2, + .remote_pub_key_length = sizeof(remote_public_key2), + .shared_secret = shared_secret2, + .shared_secret_length = sizeof(shared_secret2) }; + +const unsigned char local_private_key3[] = +{ +0x7A, 0xE6, 0x7A, 0xFC, 0xF2, 0x50, 0x5C, 0x12, 0xB7, 0x60, 0x0F, 0xA2, 0x25, 0x85, 0x9A, 0xFE, +0x36, 0xFA, 0x01, 0xE7, 0xB0, 0x78, 0x9C, 0xF5, 0x9B, 0x06, 0xA1, 0xC9, 0xB8, 0xEF, 0x90, 0xD2 +}; + +const unsigned char remote_public_key3[] = +{ +0x04, 0x19, 0x6C, 0x32, 0xA9, 0x90, 0x1B, 0xDC, 0x81, 0x70, 0x28, 0x0C, 0x78, 0x94, 0x71, 0x32, +0xB9, 0x2C, 0x9A, 0x7B, 0x8D, 0x4F, 0x59, 0x7A, 0x18, 0x33, 0x71, 0x25, 0x45, 0x8C, 0xCF, 0x92, +0x56, 0x1B, 0xA3, 0x80, 0x9E, 0xC1, 0xB9, 0x66, 0x8A, 0x29, 0x03, 0x68, 0x66, 0xE6, 0xD8, 0x45, +0x89, 0x11, 0x01, 0x3E, 0x2E, 0x78, 0xF9, 0x29, 0x6E, 0x86, 0xD6, 0x81, 0x7F, 0x7A, 0xE6, 0xF3, +0x09 +}; + +const unsigned char shared_secret3[] = +{ +0x00, 0x13, 0xB5, 0x76, 0xC6, 0xC0, 0x27, 0x02, 0xB1, 0xB6, 0x6C, 0x67, 0xFA, 0xB4, 0x6D, 0xA8, +0x54, 0x88, 0x0A, 0x39, 0xD7, 0x5F, 0xA7, 0x44, 0x64, 0x1F, 0xFA, 0x61, 0x11, 0x82, 0x3A, 0x4E +}; + +ECDH_P256_test_vector ecdh_v3 = { .local_pvt_key = local_private_key3, + .local_pvt_key_length = sizeof(local_private_key3), + .remote_pub_key = remote_public_key3, + .remote_pub_key_length = sizeof(remote_public_key2), + .shared_secret = shared_secret3, + .shared_secret_length = sizeof(shared_secret3) }; + +ECDH_P256_test_vector ecdh_test_vectors[] = { + ecdh_v1, + ecdh_v2, + ecdh_v3 +}; +#endif diff --git a/src/crypto/tests/Makefile.am b/src/crypto/tests/Makefile.am index d99a9ad7d76102..4fa42edf0df067 100644 --- a/src/crypto/tests/Makefile.am +++ b/src/crypto/tests/Makefile.am @@ -29,6 +29,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am noinst_HEADERS = \ AES_CCM_256_test_vectors.h \ HKDF_SHA256_test_vectors.h \ + ECDH_P256_test_vectors.h \ $(NULL) # From 7c58e010fe49d91b17e37d704e075813429f9ebb Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 27 Apr 2020 23:40:14 +0000 Subject: [PATCH 9/9] Restyled by clang-format --- src/crypto/tests/CHIPCryptoPALTest.cpp | 14 ++-- src/crypto/tests/ECDH_P256_test_vectors.h | 79 ++++++++++------------- 2 files changed, 41 insertions(+), 52 deletions(-) diff --git a/src/crypto/tests/CHIPCryptoPALTest.cpp b/src/crypto/tests/CHIPCryptoPALTest.cpp index d243e7708b7275..1ec86a29654dfd 100644 --- a/src/crypto/tests/CHIPCryptoPALTest.cpp +++ b/src/crypto/tests/CHIPCryptoPALTest.cpp @@ -543,19 +543,19 @@ static void TestECDH_InvalidParams(nlTestSuite * inSuite, void * inContext) static void TestECDH_SampleInputVectors(nlTestSuite * inSuite, void * inContext) { - + size_t numOfTestsExecuted = 0; for (numOfTestsExecuted = 0; numOfTestsExecuted < ArraySize(ecdh_test_vectors); numOfTestsExecuted++) { - unsigned char out_secret[kMax_ECDH_Secret_Length] = {0}; - size_t out_secret_length = sizeof(out_secret); - ECDH_P256_test_vector v = ecdh_test_vectors[numOfTestsExecuted]; - CHIP_ERROR error = ECDH_derive_secret(v.remote_pub_key, v.remote_pub_key_length, - v.local_pvt_key, v.local_pvt_key_length, out_secret, out_secret_length); + unsigned char out_secret[kMax_ECDH_Secret_Length] = { 0 }; + size_t out_secret_length = sizeof(out_secret); + ECDH_P256_test_vector v = ecdh_test_vectors[numOfTestsExecuted]; + CHIP_ERROR error = ECDH_derive_secret(v.remote_pub_key, v.remote_pub_key_length, v.local_pvt_key, v.local_pvt_key_length, + out_secret, out_secret_length); NL_TEST_ASSERT(inSuite, error == CHIP_NO_ERROR); if (error == CHIP_NO_ERROR) { - int result = memcmp(out_secret, v.shared_secret, out_secret_length) == 0; + int result = memcmp(out_secret, v.shared_secret, out_secret_length) == 0; NL_TEST_ASSERT(inSuite, result == true); } } diff --git a/src/crypto/tests/ECDH_P256_test_vectors.h b/src/crypto/tests/ECDH_P256_test_vectors.h index 05d7d00569b811..10704cfca32804 100644 --- a/src/crypto/tests/ECDH_P256_test_vectors.h +++ b/src/crypto/tests/ECDH_P256_test_vectors.h @@ -47,12 +47,12 @@ const unsigned char shared_secret1[] = { 0x46, 0xfc, 0x62, 0x10, 0x64, 0x20, 0xf 0x34, 0xfb, 0xdd, 0x2d, 0x25, 0xcc, 0xc5, 0x85, 0x20, 0x60, 0x56, 0x1e, 0x68, 0x04, 0x0d, 0xd7, 0x77, 0x89, 0x97, 0xbd, 0x7b }; -ECDH_P256_test_vector ecdh_v1 = { .local_pvt_key = local_private_key1, - .local_pvt_key_length = sizeof(local_private_key1), - .remote_pub_key = remote_public_key1, +ECDH_P256_test_vector ecdh_v1 = { .local_pvt_key = local_private_key1, + .local_pvt_key_length = sizeof(local_private_key1), + .remote_pub_key = remote_public_key1, .remote_pub_key_length = sizeof(remote_public_key1), - .shared_secret = shared_secret1, - .shared_secret_length = sizeof(shared_secret1) }; + .shared_secret = shared_secret1, + .shared_secret_length = sizeof(shared_secret1) }; const unsigned char local_private_key2[] = { 0x00, 0xf5, 0xf8, 0xe0, 0x17, 0x46, 0x10, 0xa6, 0x61, 0x27, 0x79, 0x79, 0xb5, 0x8c, 0xe5, 0xc9, 0x0f, 0xee, 0x6c, 0x9b, 0x3b, 0xb3, @@ -68,44 +68,33 @@ const unsigned char shared_secret2[] = { 0x66, 0x4e, 0x45, 0xd5, 0xbb, 0xa4, 0xa 0x52, 0x01, 0x7e, 0x4b, 0xe9, 0xb1, 0x9a, 0x51, 0x5f, 0x66, 0x9b, 0xea, 0x47, 0x03, 0x54, 0x2a, 0x2c, 0x52, 0x5c, 0xd3, 0xd3 }; -ECDH_P256_test_vector ecdh_v2 = { .local_pvt_key = local_private_key2, - .local_pvt_key_length = sizeof(local_private_key2), - .remote_pub_key = remote_public_key2, - .remote_pub_key_length = sizeof(remote_public_key2), - .shared_secret = shared_secret2, - .shared_secret_length = sizeof(shared_secret2) }; - -const unsigned char local_private_key3[] = -{ -0x7A, 0xE6, 0x7A, 0xFC, 0xF2, 0x50, 0x5C, 0x12, 0xB7, 0x60, 0x0F, 0xA2, 0x25, 0x85, 0x9A, 0xFE, -0x36, 0xFA, 0x01, 0xE7, 0xB0, 0x78, 0x9C, 0xF5, 0x9B, 0x06, 0xA1, 0xC9, 0xB8, 0xEF, 0x90, 0xD2 -}; - -const unsigned char remote_public_key3[] = -{ -0x04, 0x19, 0x6C, 0x32, 0xA9, 0x90, 0x1B, 0xDC, 0x81, 0x70, 0x28, 0x0C, 0x78, 0x94, 0x71, 0x32, -0xB9, 0x2C, 0x9A, 0x7B, 0x8D, 0x4F, 0x59, 0x7A, 0x18, 0x33, 0x71, 0x25, 0x45, 0x8C, 0xCF, 0x92, -0x56, 0x1B, 0xA3, 0x80, 0x9E, 0xC1, 0xB9, 0x66, 0x8A, 0x29, 0x03, 0x68, 0x66, 0xE6, 0xD8, 0x45, -0x89, 0x11, 0x01, 0x3E, 0x2E, 0x78, 0xF9, 0x29, 0x6E, 0x86, 0xD6, 0x81, 0x7F, 0x7A, 0xE6, 0xF3, -0x09 -}; - -const unsigned char shared_secret3[] = -{ -0x00, 0x13, 0xB5, 0x76, 0xC6, 0xC0, 0x27, 0x02, 0xB1, 0xB6, 0x6C, 0x67, 0xFA, 0xB4, 0x6D, 0xA8, -0x54, 0x88, 0x0A, 0x39, 0xD7, 0x5F, 0xA7, 0x44, 0x64, 0x1F, 0xFA, 0x61, 0x11, 0x82, 0x3A, 0x4E -}; - -ECDH_P256_test_vector ecdh_v3 = { .local_pvt_key = local_private_key3, - .local_pvt_key_length = sizeof(local_private_key3), - .remote_pub_key = remote_public_key3, - .remote_pub_key_length = sizeof(remote_public_key2), - .shared_secret = shared_secret3, - .shared_secret_length = sizeof(shared_secret3) }; - -ECDH_P256_test_vector ecdh_test_vectors[] = { - ecdh_v1, - ecdh_v2, - ecdh_v3 -}; +ECDH_P256_test_vector ecdh_v2 = { .local_pvt_key = local_private_key2, + .local_pvt_key_length = sizeof(local_private_key2), + .remote_pub_key = remote_public_key2, + .remote_pub_key_length = sizeof(remote_public_key2), + .shared_secret = shared_secret2, + .shared_secret_length = sizeof(shared_secret2) }; + +const unsigned char local_private_key3[] = { 0x7A, 0xE6, 0x7A, 0xFC, 0xF2, 0x50, 0x5C, 0x12, 0xB7, 0x60, 0x0F, + 0xA2, 0x25, 0x85, 0x9A, 0xFE, 0x36, 0xFA, 0x01, 0xE7, 0xB0, 0x78, + 0x9C, 0xF5, 0x9B, 0x06, 0xA1, 0xC9, 0xB8, 0xEF, 0x90, 0xD2 }; + +const unsigned char remote_public_key3[] = { 0x04, 0x19, 0x6C, 0x32, 0xA9, 0x90, 0x1B, 0xDC, 0x81, 0x70, 0x28, 0x0C, 0x78, + 0x94, 0x71, 0x32, 0xB9, 0x2C, 0x9A, 0x7B, 0x8D, 0x4F, 0x59, 0x7A, 0x18, 0x33, + 0x71, 0x25, 0x45, 0x8C, 0xCF, 0x92, 0x56, 0x1B, 0xA3, 0x80, 0x9E, 0xC1, 0xB9, + 0x66, 0x8A, 0x29, 0x03, 0x68, 0x66, 0xE6, 0xD8, 0x45, 0x89, 0x11, 0x01, 0x3E, + 0x2E, 0x78, 0xF9, 0x29, 0x6E, 0x86, 0xD6, 0x81, 0x7F, 0x7A, 0xE6, 0xF3, 0x09 }; + +const unsigned char shared_secret3[] = { 0x00, 0x13, 0xB5, 0x76, 0xC6, 0xC0, 0x27, 0x02, 0xB1, 0xB6, 0x6C, + 0x67, 0xFA, 0xB4, 0x6D, 0xA8, 0x54, 0x88, 0x0A, 0x39, 0xD7, 0x5F, + 0xA7, 0x44, 0x64, 0x1F, 0xFA, 0x61, 0x11, 0x82, 0x3A, 0x4E }; + +ECDH_P256_test_vector ecdh_v3 = { .local_pvt_key = local_private_key3, + .local_pvt_key_length = sizeof(local_private_key3), + .remote_pub_key = remote_public_key3, + .remote_pub_key_length = sizeof(remote_public_key2), + .shared_secret = shared_secret3, + .shared_secret_length = sizeof(shared_secret3) }; + +ECDH_P256_test_vector ecdh_test_vectors[] = { ecdh_v1, ecdh_v2, ecdh_v3 }; #endif