1/* 2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include "ossl-config.h" 25 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <assert.h> 30 31#include "krb5-types.h" 32#include "rfc2459_asn1.h" 33 34#include "ossl-dsa.h" 35#include "ossl-common.h" 36 37#ifdef HAVE_COMMONCRYPTO_COMMONDSACRYPTOR_H 38 39/* 40 * CommonCrypto DSA/DSS shim 41 */ 42 43#if 0 44 45static int 46load_key(CSSM_CSP_HANDLE cspHandle, DSA *dsa, int use_public, CSSM_KEY_PTR key, size_t *keysize) 47{ 48 CSSM_KEY_SIZE keySize; 49 CSSM_RETURN ret; 50 size_t size; 51 52 memset(key, 0, sizeof(*key)); 53 54 if (use_public) { 55 DSAPublicKey k; 56 57 memset(&k, 0, sizeof(k)); 58 59 ret = _cs_BN_to_integer(rsa->n, &k.modulus); 60 if (ret == 0) { 61 ret = _cs_BN_to_integer(rsa->e, &k.publicExponent); 62 } 63 if (ret) { 64 free_RSAPublicKey(&k); 65 return (0); 66 } 67 68 ASN1_MALLOC_ENCODE(RSAPublicKey, key->KeyData.Data, key->KeyData.Length, 69 &k, &size, ret); 70 free_RSAPublicKey(&k); 71 if (ret) { 72 return (1); 73 } 74 if (size != key->KeyData.Length) { 75 abort(); 76 } 77 } else { 78 RSAPrivateKey k; 79 80 memset(&k, 0, sizeof(k)); 81 82 k.version = 1; 83 ret = _cs_BN_to_integer(rsa->n, &k.modulus); 84 if (ret == 0) { 85 ret = _cs_BN_to_integer(rsa->e, &k.publicExponent); 86 } 87 if (ret == 0) { 88 ret = _cs_BN_to_integer(rsa->d, &k.privateExponent); 89 } 90 if (ret == 0) { 91 ret = _cs_BN_to_integer(rsa->p, &k.prime1); 92 } 93 if (ret == 0) { 94 ret = _cs_BN_to_integer(rsa->q, &k.prime2); 95 } 96 if (ret == 0) { 97 ret = _cs_BN_to_integer(rsa->dmp1, &k.exponent1); 98 } 99 if (ret == 0) { 100 ret = _cs_BN_to_integer(rsa->dmq1, &k.exponent2); 101 } 102 if (ret == 0) { 103 ret = _cs_BN_to_integer(rsa->iqmp, &k.coefficient); 104 } 105 if (ret) { 106 free_RSAPrivateKey(&k); 107 return (1); 108 } 109 110 ASN1_MALLOC_ENCODE(RSAPrivateKey, key->KeyData.Data, key->KeyData.Length, 111 &k, &size, ret); 112 free_RSAPrivateKey(&k); 113 if (ret) { 114 return (1); 115 } 116 if (size != key->KeyData.Length) { 117 abort(); 118 } 119 } 120 121 key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; 122 key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW; 123 key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; 124 key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA; 125 key->KeyHeader.KeyClass = use_public ? 126 CSSM_KEYCLASS_PUBLIC_KEY : 127 CSSM_KEYCLASS_PRIVATE_KEY; 128 key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; 129 key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; 130 131 ret = CSSM_QueryKeySizeInBits(cspHandle, 0, key, &keySize); 132 if (ret) { 133 return (1); 134 } 135 136 key->KeyHeader.LogicalKeySizeInBits = keySize.LogicalKeySizeInBits; 137 138 *keysize = (keySize.LogicalKeySizeInBits + 7) / 8; 139 140 return (0); 141} 142 143 144static void 145unload_key(CSSM_KEY_PTR key) 146{ 147 free(key->KeyData.Data); 148 memset(key, 0, sizeof(*key)); 149} 150 151 152typedef CSSM_RETURN (*op)(CSSM_CC_HANDLE, const CSSM_DATA *, 153 uint32, CSSM_DATA_PTR, uint32, 154 CSSM_SIZE *, CSSM_DATA_PTR); 155 156 157static int 158perform_rsa_op(int flen, const unsigned char *from, 159 unsigned char *to, RSA *rsa, int padding, 160 CSSM_ENCRYPT_MODE algMode, op func) 161{ 162 CSSM_CSP_HANDLE cspHandle = _cs_get_cdsa_csphandle(); 163 CSSM_RETURN cret; 164 CSSM_ACCESS_CREDENTIALS creds; 165 CSSM_KEY cssmKey; 166 CSSM_CC_HANDLE handle = 0; 167 CSSM_DATA out, in, rem; 168 int fret = 0; 169 CSSM_SIZE outlen = 0; 170 char remdata[1024]; 171 size_t keysize; 172 173 if (padding != RSA_PKCS1_PADDING) { 174 return (-1); 175 } 176 177 memset(&creds, 0, sizeof(creds)); 178 179 fret = load_key(cspHandle, rsa, (algMode == CSSM_ALGMODE_PUBLIC_KEY), 180 &cssmKey, &keysize); 181 if (fret) { 182 return (-2); 183 } 184 185 fret = CSSM_CSP_CreateAsymmetricContext(cspHandle, 186 CSSM_ALGID_RSA, 187 &creds, 188 &cssmKey, 189 CSSM_PADDING_PKCS1, 190 &handle); 191 if (fret) { 192 abort(); 193 } 194 195 { 196 CSSM_CONTEXT_ATTRIBUTE attr; 197 198 attr.AttributeType = CSSM_ATTRIBUTE_MODE; 199 attr.AttributeLength = sizeof(attr.Attribute.Uint32); 200 attr.Attribute.Uint32 = algMode; 201 202 fret = CSSM_UpdateContextAttributes(handle, 1, &attr); 203 if (fret) { 204 abort(); 205 } 206 } 207 208 in.Data = (uint8 *)from; 209 in.Length = flen; 210 211 out.Data = (uint8 *)to; 212 out.Length = keysize; 213 214 rem.Data = (uint8 *)remdata; 215 rem.Length = sizeof(remdata); 216 217 cret = func(handle, &in, 1, &out, 1, &outlen, &rem); 218 if (cret) { 219 /* cssmErrorString(cret); */ 220 fret = -1; 221 } else{ 222 fret = outlen; 223 } 224 225 if (handle) { 226 CSSM_DeleteContext(handle); 227 } 228 unload_key(&cssmKey); 229 230 return (fret); 231} 232 233 234#endif /* #if 0 */ 235 236/* 237 * 238 */ 239 240#ifdef PR_10488503_FIXED 241 242/* CommonCrypto doesn't implement DSA/DSS. See <rdar://problem/10488503> */ 243 244#else 245 246#include "tommath.h" 247 248/* int dsa_make_key(CCRNGRef rng, int group_size, int modulus_size, dsa_key *key) */ 249static int 250cc_dsa_generate_key(DSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) 251{ 252 void *tmp, *tmp2; 253 int err, res; 254 unsigned char *buf; 255 256 LTC_ARGCHK(key != NULL); 257 LTC_ARGCHK(ltc_mp.name != NULL); 258 LTC_ARGCHK(rng != NULL); 259 260 261 /* check size */ 262 if ((group_size >= LTC_MDSA_MAX_GROUP) || (group_size <= 15) || 263 (group_size >= modulus_size) || ((modulus_size - group_size) >= LTC_MDSA_DELTA)) { 264 return (CRYPT_INVALID_ARG); 265 } 266 267 /* allocate ram */ 268 buf = CC_XMALLOC(LTC_MDSA_DELTA); 269 if (buf == NULL) { 270 return (CRYPT_MEM); 271 } 272 273 /* init mp_ints */ 274 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) { 275 CC_XFREE(buf, LTC_MDSA_DELTA); 276 return (err); 277 } 278 279 /* make our prime q */ 280 if ((err = rand_prime(key->q, group_size, rng)) != CRYPT_OK) { 281 goto error; 282 } 283 284 /* double q */ 285 if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { 286 goto error; 287 } 288 289 /* now make a random string and multply it against q */ 290 if (CCRNGGetBytes(rng, buf+1, modulus_size - group_size)) { 291 err = CRYPT_ERROR_READPRNG; 292 goto error; 293 } 294 295 /* force magnitude */ 296 buf[0] |= 0xC0; 297 298 /* force even */ 299 buf[modulus_size - group_size - 1] &= ~1; 300 301 if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { 302 goto error; 303 } 304 if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { 305 goto error; 306 } 307 if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { 308 goto error; 309 } 310 311 /* now loop until p is prime */ 312 for ( ; ; ) { 313 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { 314 goto error; 315 } 316 if (res == LTC_MP_YES) { 317 break; 318 } 319 320 /* add 2q to p and 2 to tmp2 */ 321 if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { 322 goto error; 323 } 324 if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { 325 goto error; 326 } 327 } 328 329 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ 330 mp_set(key->g, 1); 331 332 do { 333 if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { 334 goto error; 335 } 336 if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { 337 goto error; 338 } 339 } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ); 340 341 /* at this point tmp generates a group of order q mod p */ 342 mp_exch(tmp, key->g); 343 344 /* so now we have our DH structure, generator g, order q, modulus p 345 * Now we need a random exponent [mod q] and it's power g^x mod p 346 */ 347 do { 348 if (CCRNGGetBytes(rng, buf, group_size)) { 349 err = CRYPT_ERROR_READPRNG; 350 goto error; 351 } 352 if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK) { 353 goto error; 354 } 355 } while (mp_cmp_d(key->x, 1) != LTC_MP_GT); 356 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { 357 goto error; 358 } 359 360 key->type = PK_PRIVATE; 361 key->qord = group_size; 362 363#ifdef LTC_CLEAN_STACK 364 zeromem(buf, LTC_MDSA_DELTA); 365#endif 366 367 err = CRYPT_OK; 368 goto done; 369error: 370 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); 371done: 372 mp_clear_multi(tmp, tmp2, NULL); 373 CC_XFREE(buf, LTC_MDSA_DELTA); 374 return (err); 375} 376 377 378/** 379 * Sign a hash with DSA 380 * @param in The hash to sign 381 * @param inlen The length of the hash to sign 382 * @param r The "r" integer of the signature (caller must initialize with mp_init() first) 383 * @param s The "s" integer of the signature (caller must initialize with mp_init() first) 384 * @param prng An active PRNG state 385 * @param wprng The index of the PRNG desired 386 * @param key A private DSA key 387 * @return CRYPT_OK if successful 388 */ 389 390/* int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, 391 * void *r, void *s, 392 * CCRNGRef rng, dsa_key *key) */ 393static DSA_SIG * 394cc_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 395{ 396 void *k, *kinv, *tmp; 397 unsigned char *buf; 398 int err; 399 400 LTC_ARGCHK(in != NULL); 401 LTC_ARGCHK(r != NULL); 402 LTC_ARGCHK(s != NULL); 403 LTC_ARGCHK(key != NULL); 404 LTC_ARGCHK(rng != NULL); 405 406 if (key->type != PK_PRIVATE) { 407 return (CRYPT_PK_NOT_PRIVATE); 408 } 409 410 /* check group order size */ 411 if (key->qord >= LTC_MDSA_MAX_GROUP) { 412 return (CRYPT_INVALID_ARG); 413 } 414 415 buf = CC_XMALLOC(LTC_MDSA_MAX_GROUP); 416 if (buf == NULL) { 417 return (CRYPT_MEM); 418 } 419 420 /* Init our temps */ 421 if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { 422 goto ERRBUF; 423 } 424 425retry: 426 427 do { 428 /* gen random k */ 429 430 if (CCRNGGetBytes(rng, buf, key->qord)) { 431 err = CRYPT_ERROR_READPRNG; 432 goto error; 433 } 434 435 /* read k */ 436 if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { 437 goto error; 438 } 439 440 /* k > 1 ? */ 441 if (mp_cmp_d(k, 1) != LTC_MP_GT) { 442 goto retry; 443 } 444 445 /* test gcd */ 446 if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { 447 goto error; 448 } 449 } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ); 450 451 /* now find 1/k mod q */ 452 if ((err = mp_invmod(k, key->q, kinv)) != CRYPT_OK) { 453 goto error; 454 } 455 456 /* now find r = g^k mod p mod q */ 457 if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { 458 goto error; 459 } 460 if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { 461 goto error; 462 } 463 464 if (mp_iszero(r) == LTC_MP_YES) { 465 goto retry; 466 } 467 468 /* now find s = (in + xr)/k mod q */ 469 if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { 470 goto error; 471 } 472 if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { 473 goto error; 474 } 475 if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { 476 goto error; 477 } 478 if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { 479 goto error; 480 } 481 482 if (mp_iszero(s) == LTC_MP_YES) { 483 goto retry; 484 } 485 486 err = CRYPT_OK; 487error: 488 mp_clear_multi(k, kinv, tmp, NULL); 489ERRBUF: 490#ifdef LTC_CLEAN_STACK 491 zeromem(buf, LTC_MDSA_MAX_GROUP); 492#endif 493 CC_XFREE(buf, X); 494 return (err); 495} 496 497 498/** 499 * Sign a hash with DSA 500 * @param in The hash to sign 501 * @param inlen The length of the hash to sign 502 * @param out [out] Where to store the signature 503 * @param outlen [in/out] The max size and resulting size of the signature 504 * @param prng An active PRNG state 505 * @param wprng The index of the PRNG desired 506 * @param key A private DSA key 507 * @return CRYPT_OK if successful 508 */ 509 510/* 511 * int dsa_sign_hash(const unsigned char *in, unsigned long inlen, 512 * unsigned char *out, unsigned long *outlen, 513 * CCRNGRef rng, dsa_key *key) 514 */ 515static int 516cc_dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) 517{ 518 void *r, *s; 519 int err; 520 521 LTC_ARGCHK(in != NULL); 522 LTC_ARGCHK(out != NULL); 523 LTC_ARGCHK(outlen != NULL); 524 LTC_ARGCHK(key != NULL); 525 526 if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) { 527 return (CRYPT_MEM); 528 } 529 530 if ((err = dsa_sign_hash_raw(in, inlen, r, s, rng, key)) != CRYPT_OK) { 531 goto error; 532 } 533 534 err = der_encode_sequence_multi(out, outlen, 535 LTC_ASN1_INTEGER, 1UL, r, 536 LTC_ASN1_INTEGER, 1UL, s, 537 LTC_ASN1_EOL, 0UL, NULL); 538 539error: 540 mp_clear_multi(r, s, NULL); 541 return (err); 542} 543 544 545/** 546 * Verify a DSA signature 547 * @param r DSA "r" parameter 548 * @param s DSA "s" parameter 549 * @param hash The hash that was signed 550 * @param hashlen The length of the hash that was signed 551 * @param stat [out] The result of the signature verification, 1==valid, 0==invalid 552 * @param key The corresponding public DH key 553 * @return CRYPT_OK if successful (even if the signature is invalid) 554 */ 555 556/* 557 * int dsa_verify_hash_raw( void *r, void *s, 558 * const unsigned char *hash, unsigned long hashlen, 559 * int *stat, dsa_key *key) 560 */ 561static int 562cc_dsa_do_verify(const unsigned char *dgst, int dgst_len, 563 DSA_SIG *sig, DSA *dsa) 564{ 565 void *w, *v, *u1, *u2; 566 int err; 567 568 LTC_ARGCHK(r != NULL); 569 LTC_ARGCHK(s != NULL); 570 LTC_ARGCHK(stat != NULL); 571 LTC_ARGCHK(key != NULL); 572 573 /* default to invalid signature */ 574 *stat = 0; 575 576 /* init our variables */ 577 if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) { 578 return (err); 579 } 580 581 /* neither r or s can be null or >q*/ 582 if ((mp_iszero(r) == LTC_MP_YES) || (mp_iszero(s) == LTC_MP_YES) || (mp_cmp(r, key->q) != LTC_MP_LT) || (mp_cmp(s, key->q) != LTC_MP_LT)) { 583 err = CRYPT_INVALID_PACKET; 584 goto error; 585 } 586 587 /* w = 1/s mod q */ 588 if ((err = mp_invmod(s, key->q, w)) != CRYPT_OK) { 589 goto error; 590 } 591 592 /* u1 = m * w mod q */ 593 if ((err = mp_read_unsigned_bin(u1, (unsigned char *)hash, hashlen)) != CRYPT_OK) { 594 goto error; 595 } 596 if ((err = mp_mulmod(u1, w, key->q, u1)) != CRYPT_OK) { 597 goto error; 598 } 599 600 /* u2 = r*w mod q */ 601 if ((err = mp_mulmod(r, w, key->q, u2)) != CRYPT_OK) { 602 goto error; 603 } 604 605 /* v = g^u1 * y^u2 mod p mod q */ 606 if ((err = mp_exptmod(key->g, u1, key->p, u1)) != CRYPT_OK) { 607 goto error; 608 } 609 if ((err = mp_exptmod(key->y, u2, key->p, u2)) != CRYPT_OK) { 610 goto error; 611 } 612 if ((err = mp_mulmod(u1, u2, key->p, v)) != CRYPT_OK) { 613 goto error; 614 } 615 if ((err = mp_mod(v, key->q, v)) != CRYPT_OK) { 616 goto error; 617 } 618 619 /* if r = v then we're set */ 620 if (mp_cmp(r, v) == LTC_MP_EQ) { 621 *stat = 1; 622 } 623 624 err = CRYPT_OK; 625error: 626 mp_clear_multi(w, v, u1, u2, NULL); 627 return (err); 628} 629 630 631/** 632 * Verify a DSA signature 633 * @param sig The signature 634 * @param siglen The length of the signature (octets) 635 * @param hash The hash that was signed 636 * @param hashlen The length of the hash that was signed 637 * @param stat [out] The result of the signature verification, 1==valid, 0==invalid 638 * @param key The corresponding public DH key 639 * @return CRYPT_OK if successful (even if the signature is invalid) 640 */ 641 642/* 643 * int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, 644 * const unsigned char *hash, unsigned long hashlen, 645 * int *stat, dsa_key *key) 646 */ 647static int 648cc_dsa_verify(int type, const unsigned char *dgst, int len, 649 unsigned char *sigbuf, int siglen, DSA *dsa) 650{ 651 int err; 652 void *r, *s; 653 654 if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) { 655 return (CRYPT_MEM); 656 } 657 658 /* decode the sequence */ 659 if ((err = der_decode_sequence_multi(sig, siglen, 660 LTC_ASN1_INTEGER, 1UL, r, 661 LTC_ASN1_INTEGER, 1UL, s, 662 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { 663 goto LBL_ERR; 664 } 665 666 /* do the op */ 667 err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key); 668 669LBL_ERR: 670 mp_clear_multi(r, s, NULL); 671 return (err); 672} 673 674 675#endif /* PR_XXX_FIXED */ 676 677static int 678cc_dsa_init(DSA *dsa) 679{ 680 return (1); 681} 682 683 684static int 685cc_dsa_finish(DSA *dsa) 686{ 687 return (1); 688} 689 690 691static int 692cc_dsa_paramgen(DSA *dsa, int bits, unsigned char *seed, int seed_len, 693 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) 694{ 695 return (1); 696} 697 698 699static int 700cc_dsa_keygen(DSA *dsa) 701{ 702 return (1); 703} 704 705 706const DSA_METHOD _cs_dsa_cc_method = 707{ 708 .name = "CommonCrypto(LTC) DSA", 709 .dsa_do_sign = cc_dsa_do_sign, 710 .dsa_sign_setup = cc_dsa_sign_setup, 711 .dsa_do_verify = cc_dsa_do_verify, 712 .init = cdsa_dsa_init, 713 .finish = cdsa_dsa_finish, 714 0, 715 NULL, 716 .dsa_paramgen = cc_dsa_paramgen, 717 .dsa_keygen = cc_dsa_keygen 718}; 719#endif /* HAVE_COMMONCRYPTO_COMMONDSACRYPTOR_H */ 720 721const DSA_METHOD * 722DSA_cc_method(void) 723{ 724#ifdef HAVE_COMMONCRYPTO_COMMONDSACRYPTOR_H 725 return (&_cs_dsa_cc_method); 726 727#else 728 return (NULL); 729#endif /* HAVE_COMMONCRYPTO_COMMONDSACRYPTOR_H */ 730} 731