Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions tests/api/test_curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,69 @@ int test_wc_curve25519_make_pub(void)
return EXPECT_RESULT();
} /* END test_wc_curve25519_make_pub */

/*
* Positive cross-check of the make_pub, generic and keygen paths (and the
* crypto-callback dispatch for each under WOLF_CRYPTO_CB_ONLY_CURVE25519):
* a public key from make_pub or from generic against base point 9 must match
* the make_key public point, and a shared secret must round trip.
*/
int test_wc_curve25519_make_pub_generic(void)
{
EXPECT_DECLS;
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_SHARED_SECRET)
curve25519_key keyA;
curve25519_key keyB;
WC_RNG rng;
byte pubM[CURVE25519_KEYSIZE];
byte pubG[CURVE25519_KEYSIZE];
const byte base9[CURVE25519_KEYSIZE] = { 9 };
byte genAB[CURVE25519_KEYSIZE];
byte ssAB[CURVE25519_KEYSIZE];
byte ssBA[CURVE25519_KEYSIZE];
word32 ssABLen = (word32)sizeof(ssAB);
word32 ssBALen = (word32)sizeof(ssBA);

XMEMSET(&rng, 0, sizeof(WC_RNG));

ExpectIntEQ(wc_curve25519_init(&keyA), 0);
ExpectIntEQ(wc_curve25519_init(&keyB), 0);
ExpectIntEQ(wc_InitRng(&rng), 0);

ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &keyA), 0);
ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &keyB), 0);

/* make_pub from the private scalar must match the keygen public point */
ExpectIntEQ(wc_curve25519_make_pub((int)sizeof(pubM), pubM,
(int)sizeof(keyA.k), keyA.k), 0);
ExpectBufEQ(pubM, keyA.p.point, CURVE25519_KEYSIZE);

/* generic against base point 9 is the same operation as make_pub */
ExpectIntEQ(wc_curve25519_generic((int)sizeof(pubG), pubG,
(int)sizeof(keyA.k), keyA.k, (int)sizeof(base9), base9), 0);
ExpectBufEQ(pubG, pubM, CURVE25519_KEYSIZE);

/* generic against B's public point must equal the A-B shared secret,
* proving generic actually uses the supplied base point */
ExpectIntEQ(wc_curve25519_generic((int)sizeof(genAB), genAB,
(int)sizeof(keyA.k), keyA.k,
(int)sizeof(keyB.p.point), keyB.p.point), 0);
ExpectIntEQ(wc_curve25519_shared_secret_ex(&keyA, &keyB, ssAB, &ssABLen,
EC25519_LITTLE_ENDIAN), 0);
ExpectBufEQ(genAB, ssAB, CURVE25519_KEYSIZE);

/* shared secret must agree both ways, proving the generated keys are
* mutually consistent (a degenerate result is rejected by shared_secret) */
ExpectIntEQ(wc_curve25519_shared_secret_ex(&keyB, &keyA, ssBA, &ssBALen,
EC25519_LITTLE_ENDIAN), 0);
ExpectBufEQ(ssBA, ssAB, CURVE25519_KEYSIZE);

DoExpectIntEQ(wc_FreeRng(&rng), 0);
wc_curve25519_free(&keyA);
wc_curve25519_free(&keyB);
#endif
return EXPECT_RESULT();
} /* END test_wc_curve25519_make_pub_generic */

/*
* Testing test_wc_curve25519_export_public_ex
*/
Expand Down
2 changes: 2 additions & 0 deletions tests/api/test_curve25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ int test_wc_curve25519_shared_secret_ex(void);
int test_wc_curve25519_shared_secret_zero_check(void);
int test_wc_curve25519_shared_secret_ex_kat(void);
int test_wc_curve25519_make_pub(void);
int test_wc_curve25519_make_pub_generic(void);
int test_wc_curve25519_export_public_ex(void);
int test_wc_curve25519_export_private_raw_ex(void);
int test_wc_curve25519_import_private_raw_ex(void);
Expand All @@ -57,6 +58,7 @@ int test_wc_curve25519_nonblock(void);
TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_zero_check),\
TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_ex_kat), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_pub), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_pub_generic), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_public_ex), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_private_raw_ex), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_import_private_raw_ex), \
Expand Down
22 changes: 22 additions & 0 deletions tests/swdev/swdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,24 @@ static int swdev_curve25519(wc_CryptoInfo* info)
info->pk.curve25519.outlen, info->pk.curve25519.endian);
}
#endif /* HAVE_CURVE25519_SHARED_SECRET */

static int swdev_curve25519_make_pub(wc_CryptoInfo* info)
{
return wc_curve25519_make_pub((int)info->pk.curve25519makepub.pubSz,
info->pk.curve25519makepub.pub,
(int)info->pk.curve25519makepub.privSz,
info->pk.curve25519makepub.priv);
}

static int swdev_curve25519_generic(wc_CryptoInfo* info)
{
return wc_curve25519_generic((int)info->pk.curve25519generic.pubSz,
info->pk.curve25519generic.pub,
(int)info->pk.curve25519generic.privSz,
info->pk.curve25519generic.priv,
(int)info->pk.curve25519generic.basepointSz,
info->pk.curve25519generic.basepoint);
}
#endif /* HAVE_CURVE25519 */

#ifndef NO_SHA256
Expand Down Expand Up @@ -992,6 +1010,10 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
case WC_PK_TYPE_CURVE25519:
return swdev_curve25519(info);
#endif
case WC_PK_TYPE_CURVE25519_MAKE_PUB:
return swdev_curve25519_make_pub(info);
case WC_PK_TYPE_CURVE25519_GENERIC:
return swdev_curve25519_generic(info);
#endif /* HAVE_CURVE25519 */
default:
return CRYPTOCB_UNAVAILABLE;
Expand Down
61 changes: 61 additions & 0 deletions wolfcrypt/src/cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,67 @@ int wc_CryptoCb_Curve25519(curve25519_key* private_key,

return wc_CryptoCb_TranslateErrorCode(ret);
}

int wc_CryptoCb_Curve25519MakePub(int public_size, byte* pub,
int private_size, const byte* priv)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;

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)
dev = wc_CryptoCb_FindDeviceByIndex(0);
if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
cryptoInfo.pk.type = WC_PK_TYPE_CURVE25519_MAKE_PUB;
cryptoInfo.pk.curve25519makepub.pub = pub;
cryptoInfo.pk.curve25519makepub.pubSz = (word32)public_size;
cryptoInfo.pk.curve25519makepub.priv = priv;
cryptoInfo.pk.curve25519makepub.privSz = (word32)private_size;

ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}

return wc_CryptoCb_TranslateErrorCode(ret);
}

int wc_CryptoCb_Curve25519Generic(int public_size, byte* pub,
int private_size, const byte* priv, int basepoint_size,
const byte* basepoint)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;

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)
dev = wc_CryptoCb_FindDeviceByIndex(0);
if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
cryptoInfo.pk.type = WC_PK_TYPE_CURVE25519_GENERIC;
cryptoInfo.pk.curve25519generic.pub = pub;
cryptoInfo.pk.curve25519generic.pubSz = (word32)public_size;
cryptoInfo.pk.curve25519generic.priv = priv;
cryptoInfo.pk.curve25519generic.privSz = (word32)private_size;
cryptoInfo.pk.curve25519generic.basepoint = basepoint;
cryptoInfo.pk.curve25519generic.basepointSz = (word32)basepoint_size;

ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}

return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif /* HAVE_CURVE25519 */

#ifdef HAVE_ED25519
Expand Down
73 changes: 62 additions & 11 deletions wolfcrypt/src/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,13 @@ const curve25519_set_type curve25519_sets[] = {
}
};

#if (!defined(WOLFSSL_CURVE25519_USE_ED25519) && \
/* base point is only referenced by the software scalar-mult paths, which are
* compiled out under WOLF_CRYPTO_CB_ONLY_CURVE25519 */
#if !defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && \
((!defined(WOLFSSL_CURVE25519_USE_ED25519) && \
!(defined(CURVED25519_X64) || (defined(WOLFSSL_ARMASM) && \
defined(__aarch64__)))) || defined(WOLFSSL_CURVE25519_BLINDING) || \
defined(WC_X25519_NONBLOCK)
defined(WC_X25519_NONBLOCK))
static const word32 kCurve25519BasePoint[CURVE25519_KEYSIZE/sizeof(word32)] = {
#ifdef BIG_ENDIAN_ORDER
0x09000000
Expand Down Expand Up @@ -165,6 +168,16 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size,
if (ret != 0)
return ret;

#ifdef WOLF_CRYPTO_CB
ret = wc_CryptoCb_Curve25519MakePub(public_size, pub, private_size, priv);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
#endif

#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
return NO_VALID_DEVID;
#else
#ifdef FREESCALE_LTC_ECC
/* input basepoint on Weierstrass curve */
ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass);
Expand Down Expand Up @@ -229,13 +242,15 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size,
#endif

return ret;
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
}

#ifdef WOLFSSL_CURVE25519_BLINDING
#ifndef FREESCALE_LTC_ECC
#ifndef WOLFSSL_CURVE25519_BLINDING_RAND_CNT
#define WOLFSSL_CURVE25519_BLINDING_RAND_CNT 10
#endif
#ifndef WOLF_CRYPTO_CB_ONLY_CURVE25519
static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p,
WC_RNG* rng)
{
Expand Down Expand Up @@ -293,6 +308,7 @@ static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p,

return ret;
}
#endif /* !WOLF_CRYPTO_CB_ONLY_CURVE25519 */
#endif

int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size,
Expand Down Expand Up @@ -322,6 +338,16 @@ int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size,
if (ret != 0)
return ret;

#ifdef WOLF_CRYPTO_CB
ret = wc_CryptoCb_Curve25519MakePub(public_size, pub, private_size, priv);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
#endif

#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
return NO_VALID_DEVID;
#else
#ifdef FREESCALE_LTC_ECC
/* input basepoint on Weierstrass curve */
ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass);
Expand All @@ -341,6 +367,7 @@ int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size,
}

return ret;
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
}
#endif

Expand All @@ -359,7 +386,6 @@ int wc_curve25519_generic(int public_size, byte* pub,
* nxp_ltc_curve25519_GetBasePoint() */
return WC_HW_E;
#else
#ifndef WOLFSSL_CURVE25519_BLINDING
int ret;

if ((public_size != CURVE25519_KEYSIZE) ||
Expand All @@ -375,6 +401,17 @@ int wc_curve25519_generic(int public_size, byte* pub,
if (ret != 0)
return ret;

#ifdef WOLF_CRYPTO_CB
ret = wc_CryptoCb_Curve25519Generic(public_size, pub, private_size, priv,
basepoint_size, basepoint);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
#endif

#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
return NO_VALID_DEVID;
#elif !defined(WOLFSSL_CURVE25519_BLINDING)
fe_init();

SAVE_VECTOR_REGISTERS(return _svr_ret;);
Expand All @@ -385,15 +422,16 @@ int wc_curve25519_generic(int public_size, byte* pub,

return ret;
#else
WC_RNG rng;
int ret;
{
WC_RNG rng;

ret = wc_InitRng(&rng);
if (ret == 0) {
ret = wc_curve25519_generic_blind(public_size, pub, private_size, priv,
basepoint_size, basepoint, &rng);
ret = wc_InitRng(&rng);
if (ret == 0) {
ret = wc_curve25519_generic_blind(public_size, pub, private_size,
priv, basepoint_size, basepoint, &rng);

wc_FreeRng(&rng);
wc_FreeRng(&rng);
}
}

return ret;
Expand Down Expand Up @@ -436,11 +474,23 @@ int wc_curve25519_generic_blind(int public_size, byte* pub,
if (ret != 0)
return ret;

#ifdef WOLF_CRYPTO_CB
ret = wc_CryptoCb_Curve25519Generic(public_size, pub, private_size, priv,
basepoint_size, basepoint);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
#endif

#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
return NO_VALID_DEVID;
#else
fe_init();

ret = curve25519_smul_blind(pub, priv, basepoint, rng);

return ret;
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
#endif /* FREESCALE_LTC_ECC */
}
#endif
Expand Down Expand Up @@ -1208,7 +1258,8 @@ int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId)
#endif
(void)heap; /* if needed for XMALLOC/XFREE in future */

#ifndef FREESCALE_LTC_ECC
/* field math is implemented in the callback in crypto cb only */
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_CURVE25519)
fe_init();
#endif

Expand Down
4 changes: 1 addition & 3 deletions wolfcrypt/src/fe_operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@

/* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */

/* under WOLF_CRYPTO_CB_ONLY_ED25519 the callback device does all Ed25519
* field math, so Ed25519 alone no longer pulls this file in */
#if defined(HAVE_CURVE25519) || \
#if (defined(HAVE_CURVE25519) && !defined(WOLF_CRYPTO_CB_ONLY_CURVE25519)) || \
(defined(HAVE_ED25519) && !defined(WOLF_CRYPTO_CB_ONLY_ED25519))
#if !defined(CURVE25519_SMALL) && !defined(ED25519_SMALL)

Expand Down
Loading
Loading