Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Thu Apr 28 00:57:21 2016 +0000
Revision:
4:1b0d80432c79
wolfSSL 3.9.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 4:1b0d80432c79 1 /* dsa.c
wolfSSL 4:1b0d80432c79 2 *
wolfSSL 4:1b0d80432c79 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 4:1b0d80432c79 4 *
wolfSSL 4:1b0d80432c79 5 * This file is part of wolfSSL.
wolfSSL 4:1b0d80432c79 6 *
wolfSSL 4:1b0d80432c79 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 4:1b0d80432c79 8 * it under the terms of the GNU General Public License as published by
wolfSSL 4:1b0d80432c79 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 4:1b0d80432c79 10 * (at your option) any later version.
wolfSSL 4:1b0d80432c79 11 *
wolfSSL 4:1b0d80432c79 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 4:1b0d80432c79 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 4:1b0d80432c79 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 4:1b0d80432c79 15 * GNU General Public License for more details.
wolfSSL 4:1b0d80432c79 16 *
wolfSSL 4:1b0d80432c79 17 * You should have received a copy of the GNU General Public License
wolfSSL 4:1b0d80432c79 18 * along with this program; if not, write to the Free Software
wolfSSL 4:1b0d80432c79 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 4:1b0d80432c79 20 */
wolfSSL 4:1b0d80432c79 21
wolfSSL 4:1b0d80432c79 22
wolfSSL 4:1b0d80432c79 23 #ifdef HAVE_CONFIG_H
wolfSSL 4:1b0d80432c79 24 #include <config.h>
wolfSSL 4:1b0d80432c79 25 #endif
wolfSSL 4:1b0d80432c79 26
wolfSSL 4:1b0d80432c79 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 4:1b0d80432c79 28
wolfSSL 4:1b0d80432c79 29 #ifndef NO_DSA
wolfSSL 4:1b0d80432c79 30
wolfSSL 4:1b0d80432c79 31 #include <wolfssl/wolfcrypt/random.h>
wolfSSL 4:1b0d80432c79 32 #include <wolfssl/wolfcrypt/integer.h>
wolfSSL 4:1b0d80432c79 33 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 4:1b0d80432c79 34 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 4:1b0d80432c79 35 #include <wolfssl/wolfcrypt/sha.h>
wolfSSL 4:1b0d80432c79 36 #include <wolfssl/wolfcrypt/dsa.h>
wolfSSL 4:1b0d80432c79 37
wolfSSL 4:1b0d80432c79 38
wolfSSL 4:1b0d80432c79 39 enum {
wolfSSL 4:1b0d80432c79 40 DSA_HALF_SIZE = 20, /* r and s size */
wolfSSL 4:1b0d80432c79 41 DSA_SIG_SIZE = 40 /* signature size */
wolfSSL 4:1b0d80432c79 42 };
wolfSSL 4:1b0d80432c79 43
wolfSSL 4:1b0d80432c79 44
wolfSSL 4:1b0d80432c79 45 #ifndef WOLFSSL_HAVE_MIN
wolfSSL 4:1b0d80432c79 46 #define WOLFSSL_HAVE_MIN
wolfSSL 4:1b0d80432c79 47
wolfSSL 4:1b0d80432c79 48 static INLINE word32 min(word32 a, word32 b)
wolfSSL 4:1b0d80432c79 49 {
wolfSSL 4:1b0d80432c79 50 return a > b ? b : a;
wolfSSL 4:1b0d80432c79 51 }
wolfSSL 4:1b0d80432c79 52
wolfSSL 4:1b0d80432c79 53 #endif /* WOLFSSL_HAVE_MIN */
wolfSSL 4:1b0d80432c79 54
wolfSSL 4:1b0d80432c79 55
wolfSSL 4:1b0d80432c79 56 void wc_InitDsaKey(DsaKey* key)
wolfSSL 4:1b0d80432c79 57 {
wolfSSL 4:1b0d80432c79 58 key->type = -1; /* haven't decided yet */
wolfSSL 4:1b0d80432c79 59
wolfSSL 4:1b0d80432c79 60 /* TomsFastMath doesn't use memory allocation */
wolfSSL 4:1b0d80432c79 61 #ifndef USE_FAST_MATH
wolfSSL 4:1b0d80432c79 62 key->p.dp = 0; /* public alloc parts */
wolfSSL 4:1b0d80432c79 63 key->q.dp = 0;
wolfSSL 4:1b0d80432c79 64 key->g.dp = 0;
wolfSSL 4:1b0d80432c79 65 key->y.dp = 0;
wolfSSL 4:1b0d80432c79 66
wolfSSL 4:1b0d80432c79 67 key->x.dp = 0; /* private alloc parts */
wolfSSL 4:1b0d80432c79 68 #endif
wolfSSL 4:1b0d80432c79 69 }
wolfSSL 4:1b0d80432c79 70
wolfSSL 4:1b0d80432c79 71
wolfSSL 4:1b0d80432c79 72 void wc_FreeDsaKey(DsaKey* key)
wolfSSL 4:1b0d80432c79 73 {
wolfSSL 4:1b0d80432c79 74 (void)key;
wolfSSL 4:1b0d80432c79 75 /* TomsFastMath doesn't use memory allocation */
wolfSSL 4:1b0d80432c79 76 #ifndef USE_FAST_MATH
wolfSSL 4:1b0d80432c79 77 if (key->type == DSA_PRIVATE)
wolfSSL 4:1b0d80432c79 78 mp_clear(&key->x);
wolfSSL 4:1b0d80432c79 79 mp_clear(&key->y);
wolfSSL 4:1b0d80432c79 80 mp_clear(&key->g);
wolfSSL 4:1b0d80432c79 81 mp_clear(&key->q);
wolfSSL 4:1b0d80432c79 82 mp_clear(&key->p);
wolfSSL 4:1b0d80432c79 83 #endif
wolfSSL 4:1b0d80432c79 84 }
wolfSSL 4:1b0d80432c79 85
wolfSSL 4:1b0d80432c79 86 #ifdef WOLFSSL_KEY_GEN
wolfSSL 4:1b0d80432c79 87
wolfSSL 4:1b0d80432c79 88 int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)
wolfSSL 4:1b0d80432c79 89 {
wolfSSL 4:1b0d80432c79 90 unsigned char *buf;
wolfSSL 4:1b0d80432c79 91 int qsize, err;
wolfSSL 4:1b0d80432c79 92
wolfSSL 4:1b0d80432c79 93 if (rng == NULL || dsa == NULL)
wolfSSL 4:1b0d80432c79 94 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 95
wolfSSL 4:1b0d80432c79 96 qsize = mp_unsigned_bin_size(&dsa->q);
wolfSSL 4:1b0d80432c79 97 if (qsize == 0)
wolfSSL 4:1b0d80432c79 98 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 99
wolfSSL 4:1b0d80432c79 100 /* allocate ram */
wolfSSL 4:1b0d80432c79 101 buf = (unsigned char *)XMALLOC(qsize, NULL,
wolfSSL 4:1b0d80432c79 102 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 103 if (buf == NULL)
wolfSSL 4:1b0d80432c79 104 return MEMORY_E;
wolfSSL 4:1b0d80432c79 105
wolfSSL 4:1b0d80432c79 106 if (mp_init(&dsa->x) != MP_OKAY) {
wolfSSL 4:1b0d80432c79 107 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 108 return MP_INIT_E;
wolfSSL 4:1b0d80432c79 109 }
wolfSSL 4:1b0d80432c79 110
wolfSSL 4:1b0d80432c79 111 do {
wolfSSL 4:1b0d80432c79 112 /* make a random exponent mod q */
wolfSSL 4:1b0d80432c79 113 err = wc_RNG_GenerateBlock(rng, buf, qsize);
wolfSSL 4:1b0d80432c79 114 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 115 mp_clear(&dsa->x);
wolfSSL 4:1b0d80432c79 116 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 117 return err;
wolfSSL 4:1b0d80432c79 118 }
wolfSSL 4:1b0d80432c79 119
wolfSSL 4:1b0d80432c79 120 err = mp_read_unsigned_bin(&dsa->x, buf, qsize);
wolfSSL 4:1b0d80432c79 121 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 122 mp_clear(&dsa->x);
wolfSSL 4:1b0d80432c79 123 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 124 return err;
wolfSSL 4:1b0d80432c79 125 }
wolfSSL 4:1b0d80432c79 126 } while (mp_cmp_d(&dsa->x, 1) != MP_GT);
wolfSSL 4:1b0d80432c79 127
wolfSSL 4:1b0d80432c79 128 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 129
wolfSSL 4:1b0d80432c79 130 if (mp_init(&dsa->y) != MP_OKAY) {
wolfSSL 4:1b0d80432c79 131 mp_clear(&dsa->x);
wolfSSL 4:1b0d80432c79 132 return MP_INIT_E;
wolfSSL 4:1b0d80432c79 133 }
wolfSSL 4:1b0d80432c79 134
wolfSSL 4:1b0d80432c79 135 /* public key : y = g^x mod p */
wolfSSL 4:1b0d80432c79 136 err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y);
wolfSSL 4:1b0d80432c79 137 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 138 mp_clear(&dsa->x);
wolfSSL 4:1b0d80432c79 139 mp_clear(&dsa->y);
wolfSSL 4:1b0d80432c79 140 return err;
wolfSSL 4:1b0d80432c79 141 }
wolfSSL 4:1b0d80432c79 142
wolfSSL 4:1b0d80432c79 143 dsa->type = DSA_PRIVATE;
wolfSSL 4:1b0d80432c79 144
wolfSSL 4:1b0d80432c79 145 return MP_OKAY;
wolfSSL 4:1b0d80432c79 146 }
wolfSSL 4:1b0d80432c79 147
wolfSSL 4:1b0d80432c79 148 /* modulus_size in bits */
wolfSSL 4:1b0d80432c79 149 int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa)
wolfSSL 4:1b0d80432c79 150 {
wolfSSL 4:1b0d80432c79 151 mp_int tmp, tmp2;
wolfSSL 4:1b0d80432c79 152 int err, msize, qsize,
wolfSSL 4:1b0d80432c79 153 loop_check_prime = 0,
wolfSSL 4:1b0d80432c79 154 check_prime = MP_NO;
wolfSSL 4:1b0d80432c79 155 unsigned char *buf;
wolfSSL 4:1b0d80432c79 156
wolfSSL 4:1b0d80432c79 157 if (rng == NULL || dsa == NULL)
wolfSSL 4:1b0d80432c79 158 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 159
wolfSSL 4:1b0d80432c79 160 /* set group size in bytes from modulus size
wolfSSL 4:1b0d80432c79 161 * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
wolfSSL 4:1b0d80432c79 162 */
wolfSSL 4:1b0d80432c79 163 switch (modulus_size) {
wolfSSL 4:1b0d80432c79 164 case 1024:
wolfSSL 4:1b0d80432c79 165 qsize = 20;
wolfSSL 4:1b0d80432c79 166 break;
wolfSSL 4:1b0d80432c79 167 case 2048:
wolfSSL 4:1b0d80432c79 168 case 3072:
wolfSSL 4:1b0d80432c79 169 qsize = 32;
wolfSSL 4:1b0d80432c79 170 break;
wolfSSL 4:1b0d80432c79 171 default:
wolfSSL 4:1b0d80432c79 172 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 173 break;
wolfSSL 4:1b0d80432c79 174 }
wolfSSL 4:1b0d80432c79 175
wolfSSL 4:1b0d80432c79 176 /* modulus size in bytes */
wolfSSL 4:1b0d80432c79 177 msize = modulus_size / 8;
wolfSSL 4:1b0d80432c79 178
wolfSSL 4:1b0d80432c79 179 /* allocate ram */
wolfSSL 4:1b0d80432c79 180 buf = (unsigned char *)XMALLOC(msize - qsize,
wolfSSL 4:1b0d80432c79 181 NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 182 if (buf == NULL) {
wolfSSL 4:1b0d80432c79 183 return MEMORY_E;
wolfSSL 4:1b0d80432c79 184 }
wolfSSL 4:1b0d80432c79 185
wolfSSL 4:1b0d80432c79 186 /* make a random string that will be multplied against q */
wolfSSL 4:1b0d80432c79 187 err = wc_RNG_GenerateBlock(rng, buf, msize - qsize);
wolfSSL 4:1b0d80432c79 188 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 189 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 190 return err;
wolfSSL 4:1b0d80432c79 191 }
wolfSSL 4:1b0d80432c79 192
wolfSSL 4:1b0d80432c79 193 /* force magnitude */
wolfSSL 4:1b0d80432c79 194 buf[0] |= 0xC0;
wolfSSL 4:1b0d80432c79 195
wolfSSL 4:1b0d80432c79 196 /* force even */
wolfSSL 4:1b0d80432c79 197 buf[msize - qsize - 1] &= ~1;
wolfSSL 4:1b0d80432c79 198
wolfSSL 4:1b0d80432c79 199 if (mp_init_multi(&tmp2, &dsa->p, &dsa->q, 0, 0, 0) != MP_OKAY) {
wolfSSL 4:1b0d80432c79 200 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 201 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 202 return MP_INIT_E;
wolfSSL 4:1b0d80432c79 203 }
wolfSSL 4:1b0d80432c79 204
wolfSSL 4:1b0d80432c79 205 err = mp_read_unsigned_bin(&tmp2, buf, msize - qsize);
wolfSSL 4:1b0d80432c79 206 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 207 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 208 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 209 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 210 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 211 return err;
wolfSSL 4:1b0d80432c79 212 }
wolfSSL 4:1b0d80432c79 213 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 4:1b0d80432c79 214
wolfSSL 4:1b0d80432c79 215 /* make our prime q */
wolfSSL 4:1b0d80432c79 216 err = mp_rand_prime(&dsa->q, qsize, rng, NULL);
wolfSSL 4:1b0d80432c79 217 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 218 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 219 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 220 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 221 return err;
wolfSSL 4:1b0d80432c79 222 }
wolfSSL 4:1b0d80432c79 223
wolfSSL 4:1b0d80432c79 224 /* p = random * q */
wolfSSL 4:1b0d80432c79 225 err = mp_mul(&dsa->q, &tmp2, &dsa->p);
wolfSSL 4:1b0d80432c79 226 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 227 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 228 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 229 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 230 return err;
wolfSSL 4:1b0d80432c79 231 }
wolfSSL 4:1b0d80432c79 232
wolfSSL 4:1b0d80432c79 233 /* p = random * q + 1, so q is a prime divisor of p-1 */
wolfSSL 4:1b0d80432c79 234 err = mp_add_d(&dsa->p, 1, &dsa->p);
wolfSSL 4:1b0d80432c79 235 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 236 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 237 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 238 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 239 return err;
wolfSSL 4:1b0d80432c79 240 }
wolfSSL 4:1b0d80432c79 241
wolfSSL 4:1b0d80432c79 242 if (mp_init(&tmp) != MP_OKAY) {
wolfSSL 4:1b0d80432c79 243 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 244 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 245 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 246 return MP_INIT_E;
wolfSSL 4:1b0d80432c79 247 }
wolfSSL 4:1b0d80432c79 248
wolfSSL 4:1b0d80432c79 249 /* tmp = 2q */
wolfSSL 4:1b0d80432c79 250 err = mp_add(&dsa->q, &dsa->q, &tmp);
wolfSSL 4:1b0d80432c79 251 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 252 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 253 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 254 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 255 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 256 return err;
wolfSSL 4:1b0d80432c79 257 }
wolfSSL 4:1b0d80432c79 258
wolfSSL 4:1b0d80432c79 259 /* loop until p is prime */
wolfSSL 4:1b0d80432c79 260 while (check_prime == MP_NO) {
wolfSSL 4:1b0d80432c79 261 err = mp_prime_is_prime(&dsa->p, 8, &check_prime);
wolfSSL 4:1b0d80432c79 262 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 263 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 264 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 265 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 266 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 267 return err;
wolfSSL 4:1b0d80432c79 268 }
wolfSSL 4:1b0d80432c79 269
wolfSSL 4:1b0d80432c79 270 if (check_prime != MP_YES) {
wolfSSL 4:1b0d80432c79 271 /* p += 2q */
wolfSSL 4:1b0d80432c79 272 err = mp_add(&tmp, &dsa->p, &dsa->p);
wolfSSL 4:1b0d80432c79 273 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 274 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 275 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 276 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 277 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 278 return err;
wolfSSL 4:1b0d80432c79 279 }
wolfSSL 4:1b0d80432c79 280
wolfSSL 4:1b0d80432c79 281 loop_check_prime++;
wolfSSL 4:1b0d80432c79 282 }
wolfSSL 4:1b0d80432c79 283 }
wolfSSL 4:1b0d80432c79 284
wolfSSL 4:1b0d80432c79 285 /* tmp2 += (2*loop_check_prime)
wolfSSL 4:1b0d80432c79 286 * to have p = (q * tmp2) + 1 prime
wolfSSL 4:1b0d80432c79 287 */
wolfSSL 4:1b0d80432c79 288 if (loop_check_prime) {
wolfSSL 4:1b0d80432c79 289 err = mp_add_d(&tmp2, 2*loop_check_prime, &tmp2);
wolfSSL 4:1b0d80432c79 290 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 291 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 292 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 293 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 294 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 295 return err;
wolfSSL 4:1b0d80432c79 296 }
wolfSSL 4:1b0d80432c79 297 }
wolfSSL 4:1b0d80432c79 298
wolfSSL 4:1b0d80432c79 299 if (mp_init(&dsa->g) != MP_OKAY) {
wolfSSL 4:1b0d80432c79 300 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 301 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 302 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 303 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 304 return MP_INIT_E;
wolfSSL 4:1b0d80432c79 305 }
wolfSSL 4:1b0d80432c79 306
wolfSSL 4:1b0d80432c79 307 /* find a value g for which g^tmp2 != 1 */
wolfSSL 4:1b0d80432c79 308 mp_set(&dsa->g, 1);
wolfSSL 4:1b0d80432c79 309
wolfSSL 4:1b0d80432c79 310 do {
wolfSSL 4:1b0d80432c79 311 err = mp_add_d(&dsa->g, 1, &dsa->g);
wolfSSL 4:1b0d80432c79 312 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 313 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 314 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 315 mp_clear(&dsa->g);
wolfSSL 4:1b0d80432c79 316 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 317 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 318 return err;
wolfSSL 4:1b0d80432c79 319 }
wolfSSL 4:1b0d80432c79 320
wolfSSL 4:1b0d80432c79 321 err = mp_exptmod(&dsa->g, &tmp2, &dsa->p, &tmp);
wolfSSL 4:1b0d80432c79 322 if (err != MP_OKAY) {
wolfSSL 4:1b0d80432c79 323 mp_clear(&dsa->q);
wolfSSL 4:1b0d80432c79 324 mp_clear(&dsa->p);
wolfSSL 4:1b0d80432c79 325 mp_clear(&dsa->g);
wolfSSL 4:1b0d80432c79 326 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 327 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 328 return err;
wolfSSL 4:1b0d80432c79 329 }
wolfSSL 4:1b0d80432c79 330
wolfSSL 4:1b0d80432c79 331 } while (mp_cmp_d(&tmp, 1) == MP_EQ);
wolfSSL 4:1b0d80432c79 332
wolfSSL 4:1b0d80432c79 333 /* at this point tmp generates a group of order q mod p */
wolfSSL 4:1b0d80432c79 334 mp_exch(&tmp, &dsa->g);
wolfSSL 4:1b0d80432c79 335
wolfSSL 4:1b0d80432c79 336 mp_clear(&tmp);
wolfSSL 4:1b0d80432c79 337 mp_clear(&tmp2);
wolfSSL 4:1b0d80432c79 338
wolfSSL 4:1b0d80432c79 339 return MP_OKAY;
wolfSSL 4:1b0d80432c79 340 }
wolfSSL 4:1b0d80432c79 341 #endif /* WOLFSSL_KEY_GEN */
wolfSSL 4:1b0d80432c79 342
wolfSSL 4:1b0d80432c79 343
wolfSSL 4:1b0d80432c79 344 int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
wolfSSL 4:1b0d80432c79 345 {
wolfSSL 4:1b0d80432c79 346 mp_int k, kInv, r, s, H;
wolfSSL 4:1b0d80432c79 347 int ret, sz;
wolfSSL 4:1b0d80432c79 348 byte buffer[DSA_HALF_SIZE];
wolfSSL 4:1b0d80432c79 349
wolfSSL 4:1b0d80432c79 350 sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q));
wolfSSL 4:1b0d80432c79 351
wolfSSL 4:1b0d80432c79 352 /* generate k */
wolfSSL 4:1b0d80432c79 353 ret = wc_RNG_GenerateBlock(rng, buffer, sz);
wolfSSL 4:1b0d80432c79 354 if (ret != 0)
wolfSSL 4:1b0d80432c79 355 return ret;
wolfSSL 4:1b0d80432c79 356
wolfSSL 4:1b0d80432c79 357 buffer[0] |= 0x0C;
wolfSSL 4:1b0d80432c79 358
wolfSSL 4:1b0d80432c79 359 if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)
wolfSSL 4:1b0d80432c79 360 return MP_INIT_E;
wolfSSL 4:1b0d80432c79 361
wolfSSL 4:1b0d80432c79 362 if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
wolfSSL 4:1b0d80432c79 363 ret = MP_READ_E;
wolfSSL 4:1b0d80432c79 364
wolfSSL 4:1b0d80432c79 365 if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT)
wolfSSL 4:1b0d80432c79 366 ret = MP_CMP_E;
wolfSSL 4:1b0d80432c79 367
wolfSSL 4:1b0d80432c79 368 /* inverse k mod q */
wolfSSL 4:1b0d80432c79 369 if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
wolfSSL 4:1b0d80432c79 370 ret = MP_INVMOD_E;
wolfSSL 4:1b0d80432c79 371
wolfSSL 4:1b0d80432c79 372 /* generate r, r = (g exp k mod p) mod q */
wolfSSL 4:1b0d80432c79 373 if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY)
wolfSSL 4:1b0d80432c79 374 ret = MP_EXPTMOD_E;
wolfSSL 4:1b0d80432c79 375
wolfSSL 4:1b0d80432c79 376 if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
wolfSSL 4:1b0d80432c79 377 ret = MP_MOD_E;
wolfSSL 4:1b0d80432c79 378
wolfSSL 4:1b0d80432c79 379 /* generate H from sha digest */
wolfSSL 4:1b0d80432c79 380 if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY)
wolfSSL 4:1b0d80432c79 381 ret = MP_READ_E;
wolfSSL 4:1b0d80432c79 382
wolfSSL 4:1b0d80432c79 383 /* generate s, s = (kInv * (H + x*r)) % q */
wolfSSL 4:1b0d80432c79 384 if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
wolfSSL 4:1b0d80432c79 385 ret = MP_MUL_E;
wolfSSL 4:1b0d80432c79 386
wolfSSL 4:1b0d80432c79 387 if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
wolfSSL 4:1b0d80432c79 388 ret = MP_ADD_E;
wolfSSL 4:1b0d80432c79 389
wolfSSL 4:1b0d80432c79 390 if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
wolfSSL 4:1b0d80432c79 391 ret = MP_MULMOD_E;
wolfSSL 4:1b0d80432c79 392
wolfSSL 4:1b0d80432c79 393 /* write out */
wolfSSL 4:1b0d80432c79 394 if (ret == 0) {
wolfSSL 4:1b0d80432c79 395 int rSz = mp_unsigned_bin_size(&r);
wolfSSL 4:1b0d80432c79 396 int sSz = mp_unsigned_bin_size(&s);
wolfSSL 4:1b0d80432c79 397
wolfSSL 4:1b0d80432c79 398 if (rSz == DSA_HALF_SIZE - 1) {
wolfSSL 4:1b0d80432c79 399 out[0] = 0;
wolfSSL 4:1b0d80432c79 400 out++;
wolfSSL 4:1b0d80432c79 401 }
wolfSSL 4:1b0d80432c79 402
wolfSSL 4:1b0d80432c79 403 if (mp_to_unsigned_bin(&r, out) != MP_OKAY)
wolfSSL 4:1b0d80432c79 404 ret = MP_TO_E;
wolfSSL 4:1b0d80432c79 405 else {
wolfSSL 4:1b0d80432c79 406 if (sSz == DSA_HALF_SIZE - 1) {
wolfSSL 4:1b0d80432c79 407 out[rSz] = 0;
wolfSSL 4:1b0d80432c79 408 out++;
wolfSSL 4:1b0d80432c79 409 }
wolfSSL 4:1b0d80432c79 410 ret = mp_to_unsigned_bin(&s, out + rSz);
wolfSSL 4:1b0d80432c79 411 }
wolfSSL 4:1b0d80432c79 412 }
wolfSSL 4:1b0d80432c79 413
wolfSSL 4:1b0d80432c79 414 mp_clear(&H);
wolfSSL 4:1b0d80432c79 415 mp_clear(&s);
wolfSSL 4:1b0d80432c79 416 mp_clear(&r);
wolfSSL 4:1b0d80432c79 417 mp_clear(&kInv);
wolfSSL 4:1b0d80432c79 418 mp_clear(&k);
wolfSSL 4:1b0d80432c79 419
wolfSSL 4:1b0d80432c79 420 return ret;
wolfSSL 4:1b0d80432c79 421 }
wolfSSL 4:1b0d80432c79 422
wolfSSL 4:1b0d80432c79 423
wolfSSL 4:1b0d80432c79 424 int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
wolfSSL 4:1b0d80432c79 425 {
wolfSSL 4:1b0d80432c79 426 mp_int w, u1, u2, v, r, s;
wolfSSL 4:1b0d80432c79 427 int ret = 0;
wolfSSL 4:1b0d80432c79 428
wolfSSL 4:1b0d80432c79 429 if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY)
wolfSSL 4:1b0d80432c79 430 return MP_INIT_E;
wolfSSL 4:1b0d80432c79 431
wolfSSL 4:1b0d80432c79 432 /* set r and s from signature */
wolfSSL 4:1b0d80432c79 433 if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY ||
wolfSSL 4:1b0d80432c79 434 mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY)
wolfSSL 4:1b0d80432c79 435 ret = MP_READ_E;
wolfSSL 4:1b0d80432c79 436
wolfSSL 4:1b0d80432c79 437 /* sanity checks */
wolfSSL 4:1b0d80432c79 438 if (ret == 0) {
wolfSSL 4:1b0d80432c79 439 if (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES ||
wolfSSL 4:1b0d80432c79 440 mp_cmp(&r, &key->q) != MP_LT || mp_cmp(&s, &key->q) != MP_LT) {
wolfSSL 4:1b0d80432c79 441 ret = MP_ZERO_E;
wolfSSL 4:1b0d80432c79 442 }
wolfSSL 4:1b0d80432c79 443 }
wolfSSL 4:1b0d80432c79 444
wolfSSL 4:1b0d80432c79 445 /* put H into u1 from sha digest */
wolfSSL 4:1b0d80432c79 446 if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY)
wolfSSL 4:1b0d80432c79 447 ret = MP_READ_E;
wolfSSL 4:1b0d80432c79 448
wolfSSL 4:1b0d80432c79 449 /* w = s invmod q */
wolfSSL 4:1b0d80432c79 450 if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY)
wolfSSL 4:1b0d80432c79 451 ret = MP_INVMOD_E;
wolfSSL 4:1b0d80432c79 452
wolfSSL 4:1b0d80432c79 453 /* u1 = (H * w) % q */
wolfSSL 4:1b0d80432c79 454 if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY)
wolfSSL 4:1b0d80432c79 455 ret = MP_MULMOD_E;
wolfSSL 4:1b0d80432c79 456
wolfSSL 4:1b0d80432c79 457 /* u2 = (r * w) % q */
wolfSSL 4:1b0d80432c79 458 if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY)
wolfSSL 4:1b0d80432c79 459 ret = MP_MULMOD_E;
wolfSSL 4:1b0d80432c79 460
wolfSSL 4:1b0d80432c79 461 /* verify v = ((g^u1 * y^u2) mod p) mod q */
wolfSSL 4:1b0d80432c79 462 if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY)
wolfSSL 4:1b0d80432c79 463 ret = MP_EXPTMOD_E;
wolfSSL 4:1b0d80432c79 464
wolfSSL 4:1b0d80432c79 465 if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY)
wolfSSL 4:1b0d80432c79 466 ret = MP_EXPTMOD_E;
wolfSSL 4:1b0d80432c79 467
wolfSSL 4:1b0d80432c79 468 if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY)
wolfSSL 4:1b0d80432c79 469 ret = MP_MULMOD_E;
wolfSSL 4:1b0d80432c79 470
wolfSSL 4:1b0d80432c79 471 if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY)
wolfSSL 4:1b0d80432c79 472 ret = MP_MULMOD_E;
wolfSSL 4:1b0d80432c79 473
wolfSSL 4:1b0d80432c79 474 /* do they match */
wolfSSL 4:1b0d80432c79 475 if (ret == 0 && mp_cmp(&r, &v) == MP_EQ)
wolfSSL 4:1b0d80432c79 476 *answer = 1;
wolfSSL 4:1b0d80432c79 477 else
wolfSSL 4:1b0d80432c79 478 *answer = 0;
wolfSSL 4:1b0d80432c79 479
wolfSSL 4:1b0d80432c79 480 mp_clear(&s);
wolfSSL 4:1b0d80432c79 481 mp_clear(&r);
wolfSSL 4:1b0d80432c79 482 mp_clear(&u1);
wolfSSL 4:1b0d80432c79 483 mp_clear(&u2);
wolfSSL 4:1b0d80432c79 484 mp_clear(&w);
wolfSSL 4:1b0d80432c79 485 mp_clear(&v);
wolfSSL 4:1b0d80432c79 486
wolfSSL 4:1b0d80432c79 487 return ret;
wolfSSL 4:1b0d80432c79 488 }
wolfSSL 4:1b0d80432c79 489
wolfSSL 4:1b0d80432c79 490
wolfSSL 4:1b0d80432c79 491 #endif /* NO_DSA */
wolfSSL 4:1b0d80432c79 492
wolfSSL 4:1b0d80432c79 493