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