Merge pull request #4111 from elms/silabs/fix_ecc_shared_secret_outlen

silabs: fix `wc_ecc_shared_secret` to only return x coordinate
pull/4123/head
David Garske 2021-06-14 13:44:00 -07:00 committed by GitHub
commit fd6b30ef32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 4 deletions

View File

@ -21188,6 +21188,23 @@ static int test_wc_ecc_shared_secret (void)
byte out[KEY16]; byte out[KEY16];
word32 outlen = (word32)sizeof(out); 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. */ /* Initialize variables. */
XMEMSET(out, 0, keySz); XMEMSET(out, 0, keySz);
XMEMSET(&rng, 0, sizeof(rng)); XMEMSET(&rng, 0, sizeof(rng));
@ -21201,12 +21218,22 @@ static int test_wc_ecc_shared_secret (void)
ret = wc_ecc_init(&pubKey); 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) { if (ret == 0) {
ret = wc_ecc_make_key(&rng, keySz, &key); ret = wc_ecc_make_key(&rng, keySz, &key);
} }
if (ret == 0) { if (ret == 0) {
ret = wc_ecc_make_key(&rng, keySz, &pubKey); ret = wc_ecc_make_key(&rng, keySz, &pubKey);
} }
#endif
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ (!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()"); printf(testingFmt, "wc_ecc_shared_secret()");
if (ret == 0) { if (ret == 0) {
ret = wc_ecc_shared_secret(&key, &pubKey, out, &outlen); 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. */ /* Test bad args. */
if (ret == 0) { if (ret == 0) {
ret = wc_ecc_shared_secret(NULL, &pubKey, out, &outlen); 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); ret = wc_ecc_shared_secret(&key, &pubKey, out, NULL);
} }
if (ret == BAD_FUNC_ARG) { if (ret == BAD_FUNC_ARG) {
/* Invalid length */
outlen = 1;
ret = wc_ecc_shared_secret(&key, &pubKey, out, &outlen);
}
if (ret == BUFFER_E) {
ret = 0; ret = 0;
} else if (ret == 0) { } else if (ret == 0) {
ret = WOLFSSL_FATAL_ERROR; ret = WOLFSSL_FATAL_ERROR;

View File

@ -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_command_context_t cmd;
sl_se_key_descriptor_t key_out; sl_se_key_descriptor_t key_out;
sl_se_key_descriptor_t pub_key; sl_se_key_descriptor_t pub_key;
uint32_t pub_sz = 0; uint32_t pub_sz = 0;
sl_status_t sl_stat; 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 = public_key->key;
pub_key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY; pub_key.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY;
*outlen = pub_key.size * 2; if (*outlen < pub_key.size) {
pub_sz = pub_key.size * 2; return BUFFER_E;
}
pub_sz = pub_key.size * 2;
XMEMSET(&key_out, 0, sizeof(key_out)); XMEMSET(&key_out, 0, sizeof(key_out));
key_out.type = SL_SE_KEY_TYPE_SYMMETRIC; key_out.type = SL_SE_KEY_TYPE_SYMMETRIC;
key_out.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; 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.size = pub_sz;
key_out.storage.location.buffer.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, &pub_key,
&key_out); &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; return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E;
} }