diff --git a/examples/platforms/simulation/openthread-core-simulation-config.h b/examples/platforms/simulation/openthread-core-simulation-config.h index 879f069bf..f17af97a9 100644 --- a/examples/platforms/simulation/openthread-core-simulation-config.h +++ b/examples/platforms/simulation/openthread-core-simulation-config.h @@ -254,4 +254,15 @@ #define OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_MAX_SERVICES 20 #endif +/** + * @def OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE + * + * Define to 1 to generate ECDSA signatures determinsitically + * according to RFC 6979 instead of randomly. + * + */ +#ifndef OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE +#define OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE 1 +#endif + #endif // OPENTHREAD_CORE_SIMULATION_CONFIG_H_ diff --git a/src/core/config/misc.h b/src/core/config/misc.h index 3070bb07c..e29bcb50d 100644 --- a/src/core/config/misc.h +++ b/src/core/config/misc.h @@ -87,6 +87,17 @@ #define OPENTHREAD_CONFIG_ECDSA_ENABLE 0 #endif +/** + * @def OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE + * + * Define to 1 to generate ECDSA signatures determinsitically + * according to RFC 6979 instead of randomly. + * + */ +#ifndef OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE +#define OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE 1 +#endif + /** * @def OPENTHREAD_CONFIG_UPTIME_ENABLE * diff --git a/src/core/crypto/ecdsa.cpp b/src/core/crypto/ecdsa.cpp index b91e4e189..4500d828f 100644 --- a/src/core/crypto/ecdsa.cpp +++ b/src/core/crypto/ecdsa.cpp @@ -142,12 +142,17 @@ Error P256::KeyPair::Sign(const Sha256::Hash &aHash, Signature &aSignature) cons ret = mbedtls_ecdsa_from_keypair(&ecdsa, keypair); VerifyOrExit(ret == 0, error = MbedTls::MapError(ret)); +#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE #if (MBEDTLS_VERSION_NUMBER >= 0x02130000) ret = mbedtls_ecdsa_sign_det_ext(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), aHash.GetBytes(), Sha256::Hash::kSize, MBEDTLS_MD_SHA256, MbedTls::CryptoSecurePrng, nullptr); #else ret = mbedtls_ecdsa_sign_det(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), aHash.GetBytes(), Sha256::Hash::kSize, MBEDTLS_MD_SHA256); +#endif +#else + ret = mbedtls_ecdsa_sign(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), aHash.GetBytes(), + Sha256::Hash::kSize, MbedTls::CryptoSecurePrng, nullptr); #endif VerifyOrExit(ret == 0, error = MbedTls::MapError(ret)); @@ -244,9 +249,20 @@ Error Sign(uint8_t * aOutput, VerifyOrExit(mbedtls_ecdsa_from_keypair(&ctx, keypair) == 0, error = kErrorFailed); // Sign using ECDSA. +#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE +#if (MBEDTLS_VERSION_NUMBER >= 0x02130000) + VerifyOrExit(mbedtls_ecdsa_sign_det_ext(&ctx.MBEDTLS_PRIVATE(grp), &rMpi, &sMpi, &ctx.MBEDTLS_PRIVATE(d), + aInputHash, aInputHashLength, MBEDTLS_MD_SHA256, MbedTls::CryptoSecurePrng, + nullptr)); +#else + VerifyOrExit(mbedtls_ecdsa_sign_det(&ctx.MBEDTLS_PRIVATE(grp), &rMpi, &sMpi, &ctx.MBEDTLS_PRIVATE(d), aInputHash, + aInputHashLength, MBEDTLS_MD_SHA256)); +#endif +#else VerifyOrExit(mbedtls_ecdsa_sign(&ctx.MBEDTLS_PRIVATE(grp), &rMpi, &sMpi, &ctx.MBEDTLS_PRIVATE(d), aInputHash, aInputHashLength, MbedTls::CryptoSecurePrng, nullptr) == 0, error = kErrorFailed); +#endif VerifyOrExit(mbedtls_mpi_size(&rMpi) + mbedtls_mpi_size(&sMpi) <= aOutputLength, error = kErrorNoBufs); // Concatenate the two octet sequences in the order R and then S. diff --git a/src/core/crypto/ecdsa_tinycrypt.cpp b/src/core/crypto/ecdsa_tinycrypt.cpp index ea75a2d81..852cb40e7 100644 --- a/src/core/crypto/ecdsa_tinycrypt.cpp +++ b/src/core/crypto/ecdsa_tinycrypt.cpp @@ -37,6 +37,10 @@ #ifdef MBEDTLS_USE_TINYCRYPT +#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE +#warning "tinycrypt does not support generating deterministic ECDSA signatures" +#endif + #include #include diff --git a/tests/unit/test_ecdsa.cpp b/tests/unit/test_ecdsa.cpp index 533ebcce4..aad13a748 100644 --- a/tests/unit/test_ecdsa.cpp +++ b/tests/unit/test_ecdsa.cpp @@ -66,12 +66,14 @@ void TestEcdsaVector(void) const uint8_t kMessage[] = {'s', 'a', 'm', 'p', 'l', 'e'}; +#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE const uint8_t kExpectedSignature[] = { 0xEF, 0xD4, 0x8B, 0x2A, 0xAC, 0xB6, 0xA8, 0xFD, 0x11, 0x40, 0xDD, 0x9C, 0xD4, 0x5E, 0x81, 0xD6, 0x9D, 0x2C, 0x87, 0x7B, 0x56, 0xAA, 0xF9, 0x91, 0xC3, 0x4D, 0x0E, 0xA8, 0x4E, 0xAF, 0x37, 0x16, 0xF7, 0xCB, 0x1C, 0x94, 0x2D, 0x65, 0x7C, 0x41, 0xD4, 0x36, 0xC7, 0xA1, 0xB6, 0xE2, 0x9F, 0x65, 0xF3, 0xE9, 0x00, 0xDB, 0xB9, 0xAF, 0xF4, 0x06, 0x4D, 0xC4, 0xAB, 0x2F, 0x84, 0x3A, 0xCD, 0xA8, }; +#endif Instance *instance = testInitInstance(); @@ -110,6 +112,7 @@ void TestEcdsaVector(void) SuccessOrQuit(keyPair.Sign(hash, signature)); DumpBuffer("Signature", signature.GetBytes(), sizeof(signature)); +#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE printf("\nCheck signature against expected sequence----------------------------------\n"); DumpBuffer("Expected signature", kExpectedSignature, sizeof(kExpectedSignature)); @@ -117,6 +120,7 @@ void TestEcdsaVector(void) VerifyOrQuit(memcmp(signature.GetBytes(), kExpectedSignature, sizeof(kExpectedSignature)) == 0); printf("Signature matches expected sequence.\n"); +#endif printf("\nVerify the signature ------------------------------------------------------\n"); SuccessOrQuit(publicKey.Verify(hash, signature)); @@ -125,7 +129,7 @@ void TestEcdsaVector(void) testFreeInstance(instance); } -void TestEdsaKeyGenerationSignAndVerify(void) +void TestEcdsaKeyGenerationSignAndVerify(void) { Instance *instance = testInitInstance(); @@ -183,7 +187,7 @@ int main(void) { #if OPENTHREAD_CONFIG_ECDSA_ENABLE ot::Crypto::TestEcdsaVector(); - ot::Crypto::TestEdsaKeyGenerationSignAndVerify(); + ot::Crypto::TestEcdsaKeyGenerationSignAndVerify(); printf("All tests passed\n"); #else printf("ECDSA feature is not enabled\n"); diff --git a/third_party/mbedtls/mbedtls-config.h b/third_party/mbedtls/mbedtls-config.h index 997870c21..131aaafea 100644 --- a/third_party/mbedtls/mbedtls-config.h +++ b/third_party/mbedtls/mbedtls-config.h @@ -103,7 +103,9 @@ #define MBEDTLS_BASE64_C #define MBEDTLS_ECDH_C #define MBEDTLS_ECDSA_C +#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE #define MBEDTLS_ECDSA_DETERMINISTIC +#endif #define MBEDTLS_OID_C #define MBEDTLS_PEM_PARSE_C #define MBEDTLS_PK_WRITE_C