- Timestamp:
- Feb 7, 2019, 8:36:33 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/dsa.c
r352 r372 98 98 } 99 99 100 101 /* validate that (L,N) match allowed sizes from FIPS 186-4, Section 4.2. 102 * modLen - represents L, the size of p (prime modulus) in bits 103 * divLen - represents N, the size of q (prime divisor) in bits 104 * return 0 on success, -1 on error */ 105 static int CheckDsaLN(int modLen, int divLen) 106 { 107 int ret = -1; 108 109 switch (modLen) { 110 case 1024: 111 if (divLen == 160) 112 ret = 0; 113 break; 114 case 2048: 115 if (divLen == 224 || divLen == 256) 116 ret = 0; 117 break; 118 case 3072: 119 if (divLen == 256) 120 ret = 0; 121 break; 122 default: 123 break; 124 } 125 126 return ret; 127 } 128 129 100 130 #ifdef WOLFSSL_KEY_GEN 101 131 132 /* Create DSA key pair (&dsa->x, &dsa->y) 133 * 134 * Based on NIST FIPS 186-4, 135 * "B.1.1 Key Pair Generation Using Extra Random Bits" 136 * 137 * rng - pointer to initialized WC_RNG structure 138 * dsa - pointer to initialized DsaKey structure, will hold generated key 139 * 140 * return 0 on success, negative on error */ 102 141 int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa) 103 142 { 104 unsigned char *buf; 105 int qsize, err; 143 byte* cBuf; 144 int qSz, pSz, cSz, err; 145 mp_int tmpQ; 106 146 107 147 if (rng == NULL || dsa == NULL) 108 148 return BAD_FUNC_ARG; 109 149 110 qsize = mp_unsigned_bin_size(&dsa->q); 111 if (qsize == 0) 112 return BAD_FUNC_ARG; 113 114 /* allocate ram */ 115 buf = (unsigned char *)XMALLOC(qsize, dsa->heap, 116 DYNAMIC_TYPE_TMP_BUFFER); 117 if (buf == NULL) 150 qSz = mp_unsigned_bin_size(&dsa->q); 151 pSz = mp_unsigned_bin_size(&dsa->p); 152 153 /* verify (L,N) pair bit lengths */ 154 if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) 155 return BAD_FUNC_ARG; 156 157 /* generate extra 64 bits so that bias from mod function is negligible */ 158 cSz = qSz + (64 / WOLFSSL_BIT_SIZE); 159 cBuf = (byte*)XMALLOC(cSz, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 160 if (cBuf == NULL) { 118 161 return MEMORY_E; 119 120 if (mp_init(&dsa->x) != MP_OKAY) { 121 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 122 return MP_INIT_E; 162 } 163 164 if ((err = mp_init_multi(&dsa->x, &dsa->y, &tmpQ, NULL, NULL, NULL)) 165 != MP_OKAY) { 166 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 167 return err; 123 168 } 124 169 125 170 do { 126 /* make a random exponent mod q */ 127 err = wc_RNG_GenerateBlock(rng, buf, qsize); 171 /* generate N+64 bits (c) from RBG into &dsa->x, making sure positive. 172 * Hash_DRBG uses SHA-256 which matches maximum 173 * requested_security_strength of (L,N) */ 174 err = wc_RNG_GenerateBlock(rng, cBuf, cSz); 128 175 if (err != MP_OKAY) { 129 176 mp_clear(&dsa->x); 130 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 177 mp_clear(&dsa->y); 178 mp_clear(&tmpQ); 179 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 131 180 return err; 132 181 } 133 182 134 err = mp_read_unsigned_bin(&dsa->x, buf, qsize);183 err = mp_read_unsigned_bin(&dsa->x, cBuf, cSz); 135 184 if (err != MP_OKAY) { 136 185 mp_clear(&dsa->x); 137 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 186 mp_clear(&dsa->y); 187 mp_clear(&tmpQ); 188 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 138 189 return err; 139 190 } 140 191 } while (mp_cmp_d(&dsa->x, 1) != MP_GT); 141 192 142 XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 143 144 if (mp_init(&dsa->y) != MP_OKAY) { 145 mp_clear(&dsa->x); 146 return MP_INIT_E; 147 } 193 XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER); 194 195 /* tmpQ = q - 1 */ 196 if (err == MP_OKAY) 197 err = mp_copy(&dsa->q, &tmpQ); 198 199 if (err == MP_OKAY) 200 err = mp_sub_d(&tmpQ, 1, &tmpQ); 201 202 /* x = c mod (q-1), &dsa->x holds c */ 203 if (err == MP_OKAY) 204 err = mp_mod(&dsa->x, &tmpQ, &dsa->x); 205 206 /* x = c mod (q-1) + 1 */ 207 if (err == MP_OKAY) 208 err = mp_add_d(&dsa->x, 1, &dsa->x); 148 209 149 210 /* public key : y = g^x mod p */ 211 if (err == MP_OKAY) 150 212 err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y); 213 214 if (err == MP_OKAY) 215 dsa->type = DSA_PRIVATE; 216 151 217 if (err != MP_OKAY) { 152 218 mp_clear(&dsa->x); 153 219 mp_clear(&dsa->y); 154 return err; 155 } 156 157 dsa->type = DSA_PRIVATE; 158 159 return MP_OKAY; 160 } 220 } 221 mp_clear(&tmpQ); 222 223 return err; 224 } 225 161 226 162 227 /* modulus_size in bits */ … … 185 250 default: 186 251 return BAD_FUNC_ARG; 187 break;188 252 } 189 253 190 254 /* modulus size in bytes */ 191 msize = modulus_size / 8;255 msize = modulus_size / WOLFSSL_BIT_SIZE; 192 256 193 257 /* allocate ram */ … … 273 337 /* loop until p is prime */ 274 338 while (check_prime == MP_NO) { 275 err = mp_prime_is_prime (&dsa->p, 8, &check_prime);339 err = mp_prime_is_prime_ex(&dsa->p, 8, &check_prime, rng); 276 340 if (err != MP_OKAY) { 277 341 mp_clear(&dsa->q); … … 362 426 363 427 428 static int _DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, 429 const char* g, int trusted, WC_RNG* rng) 430 { 431 int err; 432 word32 pSz, qSz; 433 434 if (dsa == NULL || p == NULL || q == NULL || g == NULL) 435 return BAD_FUNC_ARG; 436 437 /* read p */ 438 err = mp_read_radix(&dsa->p, p, MP_RADIX_HEX); 439 if (err == MP_OKAY && !trusted) { 440 int isPrime = 1; 441 if (rng == NULL) 442 err = mp_prime_is_prime(&dsa->p, 8, &isPrime); 443 else 444 err = mp_prime_is_prime_ex(&dsa->p, 8, &isPrime, rng); 445 446 if (err == MP_OKAY) { 447 if (!isPrime) 448 err = DH_CHECK_PUB_E; 449 } 450 } 451 452 /* read q */ 453 if (err == MP_OKAY) 454 err = mp_read_radix(&dsa->q, q, MP_RADIX_HEX); 455 456 /* read g */ 457 if (err == MP_OKAY) 458 err = mp_read_radix(&dsa->g, g, MP_RADIX_HEX); 459 460 /* verify (L,N) pair bit lengths */ 461 pSz = mp_unsigned_bin_size(&dsa->p); 462 qSz = mp_unsigned_bin_size(&dsa->q); 463 464 if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) { 465 WOLFSSL_MSG("Invalid DSA p or q parameter size"); 466 err = BAD_FUNC_ARG; 467 } 468 469 if (err != MP_OKAY) { 470 mp_clear(&dsa->p); 471 mp_clear(&dsa->q); 472 mp_clear(&dsa->g); 473 } 474 475 return err; 476 } 477 478 479 /* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(), 480 * input parameters (p,q,g) should be represented as ASCII hex values. 481 * 482 * dsa - pointer to initialized DsaKey structure 483 * p - DSA (p) parameter, ASCII hex string 484 * pSz - length of p 485 * q - DSA (q) parameter, ASCII hex string 486 * qSz - length of q 487 * g - DSA (g) parameter, ASCII hex string 488 * gSz - length of g 489 * 490 * returns 0 on success, negative upon failure 491 */ 492 int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, 493 const char* g) 494 { 495 return _DsaImportParamsRaw(dsa, p, q, g, 1, NULL); 496 } 497 498 499 /* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(), 500 * input parameters (p,q,g) should be represented as ASCII hex values. Check 501 * that the p value is probably prime. 502 * 503 * dsa - pointer to initialized DsaKey structure 504 * p - DSA (p) parameter, ASCII hex string 505 * pSz - length of p 506 * q - DSA (q) parameter, ASCII hex string 507 * qSz - length of q 508 * g - DSA (g) parameter, ASCII hex string 509 * gSz - length of g 510 * trusted - trust that p is OK 511 * rng - random number generator for the prime test 512 * 513 * returns 0 on success, negative upon failure 514 */ 515 int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, const char* q, 516 const char* g, int trusted, WC_RNG* rng) 517 { 518 return _DsaImportParamsRaw(dsa, p, q, g, trusted, rng); 519 } 520 521 522 /* Export raw DSA parameters from DsaKey structure 523 * 524 * dsa - pointer to initialized DsaKey structure 525 * p - output location for DSA (p) parameter 526 * pSz - [IN/OUT] size of output buffer for p, size of p 527 * q - output location for DSA (q) parameter 528 * qSz - [IN/OUT] size of output buffer for q, size of q 529 * g - output location for DSA (g) parameter 530 * gSz - [IN/OUT] size of output buffer for g, size of g 531 * 532 * If p, q, and g pointers are all passed in as NULL, the function 533 * will set pSz, qSz, and gSz to the required output buffer sizes for p, 534 * q, and g. In this case, the function will return LENGTH_ONLY_E. 535 * 536 * returns 0 on success, negative upon failure 537 */ 538 int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz, 539 byte* q, word32* qSz, byte* g, word32* gSz) 540 { 541 int err; 542 word32 pLen, qLen, gLen; 543 544 if (dsa == NULL || pSz == NULL || qSz == NULL || gSz == NULL) 545 return BAD_FUNC_ARG; 546 547 /* get required output buffer sizes */ 548 pLen = mp_unsigned_bin_size(&dsa->p); 549 qLen = mp_unsigned_bin_size(&dsa->q); 550 gLen = mp_unsigned_bin_size(&dsa->g); 551 552 /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */ 553 if (p == NULL && q == NULL && g == NULL) { 554 *pSz = pLen; 555 *qSz = qLen; 556 *gSz = gLen; 557 return LENGTH_ONLY_E; 558 } 559 560 if (p == NULL || q == NULL || g == NULL) 561 return BAD_FUNC_ARG; 562 563 /* export p */ 564 if (*pSz < pLen) { 565 WOLFSSL_MSG("Output buffer for DSA p parameter too small, " 566 "required size placed into pSz"); 567 *pSz = pLen; 568 return BUFFER_E; 569 } 570 *pSz = pLen; 571 err = mp_to_unsigned_bin(&dsa->p, p); 572 573 /* export q */ 574 if (err == MP_OKAY) { 575 if (*qSz < qLen) { 576 WOLFSSL_MSG("Output buffer for DSA q parameter too small, " 577 "required size placed into qSz"); 578 *qSz = qLen; 579 return BUFFER_E; 580 } 581 *qSz = qLen; 582 err = mp_to_unsigned_bin(&dsa->q, q); 583 } 584 585 /* export g */ 586 if (err == MP_OKAY) { 587 if (*gSz < gLen) { 588 WOLFSSL_MSG("Output buffer for DSA g parameter too small, " 589 "required size placed into gSz"); 590 *gSz = gLen; 591 return BUFFER_E; 592 } 593 *gSz = gLen; 594 err = mp_to_unsigned_bin(&dsa->g, g); 595 } 596 597 return err; 598 } 599 600 601 /* Export raw DSA key (x, y) from DsaKey structure 602 * 603 * dsa - pointer to initialized DsaKey structure 604 * x - output location for private key 605 * xSz - [IN/OUT] size of output buffer for x, size of x 606 * y - output location for public key 607 * ySz - [IN/OUT] size of output buffer for y, size of y 608 * 609 * If x and y pointers are all passed in as NULL, the function 610 * will set xSz and ySz to the required output buffer sizes for x 611 * and y. In this case, the function will return LENGTH_ONLY_E. 612 * 613 * returns 0 on success, negative upon failure 614 */ 615 int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz) 616 { 617 int err; 618 word32 xLen, yLen; 619 620 if (dsa == NULL || xSz == NULL || ySz == NULL) 621 return BAD_FUNC_ARG; 622 623 /* get required output buffer sizes */ 624 xLen = mp_unsigned_bin_size(&dsa->x); 625 yLen = mp_unsigned_bin_size(&dsa->y); 626 627 /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */ 628 if (x == NULL && y == NULL) { 629 *xSz = xLen; 630 *ySz = yLen; 631 return LENGTH_ONLY_E; 632 } 633 634 if (x == NULL || y == NULL) 635 return BAD_FUNC_ARG; 636 637 /* export x */ 638 if (*xSz < xLen) { 639 WOLFSSL_MSG("Output buffer for DSA private key (x) too small, " 640 "required size placed into xSz"); 641 *xSz = xLen; 642 return BUFFER_E; 643 } 644 *xSz = xLen; 645 err = mp_to_unsigned_bin(&dsa->x, x); 646 647 /* export y */ 648 if (err == MP_OKAY) { 649 if (*ySz < yLen) { 650 WOLFSSL_MSG("Output buffer to DSA public key (y) too small, " 651 "required size placed into ySz"); 652 *ySz = yLen; 653 return BUFFER_E; 654 } 655 *ySz = yLen; 656 err = mp_to_unsigned_bin(&dsa->y, y); 657 } 658 659 return err; 660 } 661 662 364 663 int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) 365 664 {
Note:
See TracChangeset
for help on using the changeset viewer.