forked from wolfSSL/wolfssl
dsa.c, srp.c, wolfcrypt/test/test.c: smallstack refactors: wc_DsaExportKeyRaw(), wc_DsaSign(), wc_SrpSetKey(), ecc_test_cdh_vectors(), ecc_test_custom_curves().
This commit is contained in:
@ -654,32 +654,67 @@ int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz)
|
||||
|
||||
int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||
{
|
||||
mp_int k, kInv, r, s, H;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
mp_int *k = (mp_int *)XMALLOC(sizeof *k,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *kInv = (mp_int *)XMALLOC(sizeof *kInv,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *r = (mp_int *)XMALLOC(sizeof *r,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *s = (mp_int *)XMALLOC(sizeof *s,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *H = (mp_int *)XMALLOC(sizeof *H,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
mp_int b;
|
||||
mp_int *b = (mp_int *)XMALLOC(sizeof *b,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
byte *buffer = (byte *)XMALLOC(DSA_HALF_SIZE, key->heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#else
|
||||
mp_int k[1], kInv[1], r[1], s[1], H[1];
|
||||
#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
mp_int b[1];
|
||||
#endif
|
||||
byte buffer[DSA_HALF_SIZE];
|
||||
#endif
|
||||
mp_int* qMinus1;
|
||||
int ret = 0, sz;
|
||||
byte buffer[DSA_HALF_SIZE];
|
||||
int ret = 0, sz = 0;
|
||||
byte* tmp; /* initial output pointer */
|
||||
|
||||
if (digest == NULL || out == NULL || key == NULL || rng == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
tmp = out;
|
||||
|
||||
sz = min((int)sizeof(buffer), mp_unsigned_bin_size(&key->q));
|
||||
|
||||
#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)
|
||||
if (mp_init_multi(k, kInv, r, s, H, 0) != MP_OKAY)
|
||||
#else
|
||||
if (mp_init_multi(&k, &kInv, &r, &s, &H, &b) != MP_OKAY)
|
||||
if (mp_init_multi(k, kInv, r, s, H, b) != MP_OKAY)
|
||||
#endif
|
||||
{
|
||||
return MP_INIT_E;
|
||||
ret = MP_INIT_E;
|
||||
goto out;
|
||||
}
|
||||
qMinus1 = &kInv;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if ((k == NULL) ||
|
||||
(kInv == NULL) ||
|
||||
(r == NULL) ||
|
||||
(s == NULL) ||
|
||||
(H == NULL)
|
||||
#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
|| (b == NULL)
|
||||
#endif
|
||||
|| (buffer == NULL)) {
|
||||
ret = MEMORY_E;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (digest == NULL || out == NULL || key == NULL || rng == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sz = min(DSA_HALF_SIZE, mp_unsigned_bin_size(&key->q));
|
||||
tmp = out;
|
||||
qMinus1 = kInv;
|
||||
|
||||
/* NIST FIPS 186-4: B.2.2
|
||||
* Per-Message Secret Number Generation by Testing Candidates
|
||||
@ -687,159 +722,248 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||
* Check that k is less than q-1: range [0, q-2].
|
||||
* Add 1 to k: range [1, q-1].
|
||||
*/
|
||||
if (mp_sub_d(&key->q, 1, qMinus1))
|
||||
if (mp_sub_d(&key->q, 1, qMinus1)) {
|
||||
ret = MP_SUB_E;
|
||||
|
||||
if (ret == 0) {
|
||||
do {
|
||||
/* Step 4: generate k */
|
||||
ret = wc_RNG_GenerateBlock(rng, buffer, sz);
|
||||
|
||||
/* Step 5 */
|
||||
if (ret == 0 && mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
/* k is a random numnber and it should be less than q-1
|
||||
* if k greater than repeat
|
||||
*/
|
||||
/* Step 6 */
|
||||
} while (ret == 0 && mp_cmp(&k, qMinus1) != MP_LT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Step 4: generate k */
|
||||
if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Step 5 */
|
||||
if (mp_read_unsigned_bin(k, buffer, sz) != MP_OKAY) {
|
||||
ret = MP_READ_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* k is a random numnber and it should be less than q-1
|
||||
* if k greater than repeat
|
||||
*/
|
||||
/* Step 6 */
|
||||
} while (mp_cmp(k, qMinus1) != MP_LT);
|
||||
|
||||
/* Step 7 */
|
||||
if (ret == 0 && mp_add_d(&k, 1, &k) != MP_OKAY)
|
||||
if (mp_add_d(k, 1, k) != MP_OKAY) {
|
||||
ret = MP_MOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
/* inverse k mod q */
|
||||
if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
|
||||
if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
|
||||
ret = MP_INVMOD_E;
|
||||
|
||||
/* generate r, r = (g exp k mod p) mod q */
|
||||
if (ret == 0 && mp_exptmod_ex(&key->g, &k, key->q.used, &key->p,
|
||||
&r) != MP_OKAY) {
|
||||
ret = MP_EXPTMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
|
||||
/* generate r, r = (g exp k mod p) mod q */
|
||||
if (mp_exptmod_ex(&key->g, k, key->q.used, &key->p, r) != MP_OKAY) {
|
||||
ret = MP_EXPTMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mp_mod(r, &key->q, r) != MP_OKAY) {
|
||||
ret = MP_MOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* generate H from sha digest */
|
||||
if (ret == 0 && mp_read_unsigned_bin(&H, digest,WC_SHA_DIGEST_SIZE) != MP_OKAY)
|
||||
if (mp_read_unsigned_bin(H, digest,WC_SHA_DIGEST_SIZE) != MP_OKAY) {
|
||||
ret = MP_READ_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* generate s, s = (kInv * (H + x*r)) % q */
|
||||
if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
|
||||
if (mp_mul(&key->x, r, s) != MP_OKAY) {
|
||||
ret = MP_MUL_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
|
||||
if (mp_add(s, H, s) != MP_OKAY) {
|
||||
ret = MP_ADD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
|
||||
if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
/* Blinding value
|
||||
* Generate b in range [1, q-1].
|
||||
*/
|
||||
if (ret == 0) {
|
||||
do {
|
||||
ret = wc_RNG_GenerateBlock(rng, buffer, sz);
|
||||
if (ret == 0 && mp_read_unsigned_bin(&b, buffer, sz) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
} while (ret == 0 && mp_cmp(&b, qMinus1) != MP_LT);
|
||||
}
|
||||
if (ret == 0 && mp_add_d(&b, 1, &b) != MP_OKAY)
|
||||
do {
|
||||
if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
|
||||
goto out;
|
||||
}
|
||||
if (mp_read_unsigned_bin(b, buffer, sz) != MP_OKAY) {
|
||||
ret = MP_READ_E;
|
||||
goto out;
|
||||
}
|
||||
} while (mp_cmp(b, qMinus1) != MP_LT);
|
||||
|
||||
if (mp_add_d(b, 1, b) != MP_OKAY) {
|
||||
ret = MP_MOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* set H from sha digest */
|
||||
if (ret == 0 && mp_read_unsigned_bin(&H, digest,
|
||||
WC_SHA_DIGEST_SIZE) != MP_OKAY) {
|
||||
if (mp_read_unsigned_bin(H, digest, WC_SHA_DIGEST_SIZE) != MP_OKAY) {
|
||||
ret = MP_READ_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* generate r, r = (g exp k mod p) mod q */
|
||||
if (ret == 0 && mp_exptmod_ex(&key->g, &k, key->q.used, &key->p,
|
||||
&r) != MP_OKAY) {
|
||||
if (mp_exptmod_ex(&key->g, k, key->q.used, &key->p, r) != MP_OKAY) {
|
||||
ret = MP_EXPTMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* calculate s = (H + xr)/k
|
||||
= b.(H/k.b + x.r/k.b) */
|
||||
/* calculate s = (H + xr)/k = b.(H/k.b + x.r/k.b) */
|
||||
|
||||
/* k = k.b */
|
||||
if (ret == 0 && mp_mulmod(&k, &b, &key->q, &k) != MP_OKAY)
|
||||
if (mp_mulmod(k, b, &key->q, k) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* kInv = 1/k.b mod q */
|
||||
if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
|
||||
if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
|
||||
ret = MP_INVMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
|
||||
if (mp_mod(r, &key->q, r) != MP_OKAY) {
|
||||
ret = MP_MOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* s = x.r */
|
||||
if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
|
||||
if (mp_mul(&key->x, r, s) != MP_OKAY) {
|
||||
ret = MP_MUL_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* s = x.r/k.b */
|
||||
if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
|
||||
if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* H = H/k.b */
|
||||
if (ret == 0 && mp_mulmod(&H, &kInv, &key->q, &H) != MP_OKAY)
|
||||
if (mp_mulmod(H, kInv, &key->q, H) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* s = H/k.b + x.r/k.b
|
||||
= (H + x.r)/k.b */
|
||||
if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
|
||||
/* s = H/k.b + x.r/k.b = (H + x.r)/k.b */
|
||||
if (mp_add(s, H, s) != MP_OKAY) {
|
||||
ret = MP_ADD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* s = b.(e + x.r)/k.b
|
||||
= (e + x.r)/k */
|
||||
if (ret == 0 && mp_mulmod(&s, &b, &key->q, &s) != MP_OKAY)
|
||||
/* s = b.(e + x.r)/k.b = (e + x.r)/k */
|
||||
if (mp_mulmod(s, b, &key->q, s) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* s = (e + x.r)/k */
|
||||
if (ret == 0 && mp_mod(&s, &key->q, &s) != MP_OKAY)
|
||||
if (mp_mod(s, &key->q, s) != MP_OKAY) {
|
||||
ret = MP_MOD_E;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* detect zero r or s */
|
||||
if (ret == 0 && (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES))
|
||||
if ((mp_iszero(r) == MP_YES) || (mp_iszero(s) == MP_YES)) {
|
||||
ret = MP_ZERO_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* write out */
|
||||
if (ret == 0) {
|
||||
int rSz = mp_unsigned_bin_size(&r);
|
||||
int sSz = mp_unsigned_bin_size(&s);
|
||||
{
|
||||
int rSz = mp_unsigned_bin_size(r);
|
||||
int sSz = mp_unsigned_bin_size(s);
|
||||
|
||||
while (rSz++ < DSA_HALF_SIZE) {
|
||||
*out++ = 0x00; /* pad front with zeros */
|
||||
}
|
||||
|
||||
if (mp_to_unsigned_bin(&r, out) != MP_OKAY)
|
||||
if (mp_to_unsigned_bin(r, out) != MP_OKAY)
|
||||
ret = MP_TO_E;
|
||||
else {
|
||||
out = tmp + DSA_HALF_SIZE; /* advance to s in output */
|
||||
while (sSz++ < DSA_HALF_SIZE) {
|
||||
*out++ = 0x00; /* pad front with zeros */
|
||||
}
|
||||
ret = mp_to_unsigned_bin(&s, out);
|
||||
ret = mp_to_unsigned_bin(s, out);
|
||||
}
|
||||
}
|
||||
|
||||
ForceZero(buffer, sz);
|
||||
mp_forcezero(&kInv);
|
||||
mp_forcezero(&k);
|
||||
#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
mp_forcezero(&b);
|
||||
out:
|
||||
|
||||
mp_clear(&b);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (k) {
|
||||
if (ret != MP_INIT_E) {
|
||||
mp_forcezero(k);
|
||||
mp_clear(k);
|
||||
}
|
||||
XFREE(k, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (kInv) {
|
||||
if (ret != MP_INIT_E) {
|
||||
mp_forcezero(kInv);
|
||||
mp_clear(kInv);
|
||||
}
|
||||
XFREE(kInv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (r) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(r);
|
||||
XFREE(r, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (s) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(s);
|
||||
XFREE(s, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (H) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(H);
|
||||
XFREE(H, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
if (b) {
|
||||
if (ret != MP_INIT_E) {
|
||||
mp_forcezero(b);
|
||||
mp_clear(b);
|
||||
}
|
||||
XFREE(b, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#endif
|
||||
if (buffer) {
|
||||
ForceZero(buffer, sz);
|
||||
XFREE(buffer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#else /* !WOLFSSL_SMALL_STACK */
|
||||
if (ret != MP_INIT_E) {
|
||||
ForceZero(buffer, sz);
|
||||
mp_forcezero(kInv);
|
||||
mp_forcezero(k);
|
||||
#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||
mp_forcezero(b);
|
||||
mp_clear(b);
|
||||
#endif
|
||||
mp_clear(H);
|
||||
mp_clear(s);
|
||||
mp_clear(r);
|
||||
mp_clear(kInv);
|
||||
mp_clear(k);
|
||||
}
|
||||
#endif
|
||||
mp_clear(&H);
|
||||
mp_clear(&s);
|
||||
mp_clear(&r);
|
||||
mp_clear(&kInv);
|
||||
mp_clear(&k);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -847,70 +971,154 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||
|
||||
int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
|
||||
{
|
||||
mp_int w, u1, u2, v, r, s;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
mp_int *w = (mp_int *)XMALLOC(sizeof *w,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *u1 = (mp_int *)XMALLOC(sizeof *u1,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *u2 = (mp_int *)XMALLOC(sizeof *u2,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *v = (mp_int *)XMALLOC(sizeof *v,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *r = (mp_int *)XMALLOC(sizeof *r,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
mp_int *s = (mp_int *)XMALLOC(sizeof *s,
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#else
|
||||
mp_int w[1], u1[1], u2[1], v[1], r[1], s[1];
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
if (digest == NULL || sig == NULL || key == NULL || answer == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
if (mp_init_multi(w, u1, u2, v, r, s) != MP_OKAY) {
|
||||
ret = MP_INIT_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
if (digest == NULL || sig == NULL || key == NULL || answer == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if ((w == NULL) ||
|
||||
(u1 == NULL) ||
|
||||
(u2 == NULL) ||
|
||||
(v == NULL) ||
|
||||
(r == NULL) ||
|
||||
(s == NULL)) {
|
||||
ret = MEMORY_E;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set r and s from signature */
|
||||
if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY ||
|
||||
mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY)
|
||||
if (mp_read_unsigned_bin(r, sig, DSA_HALF_SIZE) != MP_OKAY ||
|
||||
mp_read_unsigned_bin(s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) {
|
||||
ret = MP_READ_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* sanity checks */
|
||||
if (ret == 0) {
|
||||
if (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES ||
|
||||
mp_cmp(&r, &key->q) != MP_LT || mp_cmp(&s, &key->q) != MP_LT) {
|
||||
ret = MP_ZERO_E;
|
||||
}
|
||||
if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
|
||||
mp_cmp(r, &key->q) != MP_LT || mp_cmp(s, &key->q) != MP_LT) {
|
||||
ret = MP_ZERO_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* put H into u1 from sha digest */
|
||||
if (ret == 0 && mp_read_unsigned_bin(&u1,digest,WC_SHA_DIGEST_SIZE) != MP_OKAY)
|
||||
if (mp_read_unsigned_bin(u1,digest,WC_SHA_DIGEST_SIZE) != MP_OKAY) {
|
||||
ret = MP_READ_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* w = s invmod q */
|
||||
if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY)
|
||||
if (mp_invmod(s, &key->q, w) != MP_OKAY) {
|
||||
ret = MP_INVMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* u1 = (H * w) % q */
|
||||
if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY)
|
||||
if (mp_mulmod(u1, w, &key->q, u1) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* u2 = (r * w) % q */
|
||||
if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY)
|
||||
if (mp_mulmod(r, w, &key->q, u2) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* verify v = ((g^u1 * y^u2) mod p) mod q */
|
||||
if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY)
|
||||
if (mp_exptmod(&key->g, u1, &key->p, u1) != MP_OKAY) {
|
||||
ret = MP_EXPTMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY)
|
||||
if (mp_exptmod(&key->y, u2, &key->p, u2) != MP_OKAY) {
|
||||
ret = MP_EXPTMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY)
|
||||
if (mp_mulmod(u1, u2, &key->p, v) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY)
|
||||
if (mp_mod(v, &key->q, v) != MP_OKAY) {
|
||||
ret = MP_MULMOD_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* do they match */
|
||||
if (ret == 0 && mp_cmp(&r, &v) == MP_EQ)
|
||||
if (mp_cmp(r, v) == MP_EQ)
|
||||
*answer = 1;
|
||||
else
|
||||
*answer = 0;
|
||||
|
||||
mp_clear(&s);
|
||||
mp_clear(&r);
|
||||
mp_clear(&u1);
|
||||
mp_clear(&u2);
|
||||
mp_clear(&w);
|
||||
mp_clear(&v);
|
||||
out:
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (s) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(s);
|
||||
XFREE(s, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (r) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(r);
|
||||
XFREE(r, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (u1) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(u1);
|
||||
XFREE(u1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (u2) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(u2);
|
||||
XFREE(u2, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (w) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(w);
|
||||
XFREE(w, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (v) {
|
||||
if (ret != MP_INIT_E)
|
||||
mp_clear(v);
|
||||
XFREE(v, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#else
|
||||
if (ret != MP_INIT_E) {
|
||||
mp_clear(s);
|
||||
mp_clear(r);
|
||||
mp_clear(u1);
|
||||
mp_clear(u2);
|
||||
mp_clear(w);
|
||||
mp_clear(v);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -631,117 +631,233 @@ static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size)
|
||||
int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
|
||||
byte* serverPubKey, word32 serverPubKeySz)
|
||||
{
|
||||
SrpHash hash;
|
||||
byte *secret;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
SrpHash *hash = (SrpHash *)XMALLOC(sizeof *hash, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
byte *digest = (byte *)XMALLOC(SRP_MAX_DIGEST_SIZE, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
mp_int *u = (mp_int *)XMALLOC(sizeof *u, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
mp_int *s = (mp_int *)XMALLOC(sizeof *s, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
mp_int *temp1 = (mp_int *)XMALLOC(sizeof *temp1, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
mp_int *temp2 = (mp_int *)XMALLOC(sizeof *temp2, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
#else
|
||||
SrpHash hash[1];
|
||||
byte digest[SRP_MAX_DIGEST_SIZE];
|
||||
mp_int u[1], s[1], temp1[1], temp2[1];
|
||||
#endif
|
||||
byte *secret = NULL;
|
||||
word32 i, secretSz, digestSz;
|
||||
mp_int u, s, temp1, temp2;
|
||||
byte pad = 0;
|
||||
int r;
|
||||
|
||||
/* validating params */
|
||||
|
||||
if (!srp || !clientPubKey || clientPubKeySz == 0
|
||||
|| !serverPubKey || serverPubKeySz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
if ((r = mp_init_multi(u, s, temp1, temp2, 0, 0)) != MP_OKAY) {
|
||||
r = MP_INIT_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mp_iszero(&srp->priv) == MP_YES)
|
||||
return SRP_CALL_ORDER_E;
|
||||
if (!srp || !clientPubKey || clientPubKeySz == 0
|
||||
|| !serverPubKey || serverPubKeySz == 0) {
|
||||
r = BAD_FUNC_ARG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if ((hash == NULL) ||
|
||||
(digest == NULL) ||
|
||||
(u == NULL) ||
|
||||
(s == NULL) ||
|
||||
(temp1 == NULL) ||
|
||||
(temp2 == NULL)) {
|
||||
r = MEMORY_E;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mp_iszero(&srp->priv) == MP_YES) {
|
||||
r = SRP_CALL_ORDER_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* initializing variables */
|
||||
|
||||
if ((r = SrpHashInit(&hash, srp->type)) != 0)
|
||||
return r;
|
||||
if ((r = SrpHashInit(hash, srp->type)) != 0)
|
||||
goto out;
|
||||
|
||||
digestSz = SrpHashSize(srp->type);
|
||||
secretSz = mp_unsigned_bin_size(&srp->N);
|
||||
|
||||
if ((secretSz < clientPubKeySz) || (secretSz < serverPubKeySz))
|
||||
return BAD_FUNC_ARG;
|
||||
if ((secretSz < clientPubKeySz) || (secretSz < serverPubKeySz)) {
|
||||
r = BAD_FUNC_ARG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((secret = (byte*)XMALLOC(secretSz, srp->heap, DYNAMIC_TYPE_SRP)) ==NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
if ((r = mp_init_multi(&u, &s, &temp1, &temp2, 0, 0)) != MP_OKAY) {
|
||||
XFREE(secret, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
return r;
|
||||
if ((secret = (byte*)XMALLOC(secretSz, srp->heap, DYNAMIC_TYPE_SRP)) == NULL) {
|
||||
r = MEMORY_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* building u (random scrambling parameter) */
|
||||
|
||||
/* H(A) */
|
||||
for (i = 0; !r && i < secretSz - clientPubKeySz; i++)
|
||||
r = SrpHashUpdate(&hash, &pad, 1);
|
||||
if (!r) r = SrpHashUpdate(&hash, clientPubKey, clientPubKeySz);
|
||||
for (i = 0; i < secretSz - clientPubKeySz; i++) {
|
||||
if ((r = SrpHashUpdate(hash, &pad, 1)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = SrpHashUpdate(hash, clientPubKey, clientPubKeySz)))
|
||||
goto out;
|
||||
|
||||
/* H(A | B) */
|
||||
for (i = 0; !r && i < secretSz - serverPubKeySz; i++)
|
||||
r = SrpHashUpdate(&hash, &pad, 1);
|
||||
if (!r) r = SrpHashUpdate(&hash, serverPubKey, serverPubKeySz);
|
||||
for (i = 0; i < secretSz - serverPubKeySz; i++) {
|
||||
if ((r = SrpHashUpdate(hash, &pad, 1)))
|
||||
goto out;
|
||||
}
|
||||
if ((r = SrpHashUpdate(hash, serverPubKey, serverPubKeySz)))
|
||||
goto out;
|
||||
|
||||
/* set u */
|
||||
if (!r) r = SrpHashFinal(&hash, digest);
|
||||
if (!r) r = mp_read_unsigned_bin(&u, digest, SrpHashSize(srp->type));
|
||||
SrpHashFree(&hash);
|
||||
if ((r = SrpHashFinal(hash, digest)))
|
||||
goto out;
|
||||
if ((r = mp_read_unsigned_bin(u, digest, SrpHashSize(srp->type))))
|
||||
goto out;
|
||||
SrpHashFree(hash);
|
||||
|
||||
/* building s (secret) */
|
||||
|
||||
if (!r && srp->side == SRP_CLIENT_SIDE) {
|
||||
if (srp->side == SRP_CLIENT_SIDE) {
|
||||
|
||||
/* temp1 = B - k * v; rejects k == 0, B == 0 and B >= N. */
|
||||
r = mp_read_unsigned_bin(&temp1, srp->k, digestSz);
|
||||
if (!r) r = mp_iszero(&temp1) == MP_YES ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &temp2);
|
||||
if (!r) r = mp_mulmod(&temp1, &temp2, &srp->N, &s);
|
||||
if (!r) r = mp_read_unsigned_bin(&temp2, serverPubKey, serverPubKeySz);
|
||||
if (!r) r = mp_iszero(&temp2) == MP_YES ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_cmp(&temp2, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_submod(&temp2, &s, &srp->N, &temp1);
|
||||
if ((r = mp_read_unsigned_bin(temp1, srp->k, digestSz)))
|
||||
goto out;
|
||||
if (mp_iszero(temp1) == MP_YES) {
|
||||
r = SRP_BAD_KEY_E;
|
||||
goto out;
|
||||
}
|
||||
if ((r = mp_exptmod(&srp->g, &srp->auth, &srp->N, temp2)))
|
||||
goto out;
|
||||
if ((r = mp_mulmod(temp1, temp2, &srp->N, s)))
|
||||
goto out;
|
||||
if ((r = mp_read_unsigned_bin(temp2, serverPubKey, serverPubKeySz)))
|
||||
goto out;
|
||||
if (mp_iszero(temp2) == MP_YES) {
|
||||
r = SRP_BAD_KEY_E;
|
||||
goto out;
|
||||
}
|
||||
if (mp_cmp(temp2, &srp->N) != MP_LT) {
|
||||
r = SRP_BAD_KEY_E;
|
||||
goto out;
|
||||
}
|
||||
if ((r = mp_submod(temp2, s, &srp->N, temp1)))
|
||||
goto out;
|
||||
|
||||
/* temp2 = a + u * x */
|
||||
if (!r) r = mp_mulmod(&u, &srp->auth, &srp->N, &s);
|
||||
if (!r) r = mp_add(&srp->priv, &s, &temp2);
|
||||
if ((r = mp_mulmod(u, &srp->auth, &srp->N, s)))
|
||||
goto out;
|
||||
if ((r = mp_add(&srp->priv, s, temp2)))
|
||||
goto out;
|
||||
|
||||
/* secret = temp1 ^ temp2 % N */
|
||||
if (!r) r = mp_exptmod(&temp1, &temp2, &srp->N, &s);
|
||||
if ((r = mp_exptmod(temp1, temp2, &srp->N, s)))
|
||||
goto out;
|
||||
|
||||
} else if (!r && srp->side == SRP_SERVER_SIDE) {
|
||||
} else if (srp->side == SRP_SERVER_SIDE) {
|
||||
/* temp1 = v ^ u % N */
|
||||
r = mp_exptmod(&srp->auth, &u, &srp->N, &temp1);
|
||||
if ((r = mp_exptmod(&srp->auth, u, &srp->N, temp1)))
|
||||
goto out;
|
||||
|
||||
/* temp2 = A * temp1 % N; rejects A == 0, A >= N */
|
||||
if (!r) r = mp_read_unsigned_bin(&s, clientPubKey, clientPubKeySz);
|
||||
if (!r) r = mp_iszero(&s) == MP_YES ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_cmp(&s, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_mulmod(&s, &temp1, &srp->N, &temp2);
|
||||
if ((r = mp_read_unsigned_bin(s, clientPubKey, clientPubKeySz)))
|
||||
goto out;
|
||||
if (mp_iszero(s) == MP_YES) {
|
||||
r = SRP_BAD_KEY_E;
|
||||
goto out;
|
||||
}
|
||||
if (mp_cmp(s, &srp->N) != MP_LT) {
|
||||
r = SRP_BAD_KEY_E;
|
||||
goto out;
|
||||
}
|
||||
if ((r = mp_mulmod(s, temp1, &srp->N, temp2)))
|
||||
goto out;
|
||||
|
||||
/* rejects A * v ^ u % N >= 1, A * v ^ u % N == -1 % N */
|
||||
if (!r) r = mp_read_unsigned_bin(&temp1, (const byte*)"\001", 1);
|
||||
if (!r) r = mp_cmp(&temp2, &temp1) != MP_GT ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_sub(&srp->N, &temp1, &s);
|
||||
if (!r) r = mp_cmp(&temp2, &s) == MP_EQ ? SRP_BAD_KEY_E : 0;
|
||||
if ((r = mp_read_unsigned_bin(temp1, (const byte*)"\001", 1)))
|
||||
goto out;
|
||||
if (mp_cmp(temp2, temp1) != MP_GT) {
|
||||
r = SRP_BAD_KEY_E;
|
||||
goto out;
|
||||
}
|
||||
if ((r = mp_sub(&srp->N, temp1, s)))
|
||||
goto out;
|
||||
if (mp_cmp(temp2, s) == MP_EQ) {
|
||||
r = SRP_BAD_KEY_E;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* secret = temp2 * b % N */
|
||||
if (!r) r = mp_exptmod(&temp2, &srp->priv, &srp->N, &s);
|
||||
if ((r = mp_exptmod(temp2, &srp->priv, &srp->N, s)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* building session key from secret */
|
||||
|
||||
if (!r) r = mp_to_unsigned_bin(&s, secret);
|
||||
if (!r) r = srp->keyGenFunc_cb(srp, secret, mp_unsigned_bin_size(&s));
|
||||
if ((r = mp_to_unsigned_bin(s, secret)))
|
||||
goto out;
|
||||
if ((r = srp->keyGenFunc_cb(srp, secret, mp_unsigned_bin_size(s))))
|
||||
goto out;
|
||||
|
||||
/* updating client proof = H( H(N) ^ H(g) | H(user) | salt | A | B | K) */
|
||||
|
||||
if (!r) r = SrpHashUpdate(&srp->client_proof, clientPubKey, clientPubKeySz);
|
||||
if (!r) r = SrpHashUpdate(&srp->client_proof, serverPubKey, serverPubKeySz);
|
||||
if (!r) r = SrpHashUpdate(&srp->client_proof, srp->key, srp->keySz);
|
||||
if ((r = SrpHashUpdate(&srp->client_proof, clientPubKey, clientPubKeySz)))
|
||||
goto out;
|
||||
if ((r = SrpHashUpdate(&srp->client_proof, serverPubKey, serverPubKeySz)))
|
||||
goto out;
|
||||
if ((r = SrpHashUpdate(&srp->client_proof, srp->key, srp->keySz)))
|
||||
goto out;
|
||||
|
||||
/* updating server proof = H(A) */
|
||||
|
||||
if (!r) r = SrpHashUpdate(&srp->server_proof, clientPubKey, clientPubKeySz);
|
||||
r = SrpHashUpdate(&srp->server_proof, clientPubKey, clientPubKeySz);
|
||||
|
||||
XFREE(secret, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
mp_clear(&u); mp_clear(&s); mp_clear(&temp1); mp_clear(&temp2);
|
||||
out:
|
||||
|
||||
if (secret) {
|
||||
ForceZero(secret, secretSz);
|
||||
XFREE(secret, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (hash)
|
||||
XFREE(hash, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
if (digest)
|
||||
XFREE(digest, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
if (u) {
|
||||
if (r != MP_INIT_E)
|
||||
mp_clear(u);
|
||||
XFREE(u, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
}
|
||||
if (s) {
|
||||
if (r != MP_INIT_E)
|
||||
mp_clear(s);
|
||||
XFREE(s, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
}
|
||||
if (temp1) {
|
||||
if (r != MP_INIT_E)
|
||||
mp_clear(temp1);
|
||||
XFREE(temp1, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
}
|
||||
if (temp2) {
|
||||
if (r != MP_INIT_E)
|
||||
mp_clear(temp2);
|
||||
XFREE(temp2, srp->heap, DYNAMIC_TYPE_SRP);
|
||||
}
|
||||
#else
|
||||
if (r != MP_INIT_E) {
|
||||
mp_clear(u);
|
||||
mp_clear(s);
|
||||
mp_clear(temp1);
|
||||
mp_clear(temp2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -19408,39 +19408,53 @@ done:
|
||||
static int ecc_test_cdh_vectors(WC_RNG* rng)
|
||||
{
|
||||
int ret;
|
||||
ecc_key pub_key, priv_key;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ecc_key *pub_key = (ecc_key *)XMALLOC(sizeof *pub_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
ecc_key *priv_key = (ecc_key *)XMALLOC(sizeof *priv_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#else
|
||||
ecc_key pub_key[1], priv_key[1];
|
||||
#endif
|
||||
byte sharedA[32] = {0}, sharedB[32] = {0};
|
||||
word32 x, z;
|
||||
|
||||
const char* QCAVSx = "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287";
|
||||
const char* QCAVSy = "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac";
|
||||
const char* dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534";
|
||||
const char* QIUTx = "ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230";
|
||||
const char* QIUTy = "28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141";
|
||||
const char* ZIUT = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b";
|
||||
static const char* QCAVSx = "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287";
|
||||
static const char* QCAVSy = "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac";
|
||||
static const char* dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534";
|
||||
static const char* QIUTx = "ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230";
|
||||
static const char* QIUTy = "28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141";
|
||||
static const char* ZIUT = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b";
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if ((pub_key == NULL) ||
|
||||
(priv_key == NULL)) {
|
||||
ret = MEMORY_E;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
XMEMSET(pub_key, 0, sizeof *pub_key);
|
||||
XMEMSET(priv_key, 0, sizeof *priv_key);
|
||||
|
||||
/* setup private and public keys */
|
||||
ret = wc_ecc_init_ex(&pub_key, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = wc_ecc_init_ex(&priv_key, HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
wc_ecc_free(&pub_key);
|
||||
return ret;
|
||||
}
|
||||
wc_ecc_set_flags(&pub_key, WC_ECC_FLAG_COFACTOR);
|
||||
wc_ecc_set_flags(&priv_key, WC_ECC_FLAG_COFACTOR);
|
||||
ret = wc_ecc_import_raw(&pub_key, QCAVSx, QCAVSy, NULL, "SECP256R1");
|
||||
ret = wc_ecc_init_ex(pub_key, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
ret = wc_ecc_import_raw(&priv_key, QIUTx, QIUTy, dIUT, "SECP256R1");
|
||||
ret = wc_ecc_init_ex(priv_key, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
wc_ecc_set_flags(pub_key, WC_ECC_FLAG_COFACTOR);
|
||||
wc_ecc_set_flags(priv_key, WC_ECC_FLAG_COFACTOR);
|
||||
ret = wc_ecc_import_raw(pub_key, QCAVSx, QCAVSy, NULL, "SECP256R1");
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
ret = wc_ecc_import_raw(priv_key, QIUTx, QIUTy, dIUT, "SECP256R1");
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
|
||||
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
|
||||
!defined(HAVE_SELFTEST)
|
||||
ret = wc_ecc_set_rng(&priv_key, rng);
|
||||
ret = wc_ecc_set_rng(priv_key, rng);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
#else
|
||||
@ -19451,10 +19465,10 @@ static int ecc_test_cdh_vectors(WC_RNG* rng)
|
||||
x = sizeof(sharedA);
|
||||
do {
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &priv_key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
|
||||
ret = wc_AsyncWait(ret, priv_key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
|
||||
#endif
|
||||
if (ret == 0)
|
||||
ret = wc_ecc_shared_secret(&priv_key, &pub_key, sharedA, &x);
|
||||
ret = wc_ecc_shared_secret(priv_key, pub_key, sharedA, &x);
|
||||
} while (ret == WC_PENDING_E);
|
||||
if (ret != 0) {
|
||||
goto done;
|
||||
@ -19473,8 +19487,21 @@ static int ecc_test_cdh_vectors(WC_RNG* rng)
|
||||
}
|
||||
|
||||
done:
|
||||
wc_ecc_free(&priv_key);
|
||||
wc_ecc_free(&pub_key);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (priv_key) {
|
||||
wc_ecc_free(priv_key);
|
||||
XFREE(priv_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (pub_key) {
|
||||
wc_ecc_free(pub_key);
|
||||
XFREE(pub_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#else
|
||||
wc_ecc_free(priv_key);
|
||||
wc_ecc_free(pub_key);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_ECC_CDH */
|
||||
@ -21230,24 +21257,28 @@ static int ecc_test_custom_curves(WC_RNG* rng)
|
||||
{
|
||||
int ret;
|
||||
word32 inOutIdx;
|
||||
ecc_key key;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ecc_key *key = (ecc_key *)XMALLOC(sizeof *key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#else
|
||||
ecc_key key[1];
|
||||
#endif
|
||||
|
||||
/* test use of custom curve - using BRAINPOOLP256R1 for test */
|
||||
#ifndef WOLFSSL_ECC_CURVE_STATIC
|
||||
const ecc_oid_t ecc_oid_brainpoolp256r1[] = {
|
||||
static const ecc_oid_t ecc_oid_brainpoolp256r1[] = {
|
||||
0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07
|
||||
};
|
||||
const word32 ecc_oid_brainpoolp256r1_sz =
|
||||
sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t);
|
||||
#define ecc_oid_brainpoolp256r1_sz \
|
||||
(sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t))
|
||||
#else
|
||||
#define ecc_oid_brainpoolp256r1 { \
|
||||
0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07 \
|
||||
}
|
||||
#define ecc_oid_brainpoolp256r1_sz 9
|
||||
#endif
|
||||
const word32 ecc_oid_brainpoolp256r1_sum = 104;
|
||||
#define ecc_oid_brainpoolp256r1_sum 104
|
||||
|
||||
const ecc_set_type ecc_dp_brainpool256r1 = {
|
||||
static const ecc_set_type ecc_dp_brainpool256r1 = {
|
||||
32, /* size/bytes */
|
||||
ECC_CURVE_CUSTOM, /* ID */
|
||||
"BRAINPOOLP256R1", /* curve name */
|
||||
@ -21263,11 +21294,20 @@ static int ecc_test_custom_curves(WC_RNG* rng)
|
||||
1, /* cofactor */
|
||||
};
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (! key) {
|
||||
ret = MEMORY_E;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
XMEMSET(key, 0, sizeof *key);
|
||||
|
||||
ret = ecc_test_curve_size(rng, 0, ECC_TEST_VERIFY_COUNT, ECC_CURVE_DEF,
|
||||
&ecc_dp_brainpool256r1);
|
||||
if (ret != 0) {
|
||||
printf("ECC test for custom curve failed! %d\n", ret);
|
||||
return ret;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)
|
||||
@ -21282,23 +21322,33 @@ static int ecc_test_custom_curves(WC_RNG* rng)
|
||||
ret = ecc_test_curve_size(rng, 0, ECC_TEST_VERIFY_COUNT, curve_id, NULL);
|
||||
if (ret < 0) {
|
||||
printf("ECC test for curve_id %d failed! %d\n", curve_id, ret);
|
||||
return ret;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = wc_ecc_init_ex(&key, HEAP_HINT, devId);
|
||||
ret = wc_ecc_init_ex(key, HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
return -10120;
|
||||
ret = -10120;
|
||||
goto done;
|
||||
}
|
||||
|
||||
inOutIdx = 0;
|
||||
ret = wc_EccPublicKeyDecode(eccKeyExplicitCurve, &inOutIdx, &key,
|
||||
ret = wc_EccPublicKeyDecode(eccKeyExplicitCurve, &inOutIdx, key,
|
||||
sizeof(eccKeyExplicitCurve));
|
||||
if (ret != 0)
|
||||
return -10121;
|
||||
ret = -10121;
|
||||
|
||||
wc_ecc_free(&key);
|
||||
done:
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (key) {
|
||||
wc_ecc_free(key);
|
||||
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#else
|
||||
wc_ecc_free(key);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user