source: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfcrypt/src/dsa.c@ 464

Last change on this file since 464 was 464, checked in by coas-nagasima, 3 years ago

WolfSSLとAzure IoT SDKを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 29.5 KB
Line 
1/* dsa.c
2 *
3 * Copyright (C) 2006-2020 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22
23#ifdef HAVE_CONFIG_H
24 #include <config.h>
25#endif
26
27#include <wolfssl/wolfcrypt/settings.h>
28
29#ifndef NO_DSA
30
31#include <wolfssl/wolfcrypt/random.h>
32#include <wolfssl/wolfcrypt/integer.h>
33#include <wolfssl/wolfcrypt/error-crypt.h>
34#include <wolfssl/wolfcrypt/logging.h>
35#include <wolfssl/wolfcrypt/sha.h>
36#include <wolfssl/wolfcrypt/dsa.h>
37
38#ifdef NO_INLINE
39 #include <wolfssl/wolfcrypt/misc.h>
40#else
41 #define WOLFSSL_MISC_INCLUDED
42 #include <wolfcrypt/src/misc.c>
43#endif
44
45#ifdef _MSC_VER
46 /* disable for while(0) cases (MSVC bug) */
47 #pragma warning(disable:4127)
48#endif
49
50int wc_InitDsaKey(DsaKey* key)
51{
52 if (key == NULL)
53 return BAD_FUNC_ARG;
54
55 key->type = -1; /* haven't decided yet */
56 key->heap = NULL;
57
58 return mp_init_multi(
59 /* public alloc parts */
60 &key->p,
61 &key->q,
62 &key->g,
63 &key->y,
64
65 /* private alloc parts */
66 &key->x,
67 NULL
68 );
69}
70
71
72int wc_InitDsaKey_h(DsaKey* key, void* h)
73{
74 int ret = wc_InitDsaKey(key);
75 if (ret == 0)
76 key->heap = h;
77
78 return ret;
79}
80
81
82void wc_FreeDsaKey(DsaKey* key)
83{
84 if (key == NULL)
85 return;
86
87 if (key->type == DSA_PRIVATE)
88 mp_forcezero(&key->x);
89
90 mp_clear(&key->x);
91 mp_clear(&key->y);
92 mp_clear(&key->g);
93 mp_clear(&key->q);
94 mp_clear(&key->p);
95}
96
97
98/* validate that (L,N) match allowed sizes from FIPS 186-4, Section 4.2.
99 * modLen - represents L, the size of p (prime modulus) in bits
100 * divLen - represents N, the size of q (prime divisor) in bits
101 * return 0 on success, -1 on error */
102static int CheckDsaLN(int modLen, int divLen)
103{
104 int ret = -1;
105
106 switch (modLen) {
107 case 1024:
108 if (divLen == 160)
109 ret = 0;
110 break;
111 case 2048:
112 if (divLen == 224 || divLen == 256)
113 ret = 0;
114 break;
115 case 3072:
116 if (divLen == 256)
117 ret = 0;
118 break;
119 default:
120 break;
121 }
122
123 return ret;
124}
125
126
127#ifdef WOLFSSL_KEY_GEN
128
129/* Create DSA key pair (&dsa->x, &dsa->y)
130 *
131 * Based on NIST FIPS 186-4,
132 * "B.1.1 Key Pair Generation Using Extra Random Bits"
133 *
134 * rng - pointer to initialized WC_RNG structure
135 * dsa - pointer to initialized DsaKey structure, will hold generated key
136 *
137 * return 0 on success, negative on error */
138int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)
139{
140 byte* cBuf;
141 int qSz, pSz, cSz, err;
142 mp_int tmpQ;
143
144 if (rng == NULL || dsa == NULL)
145 return BAD_FUNC_ARG;
146
147 qSz = mp_unsigned_bin_size(&dsa->q);
148 pSz = mp_unsigned_bin_size(&dsa->p);
149
150 /* verify (L,N) pair bit lengths */
151 if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0)
152 return BAD_FUNC_ARG;
153
154 /* generate extra 64 bits so that bias from mod function is negligible */
155 cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
156 cBuf = (byte*)XMALLOC(cSz, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
157 if (cBuf == NULL) {
158 return MEMORY_E;
159 }
160
161 if ((err = mp_init_multi(&dsa->x, &dsa->y, &tmpQ, NULL, NULL, NULL))
162 != MP_OKAY) {
163 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
164 return err;
165 }
166
167 do {
168 /* generate N+64 bits (c) from RBG into &dsa->x, making sure positive.
169 * Hash_DRBG uses SHA-256 which matches maximum
170 * requested_security_strength of (L,N) */
171 err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
172 if (err != MP_OKAY) {
173 mp_clear(&dsa->x);
174 mp_clear(&dsa->y);
175 mp_clear(&tmpQ);
176 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
177 return err;
178 }
179
180 err = mp_read_unsigned_bin(&dsa->x, cBuf, cSz);
181 if (err != MP_OKAY) {
182 mp_clear(&dsa->x);
183 mp_clear(&dsa->y);
184 mp_clear(&tmpQ);
185 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
186 return err;
187 }
188 } while (mp_cmp_d(&dsa->x, 1) != MP_GT);
189
190 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
191
192 /* tmpQ = q - 1 */
193 if (err == MP_OKAY)
194 err = mp_copy(&dsa->q, &tmpQ);
195
196 if (err == MP_OKAY)
197 err = mp_sub_d(&tmpQ, 1, &tmpQ);
198
199 /* x = c mod (q-1), &dsa->x holds c */
200 if (err == MP_OKAY)
201 err = mp_mod(&dsa->x, &tmpQ, &dsa->x);
202
203 /* x = c mod (q-1) + 1 */
204 if (err == MP_OKAY)
205 err = mp_add_d(&dsa->x, 1, &dsa->x);
206
207 /* public key : y = g^x mod p */
208 if (err == MP_OKAY)
209 err = mp_exptmod_ex(&dsa->g, &dsa->x, dsa->q.used, &dsa->p, &dsa->y);
210
211 if (err == MP_OKAY)
212 dsa->type = DSA_PRIVATE;
213
214 if (err != MP_OKAY) {
215 mp_clear(&dsa->x);
216 mp_clear(&dsa->y);
217 }
218 mp_clear(&tmpQ);
219
220 return err;
221}
222
223
224/* modulus_size in bits */
225int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa)
226{
227 mp_int tmp, tmp2;
228 int err, msize, qsize,
229 loop_check_prime = 0,
230 check_prime = MP_NO;
231 unsigned char *buf;
232
233 if (rng == NULL || dsa == NULL)
234 return BAD_FUNC_ARG;
235
236 /* set group size in bytes from modulus size
237 * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
238 */
239 switch (modulus_size) {
240 case 1024:
241 qsize = 20;
242 break;
243 case 2048:
244 case 3072:
245 qsize = 32;
246 break;
247 default:
248 return BAD_FUNC_ARG;
249 }
250
251 /* modulus size in bytes */
252 msize = modulus_size / WOLFSSL_BIT_SIZE;
253
254 /* allocate ram */
255 buf = (unsigned char *)XMALLOC(msize - qsize,
256 dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
257 if (buf == NULL) {
258 return MEMORY_E;
259 }
260
261 /* make a random string that will be multiplied against q */
262 err = wc_RNG_GenerateBlock(rng, buf, msize - qsize);
263 if (err != MP_OKAY) {
264 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
265 return err;
266 }
267
268 /* force magnitude */
269 buf[0] |= 0xC0;
270
271 /* force even */
272 buf[msize - qsize - 1] &= ~1;
273
274 if (mp_init_multi(&tmp2, &dsa->p, &dsa->q, 0, 0, 0) != MP_OKAY) {
275 mp_clear(&dsa->q);
276 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
277 return MP_INIT_E;
278 }
279
280 err = mp_read_unsigned_bin(&tmp2, buf, msize - qsize);
281 if (err != MP_OKAY) {
282 mp_clear(&dsa->q);
283 mp_clear(&dsa->p);
284 mp_clear(&tmp2);
285 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
286 return err;
287 }
288 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
289
290 /* make our prime q */
291 err = mp_rand_prime(&dsa->q, qsize, rng, NULL);
292 if (err != MP_OKAY) {
293 mp_clear(&dsa->q);
294 mp_clear(&dsa->p);
295 mp_clear(&tmp2);
296 return err;
297 }
298
299 /* p = random * q */
300 err = mp_mul(&dsa->q, &tmp2, &dsa->p);
301 if (err != MP_OKAY) {
302 mp_clear(&dsa->q);
303 mp_clear(&dsa->p);
304 mp_clear(&tmp2);
305 return err;
306 }
307
308 /* p = random * q + 1, so q is a prime divisor of p-1 */
309 err = mp_add_d(&dsa->p, 1, &dsa->p);
310 if (err != MP_OKAY) {
311 mp_clear(&dsa->q);
312 mp_clear(&dsa->p);
313 mp_clear(&tmp2);
314 return err;
315 }
316
317 if (mp_init(&tmp) != MP_OKAY) {
318 mp_clear(&dsa->q);
319 mp_clear(&dsa->p);
320 mp_clear(&tmp2);
321 return MP_INIT_E;
322 }
323
324 /* tmp = 2q */
325 err = mp_add(&dsa->q, &dsa->q, &tmp);
326 if (err != MP_OKAY) {
327 mp_clear(&dsa->q);
328 mp_clear(&dsa->p);
329 mp_clear(&tmp);
330 mp_clear(&tmp2);
331 return err;
332 }
333
334 /* loop until p is prime */
335 while (check_prime == MP_NO) {
336 err = mp_prime_is_prime_ex(&dsa->p, 8, &check_prime, rng);
337 if (err != MP_OKAY) {
338 mp_clear(&dsa->q);
339 mp_clear(&dsa->p);
340 mp_clear(&tmp);
341 mp_clear(&tmp2);
342 return err;
343 }
344
345 if (check_prime != MP_YES) {
346 /* p += 2q */
347 err = mp_add(&tmp, &dsa->p, &dsa->p);
348 if (err != MP_OKAY) {
349 mp_clear(&dsa->q);
350 mp_clear(&dsa->p);
351 mp_clear(&tmp);
352 mp_clear(&tmp2);
353 return err;
354 }
355
356 loop_check_prime++;
357 }
358 }
359
360 /* tmp2 += (2*loop_check_prime)
361 * to have p = (q * tmp2) + 1 prime
362 */
363 if (loop_check_prime) {
364 err = mp_add_d(&tmp2, 2*loop_check_prime, &tmp2);
365 if (err != MP_OKAY) {
366 mp_clear(&dsa->q);
367 mp_clear(&dsa->p);
368 mp_clear(&tmp);
369 mp_clear(&tmp2);
370 return err;
371 }
372 }
373
374 if (mp_init(&dsa->g) != MP_OKAY) {
375 mp_clear(&dsa->q);
376 mp_clear(&dsa->p);
377 mp_clear(&tmp);
378 mp_clear(&tmp2);
379 return MP_INIT_E;
380 }
381
382 /* find a value g for which g^tmp2 != 1 */
383 if (mp_set(&dsa->g, 1) != MP_OKAY) {
384 mp_clear(&dsa->q);
385 mp_clear(&dsa->p);
386 mp_clear(&tmp);
387 mp_clear(&tmp2);
388 return MP_INIT_E;
389 }
390
391 do {
392 err = mp_add_d(&dsa->g, 1, &dsa->g);
393 if (err != MP_OKAY) {
394 mp_clear(&dsa->q);
395 mp_clear(&dsa->p);
396 mp_clear(&dsa->g);
397 mp_clear(&tmp);
398 mp_clear(&tmp2);
399 return err;
400 }
401
402 err = mp_exptmod(&dsa->g, &tmp2, &dsa->p, &tmp);
403 if (err != MP_OKAY) {
404 mp_clear(&dsa->q);
405 mp_clear(&dsa->p);
406 mp_clear(&dsa->g);
407 mp_clear(&tmp);
408 mp_clear(&tmp2);
409 return err;
410 }
411
412 } while (mp_cmp_d(&tmp, 1) == MP_EQ);
413
414 /* at this point tmp generates a group of order q mod p */
415#ifndef USE_FAST_MATH
416 /* Exchanging is quick when the data pointer can be copied. */
417 mp_exch(&tmp, &dsa->g);
418#else
419 mp_copy(&tmp, &dsa->g);
420#endif
421
422 mp_clear(&tmp);
423 mp_clear(&tmp2);
424
425 return MP_OKAY;
426}
427#endif /* WOLFSSL_KEY_GEN */
428
429
430static int _DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,
431 const char* g, int trusted, WC_RNG* rng)
432{
433 int err;
434 word32 pSz, qSz;
435
436 if (dsa == NULL || p == NULL || q == NULL || g == NULL)
437 return BAD_FUNC_ARG;
438
439 /* read p */
440 err = mp_read_radix(&dsa->p, p, MP_RADIX_HEX);
441 if (err == MP_OKAY && !trusted) {
442 int isPrime = 1;
443 if (rng == NULL)
444 err = mp_prime_is_prime(&dsa->p, 8, &isPrime);
445 else
446 err = mp_prime_is_prime_ex(&dsa->p, 8, &isPrime, rng);
447
448 if (err == MP_OKAY) {
449 if (!isPrime)
450 err = DH_CHECK_PUB_E;
451 }
452 }
453
454 /* read q */
455 if (err == MP_OKAY)
456 err = mp_read_radix(&dsa->q, q, MP_RADIX_HEX);
457
458 /* read g */
459 if (err == MP_OKAY)
460 err = mp_read_radix(&dsa->g, g, MP_RADIX_HEX);
461
462 /* verify (L,N) pair bit lengths */
463 pSz = mp_unsigned_bin_size(&dsa->p);
464 qSz = mp_unsigned_bin_size(&dsa->q);
465
466 if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
467 WOLFSSL_MSG("Invalid DSA p or q parameter size");
468 err = BAD_FUNC_ARG;
469 }
470
471 if (err != MP_OKAY) {
472 mp_clear(&dsa->p);
473 mp_clear(&dsa->q);
474 mp_clear(&dsa->g);
475 }
476
477 return err;
478}
479
480
481/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),
482 * input parameters (p,q,g) should be represented as ASCII hex values.
483 *
484 * dsa - pointer to initialized DsaKey structure
485 * p - DSA (p) parameter, ASCII hex string
486 * pSz - length of p
487 * q - DSA (q) parameter, ASCII hex string
488 * qSz - length of q
489 * g - DSA (g) parameter, ASCII hex string
490 * gSz - length of g
491 *
492 * returns 0 on success, negative upon failure
493 */
494int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,
495 const char* g)
496{
497 return _DsaImportParamsRaw(dsa, p, q, g, 1, NULL);
498}
499
500
501/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),
502 * input parameters (p,q,g) should be represented as ASCII hex values. Check
503 * that the p value is probably prime.
504 *
505 * dsa - pointer to initialized DsaKey structure
506 * p - DSA (p) parameter, ASCII hex string
507 * pSz - length of p
508 * q - DSA (q) parameter, ASCII hex string
509 * qSz - length of q
510 * g - DSA (g) parameter, ASCII hex string
511 * gSz - length of g
512 * trusted - trust that p is OK
513 * rng - random number generator for the prime test
514 *
515 * returns 0 on success, negative upon failure
516 */
517int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, const char* q,
518 const char* g, int trusted, WC_RNG* rng)
519{
520 return _DsaImportParamsRaw(dsa, p, q, g, trusted, rng);
521}
522
523
524/* Export raw DSA parameters from DsaKey structure
525 *
526 * dsa - pointer to initialized DsaKey structure
527 * p - output location for DSA (p) parameter
528 * pSz - [IN/OUT] size of output buffer for p, size of p
529 * q - output location for DSA (q) parameter
530 * qSz - [IN/OUT] size of output buffer for q, size of q
531 * g - output location for DSA (g) parameter
532 * gSz - [IN/OUT] size of output buffer for g, size of g
533 *
534 * If p, q, and g pointers are all passed in as NULL, the function
535 * will set pSz, qSz, and gSz to the required output buffer sizes for p,
536 * q, and g. In this case, the function will return LENGTH_ONLY_E.
537 *
538 * returns 0 on success, negative upon failure
539 */
540int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz,
541 byte* q, word32* qSz, byte* g, word32* gSz)
542{
543 int err;
544 word32 pLen, qLen, gLen;
545
546 if (dsa == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
547 return BAD_FUNC_ARG;
548
549 /* get required output buffer sizes */
550 pLen = mp_unsigned_bin_size(&dsa->p);
551 qLen = mp_unsigned_bin_size(&dsa->q);
552 gLen = mp_unsigned_bin_size(&dsa->g);
553
554 /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
555 if (p == NULL && q == NULL && g == NULL) {
556 *pSz = pLen;
557 *qSz = qLen;
558 *gSz = gLen;
559 return LENGTH_ONLY_E;
560 }
561
562 if (p == NULL || q == NULL || g == NULL)
563 return BAD_FUNC_ARG;
564
565 /* export p */
566 if (*pSz < pLen) {
567 WOLFSSL_MSG("Output buffer for DSA p parameter too small, "
568 "required size placed into pSz");
569 *pSz = pLen;
570 return BUFFER_E;
571 }
572 *pSz = pLen;
573 err = mp_to_unsigned_bin(&dsa->p, p);
574
575 /* export q */
576 if (err == MP_OKAY) {
577 if (*qSz < qLen) {
578 WOLFSSL_MSG("Output buffer for DSA q parameter too small, "
579 "required size placed into qSz");
580 *qSz = qLen;
581 return BUFFER_E;
582 }
583 *qSz = qLen;
584 err = mp_to_unsigned_bin(&dsa->q, q);
585 }
586
587 /* export g */
588 if (err == MP_OKAY) {
589 if (*gSz < gLen) {
590 WOLFSSL_MSG("Output buffer for DSA g parameter too small, "
591 "required size placed into gSz");
592 *gSz = gLen;
593 return BUFFER_E;
594 }
595 *gSz = gLen;
596 err = mp_to_unsigned_bin(&dsa->g, g);
597 }
598
599 return err;
600}
601
602
603/* Export raw DSA key (x, y) from DsaKey structure
604 *
605 * dsa - pointer to initialized DsaKey structure
606 * x - output location for private key
607 * xSz - [IN/OUT] size of output buffer for x, size of x
608 * y - output location for public key
609 * ySz - [IN/OUT] size of output buffer for y, size of y
610 *
611 * If x and y pointers are all passed in as NULL, the function
612 * will set xSz and ySz to the required output buffer sizes for x
613 * and y. In this case, the function will return LENGTH_ONLY_E.
614 *
615 * returns 0 on success, negative upon failure
616 */
617int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz)
618{
619 int err;
620 word32 xLen, yLen;
621
622 if (dsa == NULL || xSz == NULL || ySz == NULL)
623 return BAD_FUNC_ARG;
624
625 /* get required output buffer sizes */
626 xLen = mp_unsigned_bin_size(&dsa->x);
627 yLen = mp_unsigned_bin_size(&dsa->y);
628
629 /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
630 if (x == NULL && y == NULL) {
631 *xSz = xLen;
632 *ySz = yLen;
633 return LENGTH_ONLY_E;
634 }
635
636 if (x == NULL || y == NULL)
637 return BAD_FUNC_ARG;
638
639 /* export x */
640 if (*xSz < xLen) {
641 WOLFSSL_MSG("Output buffer for DSA private key (x) too small, "
642 "required size placed into xSz");
643 *xSz = xLen;
644 return BUFFER_E;
645 }
646 *xSz = xLen;
647 err = mp_to_unsigned_bin(&dsa->x, x);
648
649 /* export y */
650 if (err == MP_OKAY) {
651 if (*ySz < yLen) {
652 WOLFSSL_MSG("Output buffer to DSA public key (y) too small, "
653 "required size placed into ySz");
654 *ySz = yLen;
655 return BUFFER_E;
656 }
657 *ySz = yLen;
658 err = mp_to_unsigned_bin(&dsa->y, y);
659 }
660
661 return err;
662}
663
664
665int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
666{
667#ifdef WOLFSSL_SMALL_STACK
668 mp_int *k = (mp_int *)XMALLOC(sizeof *k,
669 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
670 mp_int *kInv = (mp_int *)XMALLOC(sizeof *kInv,
671 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
672 mp_int *r = (mp_int *)XMALLOC(sizeof *r,
673 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
674 mp_int *s = (mp_int *)XMALLOC(sizeof *s,
675 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
676 mp_int *H = (mp_int *)XMALLOC(sizeof *H,
677 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
678#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
679 mp_int *b = (mp_int *)XMALLOC(sizeof *b,
680 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
681#endif
682 byte *buffer = (byte *)XMALLOC(DSA_HALF_SIZE, key->heap,
683 DYNAMIC_TYPE_TMP_BUFFER);
684#else
685 mp_int k[1], kInv[1], r[1], s[1], H[1];
686#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
687 mp_int b[1];
688#endif
689 byte buffer[DSA_HALF_SIZE];
690#endif
691 mp_int* qMinus1;
692 int ret = 0, sz = 0;
693 byte* tmp; /* initial output pointer */
694
695 do {
696#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
697 if (mp_init_multi(k, kInv, r, s, H, 0) != MP_OKAY)
698#else
699 if (mp_init_multi(k, kInv, r, s, H, b) != MP_OKAY)
700#endif
701 {
702 ret = MP_INIT_E;
703 break;
704 }
705
706#ifdef WOLFSSL_SMALL_STACK
707 if ((k == NULL) ||
708 (kInv == NULL) ||
709 (r == NULL) ||
710 (s == NULL) ||
711 (H == NULL)
712#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
713 || (b == NULL)
714#endif
715 || (buffer == NULL)) {
716 ret = MEMORY_E;
717 break;
718 }
719#endif
720
721 if (digest == NULL || out == NULL || key == NULL || rng == NULL) {
722 ret = BAD_FUNC_ARG;
723 break;
724 }
725
726 sz = min(DSA_HALF_SIZE, mp_unsigned_bin_size(&key->q));
727 tmp = out;
728 qMinus1 = kInv;
729
730 /* NIST FIPS 186-4: B.2.2
731 * Per-Message Secret Number Generation by Testing Candidates
732 * Generate k in range [1, q-1].
733 * Check that k is less than q-1: range [0, q-2].
734 * Add 1 to k: range [1, q-1].
735 */
736 if (mp_sub_d(&key->q, 1, qMinus1)) {
737 ret = MP_SUB_E;
738 break;
739 }
740
741 do {
742 /* Step 4: generate k */
743 if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
744 break;
745 }
746
747 /* Step 5 */
748 if (mp_read_unsigned_bin(k, buffer, sz) != MP_OKAY) {
749 ret = MP_READ_E;
750 break;
751 }
752
753 /* k is a random numnber and it should be less than q-1
754 * if k greater than repeat
755 */
756 /* Step 6 */
757 } while (mp_cmp(k, qMinus1) != MP_LT);
758
759 if (ret != 0)
760 break;
761
762 /* Step 7 */
763 if (mp_add_d(k, 1, k) != MP_OKAY) {
764 ret = MP_MOD_E;
765 break;
766 }
767
768#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME
769 /* inverse k mod q */
770 if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
771 ret = MP_INVMOD_E;
772 break;
773 }
774
775 /* generate r, r = (g exp k mod p) mod q */
776 if (mp_exptmod_ex(&key->g, k, key->q.used, &key->p, r) != MP_OKAY) {
777 ret = MP_EXPTMOD_E;
778 break;
779 }
780
781 if (mp_mod(r, &key->q, r) != MP_OKAY) {
782 ret = MP_MOD_E;
783 break;
784 }
785
786 /* generate H from sha digest */
787 if (mp_read_unsigned_bin(H, digest,WC_SHA_DIGEST_SIZE) != MP_OKAY) {
788 ret = MP_READ_E;
789 break;
790 }
791
792 /* generate s, s = (kInv * (H + x*r)) % q */
793 if (mp_mul(&key->x, r, s) != MP_OKAY) {
794 ret = MP_MUL_E;
795 break;
796 }
797
798 if (mp_add(s, H, s) != MP_OKAY) {
799 ret = MP_ADD_E;
800 break;
801 }
802
803 if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
804 ret = MP_MULMOD_E;
805 break;
806 }
807#else
808 /* Blinding value
809 * Generate b in range [1, q-1].
810 */
811 do {
812 if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) {
813 break;
814 }
815 if (mp_read_unsigned_bin(b, buffer, sz) != MP_OKAY) {
816 ret = MP_READ_E;
817 break;
818 }
819 } while (mp_cmp(b, qMinus1) != MP_LT);
820
821 if (ret != 0)
822 break;
823
824 if (mp_add_d(b, 1, b) != MP_OKAY) {
825 ret = MP_MOD_E;
826 break;
827 }
828
829 /* set H from sha digest */
830 if (mp_read_unsigned_bin(H, digest, WC_SHA_DIGEST_SIZE) != MP_OKAY) {
831 ret = MP_READ_E;
832 break;
833 }
834
835 /* generate r, r = (g exp k mod p) mod q */
836 if (mp_exptmod_ex(&key->g, k, key->q.used, &key->p, r) != MP_OKAY) {
837 ret = MP_EXPTMOD_E;
838 break;
839 }
840
841 /* calculate s = (H + xr)/k = b.(H/k.b + x.r/k.b) */
842
843 /* k = k.b */
844 if (mp_mulmod(k, b, &key->q, k) != MP_OKAY) {
845 ret = MP_MULMOD_E;
846 break;
847 }
848
849 /* kInv = 1/k.b mod q */
850 if (mp_invmod(k, &key->q, kInv) != MP_OKAY) {
851 ret = MP_INVMOD_E;
852 break;
853 }
854
855 if (mp_mod(r, &key->q, r) != MP_OKAY) {
856 ret = MP_MOD_E;
857 break;
858 }
859
860 /* s = x.r */
861 if (mp_mul(&key->x, r, s) != MP_OKAY) {
862 ret = MP_MUL_E;
863 break;
864 }
865
866 /* s = x.r/k.b */
867 if (mp_mulmod(s, kInv, &key->q, s) != MP_OKAY) {
868 ret = MP_MULMOD_E;
869 break;
870 }
871
872 /* H = H/k.b */
873 if (mp_mulmod(H, kInv, &key->q, H) != MP_OKAY) {
874 ret = MP_MULMOD_E;
875 break;
876 }
877
878 /* s = H/k.b + x.r/k.b = (H + x.r)/k.b */
879 if (mp_add(s, H, s) != MP_OKAY) {
880 ret = MP_ADD_E;
881 break;
882 }
883
884 /* s = b.(e + x.r)/k.b = (e + x.r)/k */
885 if (mp_mulmod(s, b, &key->q, s) != MP_OKAY) {
886 ret = MP_MULMOD_E;
887 break;
888 }
889
890 /* s = (e + x.r)/k */
891 if (mp_mod(s, &key->q, s) != MP_OKAY) {
892 ret = MP_MOD_E;
893 break;
894 }
895#endif
896
897 /* detect zero r or s */
898 if ((mp_iszero(r) == MP_YES) || (mp_iszero(s) == MP_YES)) {
899 ret = MP_ZERO_E;
900 break;
901 }
902
903 /* write out */
904 {
905 int rSz = mp_unsigned_bin_size(r);
906 int sSz = mp_unsigned_bin_size(s);
907
908 while (rSz++ < DSA_HALF_SIZE) {
909 *out++ = 0x00; /* pad front with zeros */
910 }
911
912 if (mp_to_unsigned_bin(r, out) != MP_OKAY)
913 ret = MP_TO_E;
914 else {
915 out = tmp + DSA_HALF_SIZE; /* advance to s in output */
916 while (sSz++ < DSA_HALF_SIZE) {
917 *out++ = 0x00; /* pad front with zeros */
918 }
919 ret = mp_to_unsigned_bin(s, out);
920 }
921 }
922 } while (0);
923
924#ifdef WOLFSSL_SMALL_STACK
925 if (k) {
926 if (ret != MP_INIT_E)
927 mp_forcezero(k);
928 XFREE(k, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
929 }
930 if (kInv) {
931 if (ret != MP_INIT_E)
932 mp_forcezero(kInv);
933 XFREE(kInv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
934 }
935 if (r) {
936 if (ret != MP_INIT_E)
937 mp_clear(r);
938 XFREE(r, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
939 }
940 if (s) {
941 if (ret != MP_INIT_E)
942 mp_clear(s);
943 XFREE(s, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
944 }
945 if (H) {
946 if (ret != MP_INIT_E)
947 mp_clear(H);
948 XFREE(H, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
949 }
950#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
951 if (b) {
952 if (ret != MP_INIT_E)
953 mp_forcezero(b);
954 XFREE(b, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
955 }
956#endif
957 if (buffer) {
958 ForceZero(buffer, sz);
959 XFREE(buffer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
960 }
961#else /* !WOLFSSL_SMALL_STACK */
962 if (ret != MP_INIT_E) {
963 ForceZero(buffer, sz);
964 mp_forcezero(kInv);
965 mp_forcezero(k);
966#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME
967 mp_forcezero(b);
968#endif
969 mp_clear(H);
970 mp_clear(s);
971 mp_clear(r);
972 }
973#endif
974
975 return ret;
976}
977
978
979int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
980{
981#ifdef WOLFSSL_SMALL_STACK
982 mp_int *w = (mp_int *)XMALLOC(sizeof *w,
983 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
984 mp_int *u1 = (mp_int *)XMALLOC(sizeof *u1,
985 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
986 mp_int *u2 = (mp_int *)XMALLOC(sizeof *u2,
987 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
988 mp_int *v = (mp_int *)XMALLOC(sizeof *v,
989 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
990 mp_int *r = (mp_int *)XMALLOC(sizeof *r,
991 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
992 mp_int *s = (mp_int *)XMALLOC(sizeof *s,
993 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
994#else
995 mp_int w[1], u1[1], u2[1], v[1], r[1], s[1];
996#endif
997 int ret = 0;
998
999 do {
1000 if (mp_init_multi(w, u1, u2, v, r, s) != MP_OKAY) {
1001 ret = MP_INIT_E;
1002 break;
1003 }
1004
1005 if (digest == NULL || sig == NULL || key == NULL || answer == NULL) {
1006 ret = BAD_FUNC_ARG;
1007 break;
1008 }
1009
1010#ifdef WOLFSSL_SMALL_STACK
1011 if ((w == NULL) ||
1012 (u1 == NULL) ||
1013 (u2 == NULL) ||
1014 (v == NULL) ||
1015 (r == NULL) ||
1016 (s == NULL)) {
1017 ret = MEMORY_E;
1018 break;
1019 }
1020#endif
1021
1022 /* set r and s from signature */
1023 if (mp_read_unsigned_bin(r, sig, DSA_HALF_SIZE) != MP_OKAY ||
1024 mp_read_unsigned_bin(s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) {
1025 ret = MP_READ_E;
1026 break;
1027 }
1028
1029 /* sanity checks */
1030 if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
1031 mp_cmp(r, &key->q) != MP_LT || mp_cmp(s, &key->q) != MP_LT) {
1032 ret = MP_ZERO_E;
1033 break;
1034 }
1035
1036 /* put H into u1 from sha digest */
1037 if (mp_read_unsigned_bin(u1,digest,WC_SHA_DIGEST_SIZE) != MP_OKAY) {
1038 ret = MP_READ_E;
1039 break;
1040 }
1041
1042 /* w = s invmod q */
1043 if (mp_invmod(s, &key->q, w) != MP_OKAY) {
1044 ret = MP_INVMOD_E;
1045 break;
1046 }
1047
1048 /* u1 = (H * w) % q */
1049 if (mp_mulmod(u1, w, &key->q, u1) != MP_OKAY) {
1050 ret = MP_MULMOD_E;
1051 break;
1052 }
1053
1054 /* u2 = (r * w) % q */
1055 if (mp_mulmod(r, w, &key->q, u2) != MP_OKAY) {
1056 ret = MP_MULMOD_E;
1057 break;
1058 }
1059
1060 /* verify v = ((g^u1 * y^u2) mod p) mod q */
1061 if (mp_exptmod(&key->g, u1, &key->p, u1) != MP_OKAY) {
1062 ret = MP_EXPTMOD_E;
1063 break;
1064 }
1065
1066 if (mp_exptmod(&key->y, u2, &key->p, u2) != MP_OKAY) {
1067 ret = MP_EXPTMOD_E;
1068 break;
1069 }
1070
1071 if (mp_mulmod(u1, u2, &key->p, v) != MP_OKAY) {
1072 ret = MP_MULMOD_E;
1073 break;
1074 }
1075
1076 if (mp_mod(v, &key->q, v) != MP_OKAY) {
1077 ret = MP_MULMOD_E;
1078 break;
1079 }
1080
1081 /* do they match */
1082 if (mp_cmp(r, v) == MP_EQ)
1083 *answer = 1;
1084 else
1085 *answer = 0;
1086 } while (0);
1087
1088#ifdef WOLFSSL_SMALL_STACK
1089 if (s) {
1090 if (ret != MP_INIT_E)
1091 mp_clear(s);
1092 XFREE(s, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1093 }
1094 if (r) {
1095 if (ret != MP_INIT_E)
1096 mp_clear(r);
1097 XFREE(r, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1098 }
1099 if (u1) {
1100 if (ret != MP_INIT_E)
1101 mp_clear(u1);
1102 XFREE(u1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1103 }
1104 if (u2) {
1105 if (ret != MP_INIT_E)
1106 mp_clear(u2);
1107 XFREE(u2, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1108 }
1109 if (w) {
1110 if (ret != MP_INIT_E)
1111 mp_clear(w);
1112 XFREE(w, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1113 }
1114 if (v) {
1115 if (ret != MP_INIT_E)
1116 mp_clear(v);
1117 XFREE(v, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1118 }
1119#else
1120 if (ret != MP_INIT_E) {
1121 mp_clear(s);
1122 mp_clear(r);
1123 mp_clear(u1);
1124 mp_clear(u2);
1125 mp_clear(w);
1126 mp_clear(v);
1127 }
1128#endif
1129
1130 return ret;
1131}
1132
1133
1134#endif /* NO_DSA */
1135
Note: See TracBrowser for help on using the repository browser.