mirror of https://github.com/wolfSSL/wolfssl.git
Address review findings on curve448 cryptocb support
Assert cryptocb output in curve448_onlycb_test, reject an all-zero wc_curve448_generic result, guard the new API test for CB-only builds.pull/11209/head
parent
3d7f7ad4d6
commit
eb1cde51ab
|
|
@ -910,14 +910,16 @@ int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
|
|||
\brief This function performs a generic Curve448 scalar
|
||||
multiplication with a custom basepoint. This allows computing
|
||||
scalar * basepoint for any basepoint, not just the standard
|
||||
generator. This is a raw primitive: unlike
|
||||
wc_curve448_shared_secret_ex it does not reject an all-zero
|
||||
result. Callers doing key agreement with a peer-supplied point
|
||||
must reject an all-zero output themselves (RFC 7748 section 6.2).
|
||||
generator. As in wc_curve448_shared_secret_ex, an all-zero result
|
||||
is rejected (RFC 7748 section 6.2); build with
|
||||
WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK to get the raw scalar
|
||||
multiplication result instead.
|
||||
|
||||
\return 0 On successfully computing the result
|
||||
\return ECC_BAD_ARG_E If any input parameter is NULL or a size is
|
||||
invalid
|
||||
\return ECC_OUT_OF_RANGE_E If the result is all-zero, i.e. the
|
||||
basepoint was of small order
|
||||
|
||||
\param public_size Size of the output buffer (must be 56)
|
||||
\param pub Pointer to buffer to store the result
|
||||
|
|
|
|||
|
|
@ -832,11 +832,15 @@ int test_wc_curve448_export_import_endian(void)
|
|||
} /* END test_wc_curve448_export_import_endian */
|
||||
|
||||
/* Cross-check make_pub, generic and keygen: public keys must match and a
|
||||
* shared secret must round trip (runs via cryptocb under CB_ONLY_CURVE448). */
|
||||
* shared secret must round trip. */
|
||||
/* The keys are built with wc_curve448_init (INVALID_DEVID), so under CB-only
|
||||
* the software path is stripped and wc_curve448_make_key only dispatches when
|
||||
* WOLF_CRYPTO_CB_FIND can route to a registered device. */
|
||||
int test_wc_curve448_make_pub_generic(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_SHARED_SECRET)
|
||||
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_SHARED_SECRET) && \
|
||||
(!defined(WOLF_CRYPTO_CB_ONLY_CURVE448) || defined(WOLF_CRYPTO_CB_FIND))
|
||||
curve448_key keyA;
|
||||
curve448_key keyB;
|
||||
WC_RNG rng;
|
||||
|
|
@ -882,6 +886,17 @@ int test_wc_curve448_make_pub_generic(void)
|
|||
EC448_LITTLE_ENDIAN), 0);
|
||||
ExpectBufEQ(ssBA, ssAB, CURVE448_PUB_KEY_SIZE);
|
||||
|
||||
/* an all-zero result (small-order basepoint) must be rejected, matching
|
||||
* wc_curve448_shared_secret_ex */
|
||||
XMEMSET(pubG, 0, sizeof(pubG));
|
||||
{
|
||||
byte baseZero[CURVE448_KEY_SIZE];
|
||||
XMEMSET(baseZero, 0, sizeof(baseZero));
|
||||
ExpectIntEQ(wc_curve448_generic((int)sizeof(pubG), pubG,
|
||||
(int)sizeof(keyA.k), keyA.k, (int)sizeof(baseZero), baseZero),
|
||||
WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E));
|
||||
}
|
||||
|
||||
/* argument checks on the new generic API */
|
||||
ExpectIntEQ(wc_curve448_generic((int)sizeof(pubG), NULL,
|
||||
(int)sizeof(keyA.k), keyA.k, (int)sizeof(base5), base5),
|
||||
|
|
|
|||
|
|
@ -105,7 +105,26 @@ int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Multiply a scalar (private key) against any basepoint over curve448. */
|
||||
/* Is every byte of the curve448 result zero? Only reached when the caller's
|
||||
* basepoint is of small order, which leaks the result to anyone watching. */
|
||||
#ifndef WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
static WC_INLINE int curve448_result_is_zero(const byte* out)
|
||||
{
|
||||
int i;
|
||||
byte t = 0;
|
||||
for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) {
|
||||
t |= out[i];
|
||||
}
|
||||
return (t == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Multiply a scalar (private key) against any basepoint over curve448.
|
||||
*
|
||||
* An all-zero result is rejected with ECC_OUT_OF_RANGE_E, matching
|
||||
* wc_curve448_shared_secret_ex; define WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK to
|
||||
* get the raw scalar multiplication result instead.
|
||||
*/
|
||||
int wc_curve448_generic(int public_size, byte* pub,
|
||||
int private_size, const byte* priv,
|
||||
int basepoint_size, const byte* basepoint)
|
||||
|
|
@ -129,8 +148,15 @@ int wc_curve448_generic(int public_size, byte* pub,
|
|||
#ifdef WOLF_CRYPTO_CB
|
||||
ret = wc_CryptoCb_Curve448Generic(public_size, pub, private_size, priv,
|
||||
basepoint_size, basepoint);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
#ifndef WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
/* RFC 7748: reject an all-zero result from the callback too */
|
||||
if ((ret == 0) && curve448_result_is_zero(pub)) {
|
||||
ret = ECC_OUT_OF_RANGE_E;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
/* fall-through when unavailable */
|
||||
#endif
|
||||
|
||||
|
|
@ -140,6 +166,11 @@ int wc_curve448_generic(int public_size, byte* pub,
|
|||
fe448_init();
|
||||
|
||||
ret = curve448(pub, priv, basepoint);
|
||||
#ifndef WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
if ((ret == 0) && curve448_result_is_zero(pub)) {
|
||||
ret = ECC_OUT_OF_RANGE_E;
|
||||
}
|
||||
#endif
|
||||
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE448 */
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -80424,6 +80424,17 @@ exit_onlycb:
|
|||
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE448) && !defined(WOLFSSL_SWDEV)
|
||||
/* Is every byte of buf the marker value v? */
|
||||
static int curve448_buf_is(const byte* buf, byte v, word32 len)
|
||||
{
|
||||
word32 i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (buf[i] != v)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Exercise Curve448 dispatch under CB_ONLY_CURVE448: cb-handled then
|
||||
* cb-delegated. */
|
||||
static wc_test_ret_t curve448_onlycb_test(myCryptoDevCtx *ctx)
|
||||
|
|
@ -80451,11 +80462,14 @@ static wc_test_ret_t curve448_onlycb_test(myCryptoDevCtx *ctx)
|
|||
return WC_TEST_RET_ENC_EC(ret);
|
||||
}
|
||||
|
||||
/* cb handles the op, expects 0(success) */
|
||||
/* cb handles the op, expects 0(success) and the stub's key material */
|
||||
ctx->exampleVar = 99;
|
||||
ret = wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &key);
|
||||
if (ret != 0)
|
||||
ret = WC_TEST_RET_ENC_EC(ret);
|
||||
else if (!key.privSet || !key.pubSet || (key.p[0] != 0xC3) ||
|
||||
(key.k[CURVE448_KEY_SIZE-1] != 0xDA))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
|
||||
if (ret == 0) {
|
||||
/* cb delegates to software, expects NO_VALID_DEVID(failure) */
|
||||
|
|
@ -80477,18 +80491,24 @@ static wc_test_ret_t curve448_onlycb_test(myCryptoDevCtx *ctx)
|
|||
scalar[0] = 4;
|
||||
scalar[CURVE448_KEY_SIZE-1] = 0x80;
|
||||
|
||||
/* cb handles make_pub and generic, expects 0(success) */
|
||||
/* cb handles make_pub and generic, expects 0(success) and the
|
||||
* stub's per-type marker written over the caller's buffer */
|
||||
ctx->exampleVar = 99;
|
||||
XMEMSET(pubTmp, 0, sizeof(pubTmp));
|
||||
ret = wc_curve448_make_pub((int)sizeof(pubTmp), pubTmp,
|
||||
(int)sizeof(scalar), scalar);
|
||||
if (ret != 0)
|
||||
ret = WC_TEST_RET_ENC_EC(ret);
|
||||
else if (!curve448_buf_is(pubTmp, 0x6B, sizeof(pubTmp)))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
if (ret == 0) {
|
||||
ret = wc_curve448_generic((int)sizeof(pubTmp), pubTmp,
|
||||
(int)sizeof(scalar), scalar, (int)sizeof(basepoint),
|
||||
basepoint);
|
||||
if (ret != 0)
|
||||
ret = WC_TEST_RET_ENC_EC(ret);
|
||||
else if (!curve448_buf_is(pubTmp, 0x3C, sizeof(pubTmp)))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
|
||||
/* cb delegates to software, expects NO_VALID_DEVID(failure) */
|
||||
|
|
@ -81186,7 +81206,21 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
|||
printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar);
|
||||
#endif
|
||||
if (myCtx->exampleVar == 99) {
|
||||
/* the dispatcher must hand over a usable payload */
|
||||
if ((info->pk.curve448kg.rng == NULL) ||
|
||||
(info->pk.curve448kg.size != CURVE448_KEY_SIZE)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
info->pk.curve448kg.key->devId = devIdArg;
|
||||
/* deterministic key material so the caller can prove the
|
||||
* callback's output actually reached it */
|
||||
XMEMSET(info->pk.curve448kg.key->k, 0x5A, CURVE448_KEY_SIZE);
|
||||
info->pk.curve448kg.key->k[0] &= 0xfc;
|
||||
info->pk.curve448kg.key->k[CURVE448_KEY_SIZE-1] |= 0x80;
|
||||
XMEMSET(info->pk.curve448kg.key->p, 0xC3,
|
||||
CURVE448_PUB_KEY_SIZE);
|
||||
info->pk.curve448kg.key->privSet = 1;
|
||||
info->pk.curve448kg.key->pubSet = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -81229,6 +81263,36 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
|||
info->pk.type == WC_PK_TYPE_CURVE448_GENERIC) {
|
||||
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE448)
|
||||
if (myCtx->exampleVar == 99) {
|
||||
/* check the dispatcher populated every payload field, then
|
||||
* write a per-type marker so the caller can prove the
|
||||
* callback's output actually reached it */
|
||||
if (info->pk.type == WC_PK_TYPE_CURVE448_MAKE_PUB) {
|
||||
if ((info->pk.curve448makepub.pub == NULL) ||
|
||||
(info->pk.curve448makepub.priv == NULL) ||
|
||||
(info->pk.curve448makepub.pubSz !=
|
||||
CURVE448_PUB_KEY_SIZE) ||
|
||||
(info->pk.curve448makepub.privSz !=
|
||||
CURVE448_KEY_SIZE)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
XMEMSET(info->pk.curve448makepub.pub, 0x6B,
|
||||
CURVE448_PUB_KEY_SIZE);
|
||||
}
|
||||
else {
|
||||
if ((info->pk.curve448generic.pub == NULL) ||
|
||||
(info->pk.curve448generic.priv == NULL) ||
|
||||
(info->pk.curve448generic.basepoint == NULL) ||
|
||||
(info->pk.curve448generic.pubSz !=
|
||||
CURVE448_PUB_KEY_SIZE) ||
|
||||
(info->pk.curve448generic.privSz !=
|
||||
CURVE448_KEY_SIZE) ||
|
||||
(info->pk.curve448generic.basepointSz !=
|
||||
CURVE448_KEY_SIZE)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
XMEMSET(info->pk.curve448generic.pub, 0x3C,
|
||||
CURVE448_PUB_KEY_SIZE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue