Merge pull request #5501 from haydenroche5/ecc_non_block

Add support for non-blocking ECC key gen and shared secret gen for P-256/384/521.
This commit is contained in:
David Garske
2022-08-31 18:31:28 -07:00
committed by GitHub
10 changed files with 8670 additions and 5921 deletions

View File

@ -4324,6 +4324,11 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
mp_int k_lcl[1];
#endif
#endif
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
defined(WC_ECC_NONBLOCK_ONLY)
ecc_nb_ctx_t nb_ctx;
XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
#ifdef HAVE_ECC_CDH
/* if cofactor flag has been set */
@ -4349,27 +4354,85 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
#endif
#ifdef WOLFSSL_HAVE_SP_ECC
#ifndef WOLFSSL_SP_NO_256
if (private_key->idx != ECC_CUSTOM_IDX &&
ecc_sets[private_key->idx].id == ECC_SECP256R1) {
ecc_sets[private_key->idx].id == ECC_SECP256R1) {
#ifndef WC_ECC_NONBLOCK
err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
#else
if (private_key->nb_ctx) {
err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
point, out, outlen,
private_key->heap);
}
else {
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
outlen, private_key->heap);
} while (err == FP_WOULDBLOCK);
#else
err = sp_ecc_secret_gen_256(k, point, out, outlen,
private_key->heap);
#endif /* WC_ECC_NONBLOCK_ONLY */
}
#endif /* !WC_ECC_NONBLOCK */
}
else
#endif
#endif /* ! WOLFSSL_SP_NO_256 */
#ifdef WOLFSSL_SP_384
if (private_key->idx != ECC_CUSTOM_IDX &&
ecc_sets[private_key->idx].id == ECC_SECP384R1) {
ecc_sets[private_key->idx].id == ECC_SECP384R1) {
#ifndef WC_ECC_NONBLOCK
err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
#else
if (private_key->nb_ctx) {
err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
point, out, outlen,
private_key->heap);
}
else {
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
outlen, private_key->heap);
} while (err == FP_WOULDBLOCK);
#else
err = sp_ecc_secret_gen_384(k, point, out, outlen,
private_key->heap);
#endif /* WC_ECC_NONBLOCK_ONLY */
}
#endif /* !WC_ECC_NONBLOCK */
}
else
#endif
#endif /* WOLFSSL_SP_384 */
#ifdef WOLFSSL_SP_521
if (private_key->idx != ECC_CUSTOM_IDX &&
ecc_sets[private_key->idx].id == ECC_SECP521R1) {
#ifndef WC_ECC_NONBLOCK
err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
#else
if (private_key->nb_ctx) {
err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
point, out, outlen,
private_key->heap);
}
else {
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
outlen, private_key->heap);
} while (err == FP_WOULDBLOCK);
#else
err = sp_ecc_secret_gen_521(k, point, out, outlen,
private_key->heap);
#endif /* WC_ECC_NONBLOCK_ONLY */
}
#endif /* !WC_ECC_NONBLOCK */
}
else
#endif
#endif /* WOLFSSL_SP_521 */
#else
(void)point;
(void)out;
@ -5071,7 +5134,6 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
#if defined(HAVE_ECC_MAKE_PUB) && !defined(WOLFSSL_SP_MATH)
DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
#endif
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A)
const CRYS_ECPKI_Domain_t* pDomain;
@ -5080,6 +5142,12 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
word32 raw_size = 0;
#endif
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
defined(WC_ECC_NONBLOCK_ONLY)
ecc_nb_ctx_t nb_ctx;
XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
if (key == NULL || rng == NULL) {
return BAD_FUNC_ARG;
}
@ -5217,33 +5285,88 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
#else
#ifdef WOLFSSL_HAVE_SP_ECC
#ifndef WOLFSSL_SP_NO_256
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
#ifndef WC_ECC_NONBLOCK
err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);
#else
if (key->nb_ctx) {
err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, &key->k,
&key->pubkey, key->heap);
}
else {
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, &key->k,
&key->pubkey, key->heap);
} while (err == FP_WOULDBLOCK);
#else
err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);
#endif /* WC_ECC_NONBLOCK_ONLY */
}
#endif /* !WC_ECC_NONBLOCK */
if (err == MP_OKAY) {
key->type = ECC_PRIVATEKEY;
}
}
else
#endif
#endif /* !WOLFSSL_SP_NO_256 */
#ifdef WOLFSSL_SP_384
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
#ifndef WC_ECC_NONBLOCK
err = sp_ecc_make_key_384(rng, &key->k, &key->pubkey, key->heap);
#else
if (key->nb_ctx) {
err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, &key->k,
&key->pubkey, key->heap);
}
else {
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, &key->k,
&key->pubkey, key->heap);
} while (err == FP_WOULDBLOCK);
#else
err = sp_ecc_make_key_384(rng, &key->k, &key->pubkey, key->heap);
#endif /* WC_ECC_NONBLOCK_ONLY */
}
#endif /* !WC_ECC_NONBLOCK */
if (err == MP_OKAY) {
key->type = ECC_PRIVATEKEY;
}
}
else
#endif
#endif /* WOLFSSL_SP_384 */
#ifdef WOLFSSL_SP_521
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
#ifndef WC_ECC_NONBLOCK
err = sp_ecc_make_key_521(rng, &key->k, &key->pubkey, key->heap);
#else
if (key->nb_ctx) {
err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, &key->k,
&key->pubkey, key->heap);
}
else {
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, &key->k,
&key->pubkey, key->heap);
} while (err == FP_WOULDBLOCK);
#else
err = sp_ecc_make_key_521(rng, &key->k, &key->pubkey, key->heap);
if (err == MP_OKAY) {
key->type = ECC_PRIVATEKEY;
}
#endif /* WC_ECC_NONBLOCK_ONLY */
}
#endif /* !WC_ECC_NONBLOCK */
if (err == MP_OKAY) {
key->type = ECC_PRIVATEKEY;
}
}
else
#endif
#endif /* WOLFSSL_SP_521 */
#endif /* WOLFSSL_HAVE_SP_ECC */
{ /* software key gen */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24766,24 +24766,31 @@ exit:
/* ECC Non-blocking tests for Sign and Verify */
/* Requires SP math and supports P384 or P256 */
/* ./configure --enable-ecc=nonblock --enable-sp=yes,nonblock CFLAGS="-DWOLFSSL_PUBLIC_MP" */
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_PUBLIC_MP) && \
defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY) && \
defined(WOLFSSL_HAVE_SP_ECC)
/* Test Data - Random */
static const uint8_t kMsg[] = {
0x69, 0xbc, 0x9f, 0xce, 0x68, 0x17, 0xc2, 0x10, 0xea, 0xfc, 0x10, 0x65, 0x67, 0x52, 0xed, 0x78,
0x6e, 0xb8, 0x83, 0x9c, 0x9a, 0xb4, 0x56, 0x0d, 0xc1, 0x0d, 0x1f, 0x78, 0x6e, 0x75, 0xd7, 0xbe,
0x92, 0x6b, 0x12, 0xf6, 0x76, 0x60, 0x8e, 0xb1, 0xf4, 0x19, 0x0c, 0x81, 0xe7, 0x54, 0x5e, 0xbc,
0xe0, 0xae, 0xc2, 0x7d, 0x1b, 0xc4, 0x6e, 0xec, 0xb1, 0x99, 0x6c, 0xbf, 0x0e, 0x38, 0xa8, 0x01,
0xa6, 0x9a, 0x48, 0x12, 0xe4, 0xc9, 0x3b, 0xf0, 0x63, 0x46, 0x15, 0xb4, 0x61, 0xa8, 0x1a, 0x60,
0x71, 0x87, 0x98, 0xd7, 0x6f, 0x98, 0x7b, 0x2d, 0xb9, 0x19, 0x1b, 0x21, 0x9c, 0x70, 0x58, 0xe8,
0x0d, 0x0f, 0xe9, 0x2d, 0x9a, 0x9a, 0xf1, 0x55, 0xa0, 0x4c, 0xd3, 0x07, 0xbd, 0x97, 0x48, 0xec,
0x88, 0x0a, 0xaf, 0xb3, 0x80, 0x78, 0xa4, 0x59, 0x43, 0x57, 0xd3, 0xa7, 0x01, 0x66, 0x0e, 0xfc
};
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_HAVE_SP_ECC) && \
defined(WOLFSSL_PUBLIC_MP)
/* ECC Private Key "d" */
static const uint8_t kPrivKey[] = {
static const byte p256PrivKey[] = {
/* SECP256R1 */
/* d */
0x1e, 0xe7, 0x70, 0x07, 0xd3, 0x30, 0x94, 0x39,
0x28, 0x90, 0xdf, 0x23, 0x88, 0x2c, 0x4a, 0x34,
0x15, 0xdb, 0x4c, 0x43, 0xcd, 0xfa, 0xe5, 0x1f,
0x3d, 0x4c, 0x37, 0xfe, 0x59, 0x3b, 0x96, 0xd8
};
#ifdef HAVE_ECC384
static const byte p384PrivKey[] = {
/* SECP384R1 */
/* d */
0xa4, 0xe5, 0x06, 0xe8, 0x06, 0x16, 0x3e, 0xab,
0x89, 0xf8, 0x60, 0x43, 0xc0, 0x60, 0x25, 0xdb,
0xba, 0x7b, 0xfe, 0x19, 0x35, 0x08, 0x55, 0x65,
0x76, 0xe2, 0xdc, 0xe0, 0x01, 0x8b, 0x6b, 0x68,
0xdf, 0xcf, 0x6f, 0x80, 0x12, 0xce, 0x79, 0x37,
0xeb, 0x2b, 0x9c, 0x7b, 0xc4, 0x68, 0x1c, 0x74
};
#endif /* HAVE_ECC384 */
#ifdef HAVE_ECC521
static const byte p521PrivKey[] = {
/* SECP521R1 */
/* d */
0x01, 0x68, 0x91, 0x33, 0x53, 0xe2, 0x90, 0x68,
@ -24795,28 +24802,44 @@ static const uint8_t kPrivKey[] = {
0x02, 0x32, 0xee, 0x26, 0x87, 0xcc, 0xed, 0x63,
0x3f, 0x39, 0x27, 0xf0, 0xd7, 0x17, 0x77, 0xa1,
0xa4, 0x36
#elif defined(HAVE_ECC384)
/* SECP384R1 */
/* d */
0xa4, 0xe5, 0x06, 0xe8, 0x06, 0x16, 0x3e, 0xab,
0x89, 0xf8, 0x60, 0x43, 0xc0, 0x60, 0x25, 0xdb,
0xba, 0x7b, 0xfe, 0x19, 0x35, 0x08, 0x55, 0x65,
0x76, 0xe2, 0xdc, 0xe0, 0x01, 0x8b, 0x6b, 0x68,
0xdf, 0xcf, 0x6f, 0x80, 0x12, 0xce, 0x79, 0x37,
0xeb, 0x2b, 0x9c, 0x7b, 0xc4, 0x68, 0x1c, 0x74
#else
/* SECP256R1 */
/* d */
0x1e, 0xe7, 0x70, 0x07, 0xd3, 0x30, 0x94, 0x39,
0x28, 0x90, 0xdf, 0x23, 0x88, 0x2c, 0x4a, 0x34,
0x15, 0xdb, 0x4c, 0x43, 0xcd, 0xfa, 0xe5, 0x1f,
0x3d, 0x4c, 0x37, 0xfe, 0x59, 0x3b, 0x96, 0xd8
#endif
};
#endif /* HAVE_ECC521 */
/* ECC public key Qx/Qy */
static const uint8_t kPubKey[] = {
static const byte p256PubKey[] = {
/* SECP256R1 */
/* Qx */
0x96, 0x93, 0x1c, 0x53, 0x0b, 0x43, 0x6c, 0x42,
0x0c, 0x52, 0x90, 0xe4, 0xa7, 0xec, 0x98, 0xb1,
0xaf, 0xd4, 0x14, 0x49, 0xd8, 0xc1, 0x42, 0x82,
0x04, 0x78, 0xd1, 0x90, 0xae, 0xa0, 0x6c, 0x07,
/* Qy */
0xf2, 0x3a, 0xb5, 0x10, 0x32, 0x8d, 0xce, 0x9e,
0x76, 0xa0, 0xd2, 0x8c, 0xf3, 0xfc, 0xa9, 0x94,
0x43, 0x24, 0xe6, 0x82, 0x00, 0x40, 0xc6, 0xdb,
0x1c, 0x2f, 0xcd, 0x38, 0x4b, 0x60, 0xdd, 0x61
};
#ifdef HAVE_ECC384
static const byte p384PubKey[] = {
/* SECP384R1 */
/* Qx */
0xea, 0xcf, 0x93, 0x4f, 0x2c, 0x09, 0xbb, 0x39,
0x14, 0x0f, 0x56, 0x64, 0xc3, 0x40, 0xb4, 0xdf,
0x0e, 0x63, 0xae, 0xe5, 0x71, 0x4b, 0x00, 0xcc,
0x04, 0x97, 0xff, 0xe1, 0xe9, 0x38, 0x96, 0xbb,
0x5f, 0x91, 0xb2, 0x6a, 0xcc, 0xb5, 0x39, 0x5f,
0x8f, 0x70, 0x59, 0xf1, 0x01, 0xf6, 0x5a, 0x2b,
/* Qy */
0x01, 0x6c, 0x68, 0x0b, 0xcf, 0x55, 0x25, 0xaf,
0x6d, 0x98, 0x48, 0x0a, 0xa8, 0x74, 0xc9, 0xa9,
0x17, 0xa0, 0x0c, 0xc3, 0xfb, 0xd3, 0x23, 0x68,
0xfe, 0x04, 0x3c, 0x63, 0x50, 0x88, 0x3b, 0xb9,
0x4f, 0x7c, 0x67, 0x34, 0xf7, 0x3b, 0xa9, 0x73,
0xe7, 0x1b, 0xc3, 0x51, 0x5e, 0x22, 0x18, 0xec
};
#endif
#ifdef HAVE_ECC521
static const byte p521PubKey[] = {
/* SECP521R1 */
/* Qx */
0x01, 0x62, 0x6e, 0xf1, 0x00, 0xec, 0xd8, 0x99,
@ -24838,269 +24861,8 @@ static const uint8_t kPubKey[] = {
0x37, 0x24, 0xd8, 0xbf, 0x03, 0x0d, 0x8b, 0xb5,
0x40, 0x5c, 0x4f, 0xd6, 0x13, 0x73, 0x42, 0xbc,
0x91, 0xd9
#elif defined(HAVE_ECC384)
/* SECP384R1 */
/* Qx */
0xea, 0xcf, 0x93, 0x4f, 0x2c, 0x09, 0xbb, 0x39,
0x14, 0x0f, 0x56, 0x64, 0xc3, 0x40, 0xb4, 0xdf,
0x0e, 0x63, 0xae, 0xe5, 0x71, 0x4b, 0x00, 0xcc,
0x04, 0x97, 0xff, 0xe1, 0xe9, 0x38, 0x96, 0xbb,
0x5f, 0x91, 0xb2, 0x6a, 0xcc, 0xb5, 0x39, 0x5f,
0x8f, 0x70, 0x59, 0xf1, 0x01, 0xf6, 0x5a, 0x2b,
/* Qy */
0x01, 0x6c, 0x68, 0x0b, 0xcf, 0x55, 0x25, 0xaf,
0x6d, 0x98, 0x48, 0x0a, 0xa8, 0x74, 0xc9, 0xa9,
0x17, 0xa0, 0x0c, 0xc3, 0xfb, 0xd3, 0x23, 0x68,
0xfe, 0x04, 0x3c, 0x63, 0x50, 0x88, 0x3b, 0xb9,
0x4f, 0x7c, 0x67, 0x34, 0xf7, 0x3b, 0xa9, 0x73,
0xe7, 0x1b, 0xc3, 0x51, 0x5e, 0x22, 0x18, 0xec
#else
/* SECP256R1 */
/* Qx */
0x96, 0x93, 0x1c, 0x53, 0x0b, 0x43, 0x6c, 0x42,
0x0c, 0x52, 0x90, 0xe4, 0xa7, 0xec, 0x98, 0xb1,
0xaf, 0xd4, 0x14, 0x49, 0xd8, 0xc1, 0x42, 0x82,
0x04, 0x78, 0xd1, 0x90, 0xae, 0xa0, 0x6c, 0x07,
/* Qy */
0xf2, 0x3a, 0xb5, 0x10, 0x32, 0x8d, 0xce, 0x9e,
0x76, 0xa0, 0xd2, 0x8c, 0xf3, 0xfc, 0xa9, 0x94,
0x43, 0x24, 0xe6, 0x82, 0x00, 0x40, 0xc6, 0xdb,
0x1c, 0x2f, 0xcd, 0x38, 0x4b, 0x60, 0xdd, 0x61
#endif
};
/* ECC Curve */
#ifdef HAVE_ECC521
/* SECP521R1 */
#define ECC_CURVE_SZ 66
#define ECC_CURVE_ID ECC_SECP521R1
#elif defined(HAVE_ECC384)
/* SECP384R1 */
#define ECC_CURVE_SZ 48
#define ECC_CURVE_ID ECC_SECP384R1
#else
/* SECP256R1 */
#define ECC_CURVE_SZ 32
#define ECC_CURVE_ID ECC_SECP256R1
#endif
/* Hash Algorithm */
#if defined(HAVE_ECC521) && defined(WOLFSSL_SHA3)
#define HASH_DIGEST_SZ WC_SHA3_512_DIGEST_SIZE
#define HASH_SHA_VER 3
#define CRYPTO_HASH_FN crypto_sha3_512
#elif defined(HAVE_ECC521) && defined(WOLFSSL_SHA512)
#define HASH_DIGEST_SZ WC_SHA512_DIGEST_SIZE
#define HASH_SHA_VER 2
#define CRYPTO_HASH_FN crypto_sha2_512
#elif defined(HAVE_ECC384) && defined(WOLFSSL_SHA3)
#define HASH_DIGEST_SZ WC_SHA3_384_DIGEST_SIZE
#define HASH_SHA_VER 3
#define CRYPTO_HASH_FN crypto_sha3_384
#elif defined(HAVE_ECC384) && defined(WOLFSSL_SHA384)
#define HASH_DIGEST_SZ WC_SHA384_DIGEST_SIZE
#define HASH_SHA_VER 2
#define CRYPTO_HASH_FN crypto_sha2_384
#elif !defined(NO_SHA256)
#define HASH_DIGEST_SZ WC_SHA256_DIGEST_SIZE
#define HASH_SHA_VER 2
#define CRYPTO_HASH_FN crypto_sha2_256
#else
#error test configuration not supported
#endif
#if defined(HAVE_ECC521) && defined(WOLFSSL_SHA3)
/* helper to perform hashing block by block */
static int crypto_sha3_512(const uint8_t *buf, uint32_t len, uint8_t *hash,
uint32_t hashSz, uint32_t blkSz)
{
int ret;
uint32_t i = 0, chunk;
wc_Sha3 sha3;
/* validate arguments */
if ((buf == NULL && len > 0) || hash == NULL ||
hashSz < WC_SHA3_512_DIGEST_SIZE || blkSz == 0)
{
return BAD_FUNC_ARG;
}
/* Init Sha3_512 structure */
ret = wc_InitSha3_512(&sha3, NULL, INVALID_DEVID);
if (ret != 0) {
return ret;
}
while (i < len) {
chunk = blkSz;
if ((chunk + i) > len)
chunk = len - i;
/* Perform chunked update */
ret = wc_Sha3_512_Update(&sha3, (buf + i), chunk);
if (ret != 0) {
break;
}
i += chunk;
}
if (ret == 0) {
/* Get final digest result */
ret = wc_Sha3_512_Final(&sha3, hash);
}
return ret;
}
#elif defined(HAVE_ECC521) && defined(WOLFSSL_SHA512)
/* helper to perform hashing block by block */
static int crypto_sha2_512(const uint8_t *buf, uint32_t len, uint8_t *hash,
uint32_t hashSz, uint32_t blkSz)
{
int ret;
uint32_t i = 0, chunk;
wc_Sha512 sha512;
/* validate arguments */
if ((buf == NULL && len > 0) || hash == NULL ||
hashSz < WC_SHA512_DIGEST_SIZE || blkSz == 0)
{
return BAD_FUNC_ARG;
}
/* Init Sha512 structure */
ret = wc_InitSha512(&sha512);
if (ret != 0) {
return ret;
}
while (i < len) {
chunk = blkSz;
if ((chunk + i) > len)
chunk = len - i;
/* Perform chunked update */
ret = wc_Sha512Update(&sha512, (buf + i), chunk);
if (ret != 0) {
break;
}
i += chunk;
}
if (ret == 0) {
/* Get final digest result */
ret = wc_Sha512Final(&sha512, hash);
}
return ret;
}
#elif defined(HAVE_ECC384) && defined(WOLFSSL_SHA3)
/* helper to perform hashing block by block */
static int crypto_sha3_384(const uint8_t *buf, uint32_t len, uint8_t *hash,
uint32_t hashSz, uint32_t blkSz)
{
int ret;
uint32_t i = 0, chunk;
wc_Sha3 sha3;
/* validate arguments */
if ((buf == NULL && len > 0) || hash == NULL ||
hashSz < WC_SHA3_384_DIGEST_SIZE || blkSz == 0)
{
return BAD_FUNC_ARG;
}
/* Init Sha3_384 structure */
ret = wc_InitSha3_384(&sha3, NULL, INVALID_DEVID);
if (ret != 0) {
return ret;
}
while (i < len) {
chunk = blkSz;
if ((chunk + i) > len)
chunk = len - i;
/* Perform chunked update */
ret = wc_Sha3_384_Update(&sha3, (buf + i), chunk);
if (ret != 0) {
break;
}
i += chunk;
}
if (ret == 0) {
/* Get final digest result */
ret = wc_Sha3_384_Final(&sha3, hash);
}
return ret;
}
#elif defined(HAVE_ECC384) && defined(WOLFSSL_SHA384)
/* helper to perform hashing block by block */
static int crypto_sha2_384(const uint8_t *buf, uint32_t len, uint8_t *hash,
uint32_t hashSz, uint32_t blkSz)
{
int ret;
uint32_t i = 0, chunk;
wc_Sha384 sha384;
/* validate arguments */
if ((buf == NULL && len > 0) || hash == NULL ||
hashSz < WC_SHA384_DIGEST_SIZE || blkSz == 0)
{
return BAD_FUNC_ARG;
}
/* Init Sha384 structure */
ret = wc_InitSha384(&sha384);
if (ret != 0) {
return ret;
}
while (i < len) {
chunk = blkSz;
if ((chunk + i) > len)
chunk = len - i;
/* Perform chunked update */
ret = wc_Sha384Update(&sha384, (buf + i), chunk);
if (ret != 0) {
break;
}
i += chunk;
}
if (ret == 0) {
/* Get final digest result */
ret = wc_Sha384Final(&sha384, hash);
}
return ret;
}
#elif !defined(NO_SHA256)
/* helper to perform hashing block by block */
static int crypto_sha2_256(const uint8_t *buf, uint32_t len, uint8_t *hash,
uint32_t hashSz, uint32_t blkSz)
{
int ret;
uint32_t i = 0, chunk;
wc_Sha256 sha256;
/* validate arguments */
if ((buf == NULL && len > 0) || hash == NULL ||
hashSz < WC_SHA256_DIGEST_SIZE || blkSz == 0)
{
return BAD_FUNC_ARG;
}
/* Init Sha256 structure */
ret = wc_InitSha256(&sha256);
if (ret != 0) {
return ret;
}
while (i < len) {
chunk = blkSz;
if ((chunk + i) > len)
chunk = len - i;
/* Perform chunked update */
ret = wc_Sha256Update(&sha256, (buf + i), chunk);
if (ret != 0) {
break;
}
i += chunk;
}
if (ret == 0) {
/* Get final digest result */
ret = wc_Sha256Final(&sha256, hash);
}
return ret;
}
#endif
/* perform verify of signature and hash using public key */
/* key is public Qx + public Qy */
/* sig is r + s */
@ -25283,48 +25045,177 @@ static int crypto_ecc_sign(const uint8_t *key, uint32_t keySz,
return ret;
}
#endif /* HAVE_ECC_SIGN && HAVE_ECC_VERIFY */
static int ecc_test_nonblock(WC_RNG* rng)
/*
* This test doesn't work with WOLFSSL_VALIDATE_ECC_KEYGEN defined because we
* don't have non-blocking versions of the key checking functions, yet.
*/
#if defined(HAVE_ECC_DHE) && !defined(WOLFSSL_VALIDATE_ECC_KEYGEN)
static int ecc_test_nonblock_dhe(int curveId, word32 curveSz,
const byte* privKey, const byte* pubKey, WC_RNG* rng)
{
int ret;
uint8_t hash[HASH_DIGEST_SZ];
uint8_t sig[ECC_CURVE_SZ*2];
uint32_t sigSz = sizeof(sig);
ecc_key keyA;
ecc_key keyB;
ecc_nb_ctx_t nbCtxA;
ecc_nb_ctx_t nbCtxB;
byte secretA[ECC_SHARED_SIZE];
byte secretB[ECC_SHARED_SIZE];
word32 secretSzA = ECC_SHARED_SIZE;
word32 secretSzB = ECC_SHARED_SIZE;
int count = 0;
ret = CRYPTO_HASH_FN(
kMsg, sizeof(kMsg), /* input message */
hash, sizeof(hash), /* hash digest result */
32 /* configurable block / chunk size */
);
ret = wc_ecc_init(&keyA);
if (ret == 0) {
ret = wc_ecc_init(&keyB);
}
if (ret == 0) {
ret = wc_ecc_set_nonblock(&keyA, &nbCtxA);
}
if (ret == 0) {
ret = wc_ecc_set_nonblock(&keyB, &nbCtxB);
}
if (ret == 0) {
do {
ret = wc_ecc_make_key_ex(rng, curveSz, &keyA, curveId);
count++;
} while (ret == FP_WOULDBLOCK);
}
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "ECC non-block key gen: %d times\n", count);
#endif
if (ret == 0) {
ret = wc_ecc_check_key(&keyA);
}
if (ret == 0) {
ret = wc_ecc_import_unsigned(&keyB, pubKey, pubKey + curveSz,
privKey, curveId);
}
count = 0;
if (ret == 0) {
do {
ret = wc_ecc_shared_secret(&keyA, &keyB, secretA, &secretSzA);
count++;
} while (ret == FP_WOULDBLOCK);
}
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "ECC non-block shared secret: %d times\n", count);
#endif
if (ret == 0) {
do {
ret = wc_ecc_shared_secret(&keyB, &keyA, secretB, &secretSzB);
} while (ret == FP_WOULDBLOCK);
}
if (ret == 0) {
if (secretSzA != secretSzB ||
XMEMCMP(secretA, secretB, secretSzA) != 0) {
ret = -1;
}
}
wc_ecc_free(&keyA);
wc_ecc_free(&keyB);
return ret;
}
#endif /* HAVE_ECC_DHE && !WOLFSSL_VALIDATE_ECC_KEYGEN */
#if defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY)
static int ecc_test_nonblock_ecdsa(int curveId, word32 curveSz,
const byte* privKey, word32 privKeySz, const byte* pubKey, word32 pubKeySz,
WC_RNG* rng)
{
int ret = 0;
byte* sig = NULL;
word32 sigSz = curveSz * 2;
static const byte hash[] = {
0x8d, 0x28, 0xa3, 0x8b, 0x0b, 0xa9, 0xfe, 0xd4, 0x0e, 0x54, 0xc4, 0x17,
0x3d, 0x54, 0x66, 0x34, 0xbf, 0x5d, 0x6f, 0x46, 0xc2, 0x20, 0xcb, 0xc3,
0x22, 0xe9, 0xb0, 0xdf, 0xe7, 0x64, 0x3f, 0xd9
};
sig = (byte*)XMALLOC(sigSz, HEAP_HINT, DYNAMIC_TYPE_SIGNATURE);
if (sig == NULL) {
ret = -1;
}
if (ret == 0) {
/* Sign hash using private key */
/* Note: result of an ECC sign varies for each call even with same
private key and hash. This is because a new random public key is
used for each operation. */
ret = crypto_ecc_sign(
kPrivKey, sizeof(kPrivKey), /* private key */
hash, sizeof(hash), /* computed hash digest */
sig, &sigSz, /* signature r/s */
ECC_CURVE_SZ, /* curve size in bytes */
ECC_CURVE_ID, /* curve id */
rng
);
ret = crypto_ecc_sign(privKey, privKeySz, hash, sizeof(hash), sig,
&sigSz, curveSz, curveId, rng);
}
if (ret == 0) {
/* Verify generated signature is valid */
ret = crypto_ecc_verify(
kPubKey, sizeof(kPubKey), /* public key point x/y */
hash, sizeof(hash), /* computed hash digest */
sig, sigSz, /* signature r/s */
ECC_CURVE_SZ, /* curve size in bytes */
ECC_CURVE_ID /* curve id */
);
ret = crypto_ecc_verify(pubKey, pubKeySz, hash, sizeof(hash), sig,
sigSz, curveSz, curveId);
}
if (sig != NULL) {
XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_SIGNATURE);
}
return ret;
}
#endif /* WC_ECC_NONBLOCK && WOLFSSL_PUBLIC_MP && HAVE_ECC_SIGN && HAVE_ECC_VERIFY */
#endif /* HAVE_ECC_SIGN && HAVE_ECC_VERIFY */
static int ecc_test_nonblock(WC_RNG* rng)
{
int ret = 0;
word32 i;
int curveIds[3] = {0, 0, 0};
word32 curveSzs[3] = {0, 0, 0};
const byte* privKeys[3] = {NULL, NULL, NULL};
word32 privKeySzs[3] = {0, 0, 0};
const byte* pubKeys[3] = {NULL, NULL, NULL};
word32 pubKeySzs[3] = {0, 0, 0};
curveIds[0] = ECC_SECP256R1;
curveSzs[0] = 32;
privKeys[0] = p256PrivKey;
privKeySzs[0] = sizeof(p256PrivKey);
pubKeys[0] = p256PubKey;
pubKeySzs[0] = sizeof(p256PubKey);
#ifdef HAVE_ECC384
curveIds[1] = ECC_SECP384R1;
curveSzs[1] = 48;
privKeys[1] = p384PrivKey;
privKeySzs[1] = sizeof(p384PrivKey);
pubKeys[1] = p384PubKey;
pubKeySzs[1] = sizeof(p384PubKey);
#endif
#ifdef HAVE_ECC521
curveIds[2] = ECC_SECP521R1;
curveSzs[2] = 66;
privKeys[2] = p521PrivKey;
privKeySzs[2] = sizeof(p521PrivKey);
pubKeys[2] = p521PubKey;
pubKeySzs[2] = sizeof(p521PubKey);
#endif
for (i = 0; ret == 0 && i < sizeof(curveIds) / sizeof(curveIds[0]); ++i) {
if (curveIds[i] == 0) {
continue;
}
#if defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY)
ret = ecc_test_nonblock_ecdsa(curveIds[i], curveSzs[i], privKeys[i],
privKeySzs[i], pubKeys[i], pubKeySzs[i], rng);
#endif /* HAVE_ECC_SIGN && HAVE_ECC_VERIFY */
#if defined(HAVE_ECC_DHE) && !defined(WOLFSSL_VALIDATE_ECC_KEYGEN)
if (ret == 0) {
ret = ecc_test_nonblock_dhe(curveIds[i], curveSzs[i], privKeys[i],
pubKeys[i], rng);
}
#endif /* HAVE_ECC_DHE && !WOLFSSL_VALIDATE_ECC_KEYGEN */
}
return ret;
}
#endif /* WC_ECC_NONBLOCK && WOLFSSL_HAVE_SP_ECC && WOLFSSL_PUBLIC_MP */
WOLFSSL_TEST_SUBROUTINE int ecc_test(void)
{

View File

@ -329,18 +329,35 @@ WOLFSSL_LOCAL int sp_ecc_check_key_1024(const mp_int* pX, const mp_int* pY,
#endif /* HAVE_FIPS_VERSION && HAVE_FIPS_VERSION == 2 && !WOLFSSL_SP_ARM[32|64]_ASM */
#ifdef WOLFSSL_SP_NONBLOCK
WOLFSSL_LOCAL int sp_ecc_make_key_256_nb(sp_ecc_ctx_t* sp_ctx, WC_RNG* rng,
mp_int* priv, ecc_point* pub, void* heap);
WOLFSSL_LOCAL int sp_ecc_secret_gen_256_nb(sp_ecc_ctx_t* sp_ctx,
const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen,
void* heap);
WOLFSSL_LOCAL int sp_ecc_sign_256_nb(sp_ecc_ctx_t* ctx, const byte* hash,
word32 hashLen, WC_RNG* rng, mp_int* priv, mp_int* rm, mp_int* sm,
mp_int* km, void* heap);
WOLFSSL_LOCAL int sp_ecc_verify_256_nb(sp_ecc_ctx_t* ctx, const byte* hash,
word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ,
const mp_int* r, const mp_int* sm, int* res, void* heap);
WOLFSSL_LOCAL int sp_ecc_make_key_384_nb(sp_ecc_ctx_t* sp_ctx, WC_RNG* rng,
mp_int* priv, ecc_point* pub, void* heap);
WOLFSSL_LOCAL int sp_ecc_secret_gen_384_nb(sp_ecc_ctx_t* sp_ctx,
const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen,
void* heap);
WOLFSSL_LOCAL int sp_ecc_sign_384_nb(sp_ecc_ctx_t* ctx, const byte* hash,
word32 hashLen, WC_RNG* rng, mp_int* priv, mp_int* rm, mp_int* sm,
mp_int* km, void* heap);
WOLFSSL_LOCAL int sp_ecc_verify_384_nb(sp_ecc_ctx_t* ctx, const byte* hash,
word32 hashLen, const mp_int* pX, const mp_int* pY, const mp_int* pZ,
const mp_int* r, const mp_int* sm, int* res, void* heap);
WOLFSSL_LOCAL int sp_ecc_make_key_521_nb(sp_ecc_ctx_t* sp_ctx, WC_RNG* rng,
mp_int* priv, ecc_point* pub, void* heap);
WOLFSSL_LOCAL int sp_ecc_secret_gen_521_nb(sp_ecc_ctx_t* sp_ctx,
const mp_int* priv, const ecc_point* pub, byte* out, word32* outLen,
void* heap);
WOLFSSL_LOCAL int sp_ecc_sign_521_nb(sp_ecc_ctx_t* ctx, const byte* hash,
word32 hashLen, WC_RNG* rng, mp_int* priv, mp_int* rm, mp_int* sm,
mp_int* km, void* heap);