mirror of https://github.com/wolfSSL/wolfssl.git
wolfcrypt/src/dsa.c: use do{}while(0) with break, rather than goto, for top level flow control in wc_DsaSign() and wc_DsaVerify() smallstack refactor.
parent
53c6d33695
commit
f2e1595eef
|
@ -682,6 +682,7 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
int ret = 0, sz = 0;
|
int ret = 0, sz = 0;
|
||||||
byte* tmp; /* initial output pointer */
|
byte* tmp; /* initial output pointer */
|
||||||
|
|
||||||
|
do {
|
||||||
#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
#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
|
#else
|
||||||
|
@ -689,7 +690,7 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ret = MP_INIT_E;
|
ret = MP_INIT_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
@ -703,13 +704,13 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
#endif
|
#endif
|
||||||
|| (buffer == NULL)) {
|
|| (buffer == NULL)) {
|
||||||
ret = MEMORY_E;
|
ret = MEMORY_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (digest == NULL || out == NULL || key == NULL || rng == NULL) {
|
if (digest == NULL || out == NULL || key == NULL || rng == NULL) {
|
||||||
ret = BAD_FUNC_ARG;
|
ret = BAD_FUNC_ARG;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sz = min(DSA_HALF_SIZE, mp_unsigned_bin_size(&key->q));
|
sz = min(DSA_HALF_SIZE, mp_unsigned_bin_size(&key->q));
|
||||||
|
@ -724,19 +725,19 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
*/
|
*/
|
||||||
if (mp_sub_d(&key->q, 1, qMinus1)) {
|
if (mp_sub_d(&key->q, 1, qMinus1)) {
|
||||||
ret = MP_SUB_E;
|
ret = MP_SUB_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* Step 4: generate k */
|
/* Step 4: generate k */
|
||||||
if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
|
if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 5 */
|
/* Step 5 */
|
||||||
if (mp_read_unsigned_bin(k, buffer, sz) != MP_OKAY) {
|
if (mp_read_unsigned_bin(k, buffer, sz) != MP_OKAY) {
|
||||||
ret = MP_READ_E;
|
ret = MP_READ_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* k is a random numnber and it should be less than q-1
|
/* k is a random numnber and it should be less than q-1
|
||||||
|
@ -745,50 +746,53 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
/* Step 6 */
|
/* Step 6 */
|
||||||
} while (mp_cmp(k, qMinus1) != MP_LT);
|
} while (mp_cmp(k, qMinus1) != MP_LT);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Step 7 */
|
/* Step 7 */
|
||||||
if (mp_add_d(k, 1, k) != MP_OKAY) {
|
if (mp_add_d(k, 1, k) != MP_OKAY) {
|
||||||
ret = MP_MOD_E;
|
ret = MP_MOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
|
||||||
/* inverse k mod q */
|
/* inverse k mod q */
|
||||||
if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
|
if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
|
||||||
ret = MP_INVMOD_E;
|
ret = MP_INVMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate r, r = (g exp k mod p) mod q */
|
/* 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) {
|
if (mp_exptmod_ex(&key->g, k, key->q.used, &key->p, r) != MP_OKAY) {
|
||||||
ret = MP_EXPTMOD_E;
|
ret = MP_EXPTMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_mod(r, &key->q, r) != MP_OKAY) {
|
if (mp_mod(r, &key->q, r) != MP_OKAY) {
|
||||||
ret = MP_MOD_E;
|
ret = MP_MOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate H from sha digest */
|
/* generate H from sha digest */
|
||||||
if (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;
|
ret = MP_READ_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate s, s = (kInv * (H + x*r)) % q */
|
/* generate s, s = (kInv * (H + x*r)) % q */
|
||||||
if (mp_mul(&key->x, r, s) != MP_OKAY) {
|
if (mp_mul(&key->x, r, s) != MP_OKAY) {
|
||||||
ret = MP_MUL_E;
|
ret = MP_MUL_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_add(s, H, s) != MP_OKAY) {
|
if (mp_add(s, H, s) != MP_OKAY) {
|
||||||
ret = MP_ADD_E;
|
ret = MP_ADD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
|
if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Blinding value
|
/* Blinding value
|
||||||
|
@ -796,29 +800,32 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
|
if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
if (mp_read_unsigned_bin(b, buffer, sz) != MP_OKAY) {
|
if (mp_read_unsigned_bin(b, buffer, sz) != MP_OKAY) {
|
||||||
ret = MP_READ_E;
|
ret = MP_READ_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
} while (mp_cmp(b, qMinus1) != MP_LT);
|
} while (mp_cmp(b, qMinus1) != MP_LT);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
if (mp_add_d(b, 1, b) != MP_OKAY) {
|
if (mp_add_d(b, 1, b) != MP_OKAY) {
|
||||||
ret = MP_MOD_E;
|
ret = MP_MOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set H from sha digest */
|
/* set H from sha digest */
|
||||||
if (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;
|
ret = MP_READ_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate r, r = (g exp k mod p) mod q */
|
/* 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) {
|
if (mp_exptmod_ex(&key->g, k, key->q.used, &key->p, r) != MP_OKAY) {
|
||||||
ret = MP_EXPTMOD_E;
|
ret = MP_EXPTMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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) */
|
||||||
|
@ -826,61 +833,61 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
/* k = k.b */
|
/* k = k.b */
|
||||||
if (mp_mulmod(k, b, &key->q, k) != MP_OKAY) {
|
if (mp_mulmod(k, b, &key->q, k) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* kInv = 1/k.b mod q */
|
/* kInv = 1/k.b mod q */
|
||||||
if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
|
if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
|
||||||
ret = MP_INVMOD_E;
|
ret = MP_INVMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_mod(r, &key->q, r) != MP_OKAY) {
|
if (mp_mod(r, &key->q, r) != MP_OKAY) {
|
||||||
ret = MP_MOD_E;
|
ret = MP_MOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* s = x.r */
|
/* s = x.r */
|
||||||
if (mp_mul(&key->x, r, s) != MP_OKAY) {
|
if (mp_mul(&key->x, r, s) != MP_OKAY) {
|
||||||
ret = MP_MUL_E;
|
ret = MP_MUL_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* s = x.r/k.b */
|
/* s = x.r/k.b */
|
||||||
if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
|
if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* H = H/k.b */
|
/* H = H/k.b */
|
||||||
if (mp_mulmod(H, kInv, &key->q, H) != MP_OKAY) {
|
if (mp_mulmod(H, kInv, &key->q, H) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* s = H/k.b + x.r/k.b = (H + x.r)/k.b */
|
/* s = H/k.b + x.r/k.b = (H + x.r)/k.b */
|
||||||
if (mp_add(s, H, s) != MP_OKAY) {
|
if (mp_add(s, H, s) != MP_OKAY) {
|
||||||
ret = MP_ADD_E;
|
ret = MP_ADD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* s = b.(e + x.r)/k.b = (e + x.r)/k */
|
/* s = b.(e + x.r)/k.b = (e + x.r)/k */
|
||||||
if (mp_mulmod(s, b, &key->q, s) != MP_OKAY) {
|
if (mp_mulmod(s, b, &key->q, s) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* s = (e + x.r)/k */
|
/* s = (e + x.r)/k */
|
||||||
if (mp_mod(s, &key->q, s) != MP_OKAY) {
|
if (mp_mod(s, &key->q, s) != MP_OKAY) {
|
||||||
ret = MP_MOD_E;
|
ret = MP_MOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* detect zero r or s */
|
/* detect zero r or s */
|
||||||
if ((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;
|
ret = MP_ZERO_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write out */
|
/* write out */
|
||||||
|
@ -902,8 +909,7 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
|
||||||
ret = mp_to_unsigned_bin(s, out);
|
ret = mp_to_unsigned_bin(s, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} while (0);
|
||||||
out:
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
if (k) {
|
if (k) {
|
||||||
|
@ -980,14 +986,15 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
|
||||||
#endif
|
#endif
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
if (mp_init_multi(w, u1, u2, v, r, s) != MP_OKAY) {
|
if (mp_init_multi(w, u1, u2, v, r, s) != MP_OKAY) {
|
||||||
ret = MP_INIT_E;
|
ret = MP_INIT_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (digest == NULL || sig == NULL || key == NULL || answer == NULL) {
|
if (digest == NULL || sig == NULL || key == NULL || answer == NULL) {
|
||||||
ret = BAD_FUNC_ARG;
|
ret = BAD_FUNC_ARG;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
@ -998,7 +1005,7 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
|
||||||
(r == NULL) ||
|
(r == NULL) ||
|
||||||
(s == NULL)) {
|
(s == NULL)) {
|
||||||
ret = MEMORY_E;
|
ret = MEMORY_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1006,59 +1013,59 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
|
||||||
if (mp_read_unsigned_bin(r, sig, 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) {
|
mp_read_unsigned_bin(s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) {
|
||||||
ret = MP_READ_E;
|
ret = MP_READ_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
|
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) {
|
mp_cmp(r, &key->q) != MP_LT || mp_cmp(s, &key->q) != MP_LT) {
|
||||||
ret = MP_ZERO_E;
|
ret = MP_ZERO_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* put H into u1 from sha digest */
|
/* put H into u1 from sha digest */
|
||||||
if (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;
|
ret = MP_READ_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* w = s invmod q */
|
/* w = s invmod q */
|
||||||
if (mp_invmod(s, &key->q, w) != MP_OKAY) {
|
if (mp_invmod(s, &key->q, w) != MP_OKAY) {
|
||||||
ret = MP_INVMOD_E;
|
ret = MP_INVMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* u1 = (H * w) % q */
|
/* u1 = (H * w) % q */
|
||||||
if (mp_mulmod(u1, w, &key->q, u1) != MP_OKAY) {
|
if (mp_mulmod(u1, w, &key->q, u1) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* u2 = (r * w) % q */
|
/* u2 = (r * w) % q */
|
||||||
if (mp_mulmod(r, w, &key->q, u2) != MP_OKAY) {
|
if (mp_mulmod(r, w, &key->q, u2) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* verify v = ((g^u1 * y^u2) mod p) mod q */
|
/* verify v = ((g^u1 * y^u2) mod p) mod q */
|
||||||
if (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;
|
ret = MP_EXPTMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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;
|
ret = MP_EXPTMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_mulmod(u1, u2, &key->p, v) != MP_OKAY) {
|
if (mp_mulmod(u1, u2, &key->p, v) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_mod(v, &key->q, v) != MP_OKAY) {
|
if (mp_mod(v, &key->q, v) != MP_OKAY) {
|
||||||
ret = MP_MULMOD_E;
|
ret = MP_MULMOD_E;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do they match */
|
/* do they match */
|
||||||
|
@ -1066,8 +1073,7 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
|
||||||
*answer = 1;
|
*answer = 1;
|
||||||
else
|
else
|
||||||
*answer = 0;
|
*answer = 0;
|
||||||
|
} while (0);
|
||||||
out:
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
if (s) {
|
if (s) {
|
||||||
|
|
Loading…
Reference in New Issue