mirror of https://github.com/wolfSSL/wolfssl.git
Only offload a key-owned X448 private scalar to that key's own device
wc_curve448_make_key and wc_curve448_export_public_ex derived the public point through the keyless wc_curve448_make_pub, which dispatches to the first registered device; route them through a devId-carrying helper.pull/11209/head
parent
93d71fdda9
commit
06abdc18e6
|
|
@ -953,6 +953,7 @@ int test_wc_curve448_make_pub_generic(void)
|
|||
typedef struct curve448SpyCtx {
|
||||
int kgSeen;
|
||||
int ssSeen;
|
||||
int mpSeen;
|
||||
int decline;
|
||||
int forceErr;
|
||||
int zeroSecret;
|
||||
|
|
@ -984,6 +985,10 @@ static int curve448_test_crypto_cb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
|||
info->pk.curve448kg.size, info->pk.curve448kg.key);
|
||||
info->pk.curve448kg.key->devId = save;
|
||||
}
|
||||
if (info->pk.type == WC_PK_TYPE_CURVE448_MAKE_PUB) {
|
||||
/* count, then decline so the software path produces the point */
|
||||
spy->mpSeen++;
|
||||
}
|
||||
if (info->pk.type == WC_PK_TYPE_CURVE448) {
|
||||
int save = info->pk.curve448.private_key->devId;
|
||||
spy->ssSeen++;
|
||||
|
|
@ -1022,6 +1027,7 @@ int test_wc_curve448_cryptocb(void)
|
|||
curve448_key keyB;
|
||||
byte ssAB[CURVE448_PUB_KEY_SIZE];
|
||||
byte ssBA[CURVE448_PUB_KEY_SIZE];
|
||||
byte pubTmp[CURVE448_PUB_KEY_SIZE];
|
||||
word32 ssABLen = (word32)sizeof(ssAB);
|
||||
word32 ssBALen = (word32)sizeof(ssBA);
|
||||
#ifndef WC_NO_CONSTRUCTORS
|
||||
|
|
@ -1100,6 +1106,28 @@ int test_wc_curve448_cryptocb(void)
|
|||
spy.zeroSecret = 0;
|
||||
#endif
|
||||
|
||||
#if !defined(WOLF_CRYPTO_CB_FIND) && !defined(WOLF_CRYPTO_CB_ONLY_CURVE448)
|
||||
/* a key bound to no device must not have its private scalar handed to
|
||||
* whichever device happens to be registered: keygen derives the public
|
||||
* point in software without dispatching make_pub */
|
||||
{
|
||||
curve448_key unbound;
|
||||
int mpBefore = spy.mpSeen;
|
||||
|
||||
XMEMSET(&unbound, 0, sizeof(unbound));
|
||||
ExpectIntEQ(wc_curve448_init(&unbound), 0);
|
||||
ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &unbound),
|
||||
0);
|
||||
ExpectIntEQ(spy.mpSeen, mpBefore);
|
||||
/* the keyless public API has no devId to respect, so it still
|
||||
* reaches the device */
|
||||
ExpectIntEQ(wc_curve448_make_pub((int)sizeof(pubTmp), pubTmp,
|
||||
(int)sizeof(unbound.k), unbound.k), 0);
|
||||
ExpectIntGT(spy.mpSeen, mpBefore);
|
||||
wc_curve448_free(&unbound);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* constructor arg checks */
|
||||
ExpectIntEQ(wc_curve448_init_ex(NULL, HEAP_HINT, devId),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
|
|
|
|||
|
|
@ -1516,7 +1516,7 @@ int wc_CryptoCb_Curve448(curve448_key* private_key,
|
|||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
|
||||
int wc_CryptoCb_Curve448MakePub(int public_size, byte* pub,
|
||||
int wc_CryptoCb_Curve448MakePub(int devId, int public_size, byte* pub,
|
||||
int private_size, const byte* priv)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
|
|
@ -1525,9 +1525,11 @@ int wc_CryptoCb_Curve448MakePub(int public_size, byte* pub,
|
|||
if (pub == NULL || priv == NULL)
|
||||
return ret;
|
||||
|
||||
/* try the find callback first, else grab the first registered device */
|
||||
dev = wc_CryptoCb_FindDevice(INVALID_DEVID, WC_ALGO_TYPE_PK);
|
||||
if (dev == NULL || dev->cb == NULL)
|
||||
/* locate registered callback */
|
||||
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK);
|
||||
/* only a caller that selected no device settles for the first registered
|
||||
* one; a devId names the single device allowed to see the scalar */
|
||||
if ((dev == NULL || dev->cb == NULL) && (devId == INVALID_DEVID))
|
||||
dev = wc_CryptoCb_FindDeviceByIndex(0);
|
||||
if (dev && dev->cb) {
|
||||
wc_CryptoInfo cryptoInfo;
|
||||
|
|
@ -1545,7 +1547,7 @@ int wc_CryptoCb_Curve448MakePub(int public_size, byte* pub,
|
|||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
|
||||
int wc_CryptoCb_Curve448Generic(int public_size, byte* pub,
|
||||
int wc_CryptoCb_Curve448Generic(int devId, int public_size, byte* pub,
|
||||
int private_size, const byte* priv, int basepoint_size,
|
||||
const byte* basepoint)
|
||||
{
|
||||
|
|
@ -1555,9 +1557,11 @@ int wc_CryptoCb_Curve448Generic(int public_size, byte* pub,
|
|||
if (pub == NULL || priv == NULL || basepoint == NULL)
|
||||
return ret;
|
||||
|
||||
/* try the find callback first, else grab the first registered device */
|
||||
dev = wc_CryptoCb_FindDevice(INVALID_DEVID, WC_ALGO_TYPE_PK);
|
||||
if (dev == NULL || dev->cb == NULL)
|
||||
/* locate registered callback */
|
||||
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK);
|
||||
/* only a caller that selected no device settles for the first registered
|
||||
* one; a devId names the single device allowed to see the scalar */
|
||||
if ((dev == NULL || dev->cb == NULL) && (devId == INVALID_DEVID))
|
||||
dev = wc_CryptoCb_FindDeviceByIndex(0);
|
||||
if (dev && dev->cb) {
|
||||
wc_CryptoInfo cryptoInfo;
|
||||
|
|
|
|||
|
|
@ -65,8 +65,18 @@ static WC_INLINE int curve448_priv_clamp_check(const byte* priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
|
||||
const byte* priv)
|
||||
/* Compute pub = priv * basepoint(5).
|
||||
*
|
||||
* devId [in] Device to offload to, INVALID_DEVID for the caller's choice.
|
||||
* cbOk [in] Whether the private scalar may be offered to a crypto
|
||||
* callback at all. The keyless public API sets this, since it
|
||||
* has no key to take a devId from; a key-owned scalar only sets
|
||||
* it when the key is actually bound to a device, so an unbound
|
||||
* key is never offloaded to whichever device happens to be
|
||||
* registered first.
|
||||
*/
|
||||
static int curve448_make_pub_ex(int public_size, byte* pub, int private_size,
|
||||
const byte* priv, int devId, int cbOk)
|
||||
{
|
||||
int ret;
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_CURVE448
|
||||
|
|
@ -87,10 +97,16 @@ int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
|
|||
return ret;
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
ret = wc_CryptoCb_Curve448MakePub(public_size, pub, private_size, priv);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall-through when unavailable */
|
||||
if (cbOk) {
|
||||
ret = wc_CryptoCb_Curve448MakePub(devId, public_size, pub,
|
||||
private_size, priv);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall-through when unavailable */
|
||||
}
|
||||
#else
|
||||
(void)devId;
|
||||
(void)cbOk;
|
||||
#endif
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_ONLY_CURVE448
|
||||
|
|
@ -105,6 +121,33 @@ int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Derive a key's public point from its own private scalar. */
|
||||
static int curve448_key_make_pub(curve448_key* key)
|
||||
{
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
#ifdef WOLF_CRYPTO_CB_FIND
|
||||
/* the find callback gets to route unbound keys */
|
||||
const int cbOk = 1;
|
||||
#else
|
||||
const int cbOk = (key->devId != INVALID_DEVID);
|
||||
#endif
|
||||
|
||||
return curve448_make_pub_ex((int)sizeof(key->p), key->p,
|
||||
(int)sizeof(key->k), key->k, key->devId, cbOk);
|
||||
#else
|
||||
return curve448_make_pub_ex((int)sizeof(key->p), key->p,
|
||||
(int)sizeof(key->k), key->k, INVALID_DEVID, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
|
||||
const byte* priv)
|
||||
{
|
||||
/* no key, so no device was selected: any registered one may serve it */
|
||||
return curve448_make_pub_ex(public_size, pub, private_size, priv,
|
||||
INVALID_DEVID, 1);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
|
@ -146,8 +189,9 @@ int wc_curve448_generic(int public_size, byte* pub,
|
|||
return ret;
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
ret = wc_CryptoCb_Curve448Generic(public_size, pub, private_size, priv,
|
||||
basepoint_size, basepoint);
|
||||
/* no key, so no device was selected: any registered one may serve it */
|
||||
ret = wc_CryptoCb_Curve448Generic(INVALID_DEVID, public_size, pub,
|
||||
private_size, priv, basepoint_size, basepoint);
|
||||
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 */
|
||||
|
|
@ -232,8 +276,7 @@ int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key)
|
|||
key->k[CURVE448_KEY_SIZE-1] |= 0x80;
|
||||
|
||||
/* compute public */
|
||||
ret = wc_curve448_make_pub((int)sizeof(key->p), key->p,
|
||||
(int)sizeof(key->k), key->k);
|
||||
ret = curve448_key_make_pub(key);
|
||||
if (ret == 0) {
|
||||
key->pubSet = 1;
|
||||
}
|
||||
|
|
@ -435,8 +478,7 @@ int wc_curve448_export_public_ex(curve448_key* key, byte* out, word32* outLen,
|
|||
if (ret == 0) {
|
||||
/* calculate public if missing */
|
||||
if (!key->pubSet) {
|
||||
ret = wc_curve448_make_pub((int)sizeof(key->p), key->p,
|
||||
(int)sizeof(key->k), key->k);
|
||||
ret = curve448_key_make_pub(key);
|
||||
key->pubSet = (ret == 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -989,10 +989,10 @@ WOLFSSL_LOCAL int wc_CryptoCb_Curve448Gen(WC_RNG* rng, int keySize,
|
|||
curve448_key* key);
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_Curve448(curve448_key* private_key,
|
||||
curve448_key* public_key, byte* out, word32* outlen, int endian);
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_Curve448MakePub(int public_size, byte* pub,
|
||||
int private_size, const byte* priv);
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_Curve448Generic(int public_size, byte* pub,
|
||||
int private_size, const byte* priv, int basepoint_size,
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_Curve448MakePub(int devId, int public_size,
|
||||
byte* pub, int private_size, const byte* priv);
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_Curve448Generic(int devId, int public_size,
|
||||
byte* pub, int private_size, const byte* priv, int basepoint_size,
|
||||
const byte* basepoint);
|
||||
#endif /* HAVE_CURVE448 */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue