From 9e26bc40bb98671fc539b8280a99454a5164f009 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 26 Jul 2019 09:08:23 +1000 Subject: [PATCH] Generate k for DSA signature as per FIPS 186-4 B.2.2 --- wolfcrypt/src/dsa.c | 49 +++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 6974704de..be8d93385 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -662,10 +662,11 @@ 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; - int ret, sz; - byte buffer[DSA_HALF_SIZE]; - byte* tmp; /* initial output pointer */ + mp_int k, kInv, r, s, H; + mp_int* qMinus1; + int ret = 0, sz; + byte buffer[DSA_HALF_SIZE]; + byte* tmp; /* initial output pointer */ if (digest == NULL || out == NULL || key == NULL || rng == NULL) { return BAD_FUNC_ARG; @@ -677,25 +678,35 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) return MP_INIT_E; + qMinus1 = &kInv; - do { - /* generate k */ - ret = wc_RNG_GenerateBlock(rng, buffer, sz); - if (ret != 0) - return ret; + /* NIST FIPS 186-4: B.2.2 + * Per-Message Secret Number Generation by Testing Candidates + * Generate k in range [1, q-1]. + * 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)) + ret = MP_SUB_E; - buffer[0] |= 0x0C; + if (ret == 0) { + do { + /* Step 4: generate k */ + ret = wc_RNG_GenerateBlock(rng, buffer, sz); - if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) - ret = MP_READ_E; + /* 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 - * if k greater than repeat - */ - } while (mp_cmp(&k, &key->q) != MP_LT); - - if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT) - ret = MP_CMP_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); + } + /* Step 7 */ + if (ret == 0 && mp_add_d(&k, 1, &k) != MP_OKAY) + ret = MP_MOD_E; /* inverse k mod q */ if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)