Skip to content

Commit a0fc584

Browse files
committed
Curve25519 crypto cb full
1 parent 57655e0 commit a0fc584

9 files changed

Lines changed: 237 additions & 22 deletions

File tree

tests/api/test_curve25519.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,69 @@ int test_wc_curve25519_make_pub(void)
576576
return EXPECT_RESULT();
577577
} /* END test_wc_curve25519_make_pub */
578578

579+
/*
580+
* Positive cross-check of the make_pub, generic and keygen paths (and the
581+
* crypto-callback dispatch for each under WOLF_CRYPTO_CB_ONLY_CURVE25519):
582+
* a public key from make_pub or from generic against base point 9 must match
583+
* the make_key public point, and a shared secret must round trip.
584+
*/
585+
int test_wc_curve25519_make_pub_generic(void)
586+
{
587+
EXPECT_DECLS;
588+
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_SHARED_SECRET)
589+
curve25519_key keyA;
590+
curve25519_key keyB;
591+
WC_RNG rng;
592+
byte pubM[CURVE25519_KEYSIZE];
593+
byte pubG[CURVE25519_KEYSIZE];
594+
const byte base9[CURVE25519_KEYSIZE] = { 9 };
595+
byte genAB[CURVE25519_KEYSIZE];
596+
byte ssAB[CURVE25519_KEYSIZE];
597+
byte ssBA[CURVE25519_KEYSIZE];
598+
word32 ssABLen = (word32)sizeof(ssAB);
599+
word32 ssBALen = (word32)sizeof(ssBA);
600+
601+
XMEMSET(&rng, 0, sizeof(WC_RNG));
602+
603+
ExpectIntEQ(wc_curve25519_init(&keyA), 0);
604+
ExpectIntEQ(wc_curve25519_init(&keyB), 0);
605+
ExpectIntEQ(wc_InitRng(&rng), 0);
606+
607+
ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &keyA), 0);
608+
ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &keyB), 0);
609+
610+
/* make_pub from the private scalar must match the keygen public point */
611+
ExpectIntEQ(wc_curve25519_make_pub((int)sizeof(pubM), pubM,
612+
(int)sizeof(keyA.k), keyA.k), 0);
613+
ExpectBufEQ(pubM, keyA.p.point, CURVE25519_KEYSIZE);
614+
615+
/* generic against base point 9 is the same operation as make_pub */
616+
ExpectIntEQ(wc_curve25519_generic((int)sizeof(pubG), pubG,
617+
(int)sizeof(keyA.k), keyA.k, (int)sizeof(base9), base9), 0);
618+
ExpectBufEQ(pubG, pubM, CURVE25519_KEYSIZE);
619+
620+
/* generic against B's public point must equal the A-B shared secret,
621+
* proving generic actually uses the supplied base point */
622+
ExpectIntEQ(wc_curve25519_generic((int)sizeof(genAB), genAB,
623+
(int)sizeof(keyA.k), keyA.k,
624+
(int)sizeof(keyB.p.point), keyB.p.point), 0);
625+
ExpectIntEQ(wc_curve25519_shared_secret_ex(&keyA, &keyB, ssAB, &ssABLen,
626+
EC25519_LITTLE_ENDIAN), 0);
627+
ExpectBufEQ(genAB, ssAB, CURVE25519_KEYSIZE);
628+
629+
/* shared secret must agree both ways, proving the generated keys are
630+
* mutually consistent (a degenerate result is rejected by shared_secret) */
631+
ExpectIntEQ(wc_curve25519_shared_secret_ex(&keyB, &keyA, ssBA, &ssBALen,
632+
EC25519_LITTLE_ENDIAN), 0);
633+
ExpectBufEQ(ssBA, ssAB, CURVE25519_KEYSIZE);
634+
635+
DoExpectIntEQ(wc_FreeRng(&rng), 0);
636+
wc_curve25519_free(&keyA);
637+
wc_curve25519_free(&keyB);
638+
#endif
639+
return EXPECT_RESULT();
640+
} /* END test_wc_curve25519_make_pub_generic */
641+
579642
/*
580643
* Testing test_wc_curve25519_export_public_ex
581644
*/

tests/api/test_curve25519.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ int test_wc_curve25519_shared_secret_ex(void);
3333
int test_wc_curve25519_shared_secret_zero_check(void);
3434
int test_wc_curve25519_shared_secret_ex_kat(void);
3535
int test_wc_curve25519_make_pub(void);
36+
int test_wc_curve25519_make_pub_generic(void);
3637
int test_wc_curve25519_export_public_ex(void);
3738
int test_wc_curve25519_export_private_raw_ex(void);
3839
int test_wc_curve25519_import_private_raw_ex(void);
@@ -57,6 +58,7 @@ int test_wc_curve25519_nonblock(void);
5758
TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_zero_check),\
5859
TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_ex_kat), \
5960
TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_pub), \
61+
TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_pub_generic), \
6062
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_public_ex), \
6163
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_private_raw_ex), \
6264
TEST_DECL_GROUP("curve25519", test_wc_curve25519_import_private_raw_ex), \

tests/swdev/swdev.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,24 @@ static int swdev_curve25519(wc_CryptoInfo* info)
336336
info->pk.curve25519.outlen, info->pk.curve25519.endian);
337337
}
338338
#endif /* HAVE_CURVE25519_SHARED_SECRET */
339+
340+
static int swdev_curve25519_make_pub(wc_CryptoInfo* info)
341+
{
342+
return wc_curve25519_make_pub((int)info->pk.curve25519makepub.pubSz,
343+
info->pk.curve25519makepub.pub,
344+
(int)info->pk.curve25519makepub.privSz,
345+
info->pk.curve25519makepub.priv);
346+
}
347+
348+
static int swdev_curve25519_generic(wc_CryptoInfo* info)
349+
{
350+
return wc_curve25519_generic((int)info->pk.curve25519generic.pubSz,
351+
info->pk.curve25519generic.pub,
352+
(int)info->pk.curve25519generic.privSz,
353+
info->pk.curve25519generic.priv,
354+
(int)info->pk.curve25519generic.basepointSz,
355+
info->pk.curve25519generic.basepoint);
356+
}
339357
#endif /* HAVE_CURVE25519 */
340358

341359
#ifndef NO_SHA256
@@ -992,6 +1010,10 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
9921010
case WC_PK_TYPE_CURVE25519:
9931011
return swdev_curve25519(info);
9941012
#endif
1013+
case WC_PK_TYPE_CURVE25519_MAKE_PUB:
1014+
return swdev_curve25519_make_pub(info);
1015+
case WC_PK_TYPE_CURVE25519_GENERIC:
1016+
return swdev_curve25519_generic(info);
9951017
#endif /* HAVE_CURVE25519 */
9961018
default:
9971019
return CRYPTOCB_UNAVAILABLE;

wolfcrypt/src/cryptocb.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,67 @@ int wc_CryptoCb_Curve25519(curve25519_key* private_key,
10781078

10791079
return wc_CryptoCb_TranslateErrorCode(ret);
10801080
}
1081+
1082+
int wc_CryptoCb_Curve25519MakePub(int public_size, byte* pub,
1083+
int private_size, const byte* priv)
1084+
{
1085+
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
1086+
CryptoCb* dev;
1087+
1088+
if (pub == NULL || priv == NULL)
1089+
return ret;
1090+
1091+
/* try the find callback first, else grab the first registered device */
1092+
dev = wc_CryptoCb_FindDevice(INVALID_DEVID, WC_ALGO_TYPE_PK);
1093+
if (dev == NULL || dev->cb == NULL)
1094+
dev = wc_CryptoCb_FindDeviceByIndex(0);
1095+
if (dev && dev->cb) {
1096+
wc_CryptoInfo cryptoInfo;
1097+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
1098+
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
1099+
cryptoInfo.pk.type = WC_PK_TYPE_CURVE25519_MAKE_PUB;
1100+
cryptoInfo.pk.curve25519makepub.pub = pub;
1101+
cryptoInfo.pk.curve25519makepub.pubSz = (word32)public_size;
1102+
cryptoInfo.pk.curve25519makepub.priv = priv;
1103+
cryptoInfo.pk.curve25519makepub.privSz = (word32)private_size;
1104+
1105+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
1106+
}
1107+
1108+
return wc_CryptoCb_TranslateErrorCode(ret);
1109+
}
1110+
1111+
int wc_CryptoCb_Curve25519Generic(int public_size, byte* pub,
1112+
int private_size, const byte* priv, int basepoint_size,
1113+
const byte* basepoint)
1114+
{
1115+
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
1116+
CryptoCb* dev;
1117+
1118+
if (pub == NULL || priv == NULL || basepoint == NULL)
1119+
return ret;
1120+
1121+
/* try the find callback first, else grab the first registered device */
1122+
dev = wc_CryptoCb_FindDevice(INVALID_DEVID, WC_ALGO_TYPE_PK);
1123+
if (dev == NULL || dev->cb == NULL)
1124+
dev = wc_CryptoCb_FindDeviceByIndex(0);
1125+
if (dev && dev->cb) {
1126+
wc_CryptoInfo cryptoInfo;
1127+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
1128+
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
1129+
cryptoInfo.pk.type = WC_PK_TYPE_CURVE25519_GENERIC;
1130+
cryptoInfo.pk.curve25519generic.pub = pub;
1131+
cryptoInfo.pk.curve25519generic.pubSz = (word32)public_size;
1132+
cryptoInfo.pk.curve25519generic.priv = priv;
1133+
cryptoInfo.pk.curve25519generic.privSz = (word32)private_size;
1134+
cryptoInfo.pk.curve25519generic.basepoint = basepoint;
1135+
cryptoInfo.pk.curve25519generic.basepointSz = (word32)basepoint_size;
1136+
1137+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
1138+
}
1139+
1140+
return wc_CryptoCb_TranslateErrorCode(ret);
1141+
}
10811142
#endif /* HAVE_CURVE25519 */
10821143

10831144
#ifdef HAVE_ED25519

wolfcrypt/src/curve25519.c

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,13 @@ const curve25519_set_type curve25519_sets[] = {
8686
}
8787
};
8888

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

171+
#ifdef WOLF_CRYPTO_CB
172+
ret = wc_CryptoCb_Curve25519MakePub(public_size, pub, private_size, priv);
173+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
174+
return ret;
175+
/* fall-through when unavailable */
176+
#endif
177+
178+
#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
179+
return NO_VALID_DEVID;
180+
#else
168181
#ifdef FREESCALE_LTC_ECC
169182
/* input basepoint on Weierstrass curve */
170183
ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass);
@@ -229,13 +242,15 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size,
229242
#endif
230243

231244
return ret;
245+
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
232246
}
233247

234248
#ifdef WOLFSSL_CURVE25519_BLINDING
235249
#ifndef FREESCALE_LTC_ECC
236250
#ifndef WOLFSSL_CURVE25519_BLINDING_RAND_CNT
237251
#define WOLFSSL_CURVE25519_BLINDING_RAND_CNT 10
238252
#endif
253+
#ifndef WOLF_CRYPTO_CB_ONLY_CURVE25519
239254
static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p,
240255
WC_RNG* rng)
241256
{
@@ -293,6 +308,7 @@ static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p,
293308

294309
return ret;
295310
}
311+
#endif /* !WOLF_CRYPTO_CB_ONLY_CURVE25519 */
296312
#endif
297313

298314
int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size,
@@ -322,6 +338,16 @@ int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size,
322338
if (ret != 0)
323339
return ret;
324340

341+
#ifdef WOLF_CRYPTO_CB
342+
ret = wc_CryptoCb_Curve25519MakePub(public_size, pub, private_size, priv);
343+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
344+
return ret;
345+
/* fall-through when unavailable */
346+
#endif
347+
348+
#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
349+
return NO_VALID_DEVID;
350+
#else
325351
#ifdef FREESCALE_LTC_ECC
326352
/* input basepoint on Weierstrass curve */
327353
ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass);
@@ -341,6 +367,7 @@ int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size,
341367
}
342368

343369
return ret;
370+
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
344371
}
345372
#endif
346373

@@ -359,7 +386,6 @@ int wc_curve25519_generic(int public_size, byte* pub,
359386
* nxp_ltc_curve25519_GetBasePoint() */
360387
return WC_HW_E;
361388
#else
362-
#ifndef WOLFSSL_CURVE25519_BLINDING
363389
int ret;
364390

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

404+
#ifdef WOLF_CRYPTO_CB
405+
ret = wc_CryptoCb_Curve25519Generic(public_size, pub, private_size, priv,
406+
basepoint_size, basepoint);
407+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
408+
return ret;
409+
/* fall-through when unavailable */
410+
#endif
411+
412+
#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
413+
return NO_VALID_DEVID;
414+
#elif !defined(WOLFSSL_CURVE25519_BLINDING)
378415
fe_init();
379416

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

386423
return ret;
387424
#else
388-
WC_RNG rng;
389-
int ret;
425+
{
426+
WC_RNG rng;
390427

391-
ret = wc_InitRng(&rng);
392-
if (ret == 0) {
393-
ret = wc_curve25519_generic_blind(public_size, pub, private_size, priv,
394-
basepoint_size, basepoint, &rng);
428+
ret = wc_InitRng(&rng);
429+
if (ret == 0) {
430+
ret = wc_curve25519_generic_blind(public_size, pub, private_size,
431+
priv, basepoint_size, basepoint, &rng);
395432

396-
wc_FreeRng(&rng);
433+
wc_FreeRng(&rng);
434+
}
397435
}
398436

399437
return ret;
@@ -436,11 +474,23 @@ int wc_curve25519_generic_blind(int public_size, byte* pub,
436474
if (ret != 0)
437475
return ret;
438476

477+
#ifdef WOLF_CRYPTO_CB
478+
ret = wc_CryptoCb_Curve25519Generic(public_size, pub, private_size, priv,
479+
basepoint_size, basepoint);
480+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
481+
return ret;
482+
/* fall-through when unavailable */
483+
#endif
484+
485+
#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
486+
return NO_VALID_DEVID;
487+
#else
439488
fe_init();
440489

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

443492
return ret;
493+
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
444494
#endif /* FREESCALE_LTC_ECC */
445495
}
446496
#endif
@@ -1206,7 +1256,8 @@ int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId)
12061256
#endif
12071257
(void)heap; /* if needed for XMALLOC/XFREE in future */
12081258

1209-
#ifndef FREESCALE_LTC_ECC
1259+
/* field math is implemented in the callback in crypto cb only */
1260+
#if !defined(FREESCALE_LTC_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_CURVE25519)
12101261
fe_init();
12111262
#endif
12121263

wolfcrypt/src/fe_operations.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323

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

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

0 commit comments

Comments
 (0)