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.

pull/3534/head
Daniel Pouzzner 2020-12-10 18:04:23 -06:00
parent 53c6d33695
commit f2e1595eef
1 changed files with 262 additions and 256 deletions

View File

@ -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) {