From ed4cf6e91cf2110bb9090e25898a916641c916aa Mon Sep 17 00:00:00 2001 From: Elms Date: Wed, 9 Jun 2021 21:47:09 -0700 Subject: [PATCH] silabs: fix `wc_ecc_shared_secret` to only return x coordinate secure element computes and returns the full coordinate. The wolfSSL API should only return the x component. --- tests/api.c | 42 ++++++++++++++++++++++++++ wolfcrypt/src/port/silabs/silabs_ecc.c | 22 +++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/tests/api.c b/tests/api.c index ae9d6742c..f2af6295b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -21188,6 +21188,23 @@ static int test_wc_ecc_shared_secret (void) byte out[KEY16]; word32 outlen = (word32)sizeof(out); +#if defined(HAVE_ECC) && !defined(NO_ECC256) + const char* qx = + "bb33ac4c27504ac64aa504c33cde9f36db722dce94ea2bfacb2009392c16e861"; + const char* qy = + "02e9af4dd302939a315b9792217ff0cf18da9111023486e82058330b803489d8"; + const char* d = + "45b66902739c6c85a1385b72e8e8c7acc4038d533504fa6c28dc348de1a8098c"; + const char* curveName = "SECP256R1"; + const byte expected_shared_secret[] = + { + 0x65, 0xc0, 0xd4, 0x61, 0x17, 0xe6, 0x09, 0x75, + 0xf0, 0x12, 0xa0, 0x4d, 0x0b, 0x41, 0x30, 0x7a, + 0x51, 0xf0, 0xb3, 0xaf, 0x23, 0x8f, 0x0f, 0xdf, + 0xf1, 0xff, 0x23, 0x64, 0x28, 0xca, 0xf8, 0x06 + }; +#endif + /* Initialize variables. */ XMEMSET(out, 0, keySz); XMEMSET(&rng, 0, sizeof(rng)); @@ -21201,12 +21218,22 @@ static int test_wc_ecc_shared_secret (void) ret = wc_ecc_init(&pubKey); } } + +#if defined(HAVE_ECC) && !defined(NO_ECC256) + if (ret == 0) { + ret = wc_ecc_import_raw(&key, qx, qy, d, curveName); + } + if (ret == 0) { + ret = wc_ecc_import_raw(&pubKey, qx, qy, NULL, curveName); + } +#else if (ret == 0) { ret = wc_ecc_make_key(&rng, keySz, &key); } if (ret == 0) { ret = wc_ecc_make_key(&rng, keySz, &pubKey); } +#endif #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ @@ -21219,6 +21246,15 @@ static int test_wc_ecc_shared_secret (void) printf(testingFmt, "wc_ecc_shared_secret()"); if (ret == 0) { ret = wc_ecc_shared_secret(&key, &pubKey, out, &outlen); + +#if defined(HAVE_ECC) && !defined(NO_ECC256) + if (ret == 0) { + if (0 != XMEMCMP(out, expected_shared_secret, outlen)) { + ret = WOLFSSL_FATAL_ERROR; + } + } +#endif + /* Test bad args. */ if (ret == 0) { ret = wc_ecc_shared_secret(NULL, &pubKey, out, &outlen); @@ -21232,6 +21268,12 @@ static int test_wc_ecc_shared_secret (void) ret = wc_ecc_shared_secret(&key, &pubKey, out, NULL); } if (ret == BAD_FUNC_ARG) { + /* Invalid length */ + outlen = 1; + ret = wc_ecc_shared_secret(&key, &pubKey, out, &outlen); + } + + if (ret == BUFFER_E) { ret = 0; } else if (ret == 0) { ret = WOLFSSL_FATAL_ERROR; diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index 78825bb85..b41c9ec80 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -303,21 +303,30 @@ int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, sl_se_command_context_t cmd; sl_se_key_descriptor_t key_out; sl_se_key_descriptor_t pub_key; - uint32_t pub_sz = 0; sl_status_t sl_stat; + /* `sl_se_ecdh_compute_shared_secret` returns the full coordinate + * point, but `wc_ecc_shared_secret` should only return the x + * coordinate. This buffer is used to hold the output of the + * secure element output and only the first half is copied to the + * `out` buffer. + */ + byte fullpoint[2 * ECC_MAX_CRYPTO_HW_SIZE]; + pub_key = public_key->key; pub_key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY; - *outlen = pub_key.size * 2; - pub_sz = pub_key.size * 2; + if (*outlen < pub_key.size) { + return BUFFER_E; + } + pub_sz = pub_key.size * 2; XMEMSET(&key_out, 0, sizeof(key_out)); key_out.type = SL_SE_KEY_TYPE_SYMMETRIC; key_out.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; - key_out.storage.location.buffer.pointer = out; + key_out.storage.location.buffer.pointer = fullpoint; key_out.size = pub_sz; key_out.storage.location.buffer.size = pub_sz; @@ -327,6 +336,11 @@ int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, &pub_key, &key_out); + if (sl_stat == SL_STATUS_OK) { + *outlen = pub_key.size; + XMEMCPY(out, fullpoint, *outlen); + } + return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E; }