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#include <stdio.h>
27#include <stdlib.h>
28#include <assert.h>
29
30#include "krb5-types.h"
31#include "rfc2459_asn1.h"
32
33#include "ossl-dsa.h"
34#include "ossl-common.h"
35
36/* #include "rk-roken.h" */
37
38#ifdef HAVE_CDSA
39
40/*
41 *
42 */
43
44#if 0
45
46static int
47load_key(CSSM_CSP_HANDLE cspHandle, DSA *dsa, int use_public, CSSM_KEY_PTR key, size_t *keysize)
48{
49	CSSM_KEY_SIZE keySize;
50	CSSM_RETURN ret;
51	size_t size;
52
53	memset(key, 0, sizeof(*key));
54
55	if (use_public) {
56		DSAPublicKey k;
57
58		memset(&k, 0, sizeof(k));
59
60		ret = _cs_BN_to_integer(rsa->n, &k.modulus);
61		if (ret == 0) {
62			ret = _cs_BN_to_integer(rsa->e, &k.publicExponent);
63		}
64		if (ret) {
65			free_RSAPublicKey(&k);
66			return (0);
67		}
68
69		ASN1_MALLOC_ENCODE(RSAPublicKey, key->KeyData.Data, key->KeyData.Length,
70		    &k, &size, ret);
71		free_RSAPublicKey(&k);
72		if (ret) {
73			return (1);
74		}
75		if (size != key->KeyData.Length) {
76			abort();
77		}
78	} else {
79		RSAPrivateKey k;
80
81		memset(&k, 0, sizeof(k));
82
83		k.version = 1;
84		ret = _cs_BN_to_integer(rsa->n, &k.modulus);
85		if (ret == 0) {
86			ret = _cs_BN_to_integer(rsa->e, &k.publicExponent);
87		}
88		if (ret == 0) {
89			ret = _cs_BN_to_integer(rsa->d, &k.privateExponent);
90		}
91		if (ret == 0) {
92			ret = _cs_BN_to_integer(rsa->p, &k.prime1);
93		}
94		if (ret == 0) {
95			ret = _cs_BN_to_integer(rsa->q, &k.prime2);
96		}
97		if (ret == 0) {
98			ret = _cs_BN_to_integer(rsa->dmp1, &k.exponent1);
99		}
100		if (ret == 0) {
101			ret = _cs_BN_to_integer(rsa->dmq1, &k.exponent2);
102		}
103		if (ret == 0) {
104			ret = _cs_BN_to_integer(rsa->iqmp, &k.coefficient);
105		}
106		if (ret) {
107			free_RSAPrivateKey(&k);
108			return (1);
109		}
110
111		ASN1_MALLOC_ENCODE(RSAPrivateKey, key->KeyData.Data, key->KeyData.Length,
112		    &k, &size, ret);
113		free_RSAPrivateKey(&k);
114		if (ret) {
115			return (1);
116		}
117		if (size != key->KeyData.Length) {
118			abort();
119		}
120	}
121
122	key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
123	key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
124	key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
125	key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA;
126	key->KeyHeader.KeyClass = use_public ?
127	    CSSM_KEYCLASS_PUBLIC_KEY :
128	    CSSM_KEYCLASS_PRIVATE_KEY;
129	key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
130	key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
131
132	ret = CSSM_QueryKeySizeInBits(cspHandle, 0, key, &keySize);
133	if (ret) {
134		return (1);
135	}
136
137	key->KeyHeader.LogicalKeySizeInBits = keySize.LogicalKeySizeInBits;
138
139	*keysize = (keySize.LogicalKeySizeInBits + 7) / 8;
140
141	return (0);
142}
143
144
145static void
146unload_key(CSSM_KEY_PTR key)
147{
148	free(key->KeyData.Data);
149	memset(key, 0, sizeof(*key));
150}
151
152
153typedef CSSM_RETURN (*op)(CSSM_CC_HANDLE, const CSSM_DATA *,
154    uint32, CSSM_DATA_PTR, uint32,
155    CSSM_SIZE *, CSSM_DATA_PTR);
156
157
158static int
159perform_rsa_op(int flen, const unsigned char *from,
160    unsigned char *to, RSA *rsa, int padding,
161    CSSM_ENCRYPT_MODE algMode, op func)
162{
163	CSSM_CSP_HANDLE cspHandle = _cs_get_cdsa_csphandle();
164	CSSM_RETURN cret;
165	CSSM_ACCESS_CREDENTIALS creds;
166	CSSM_KEY cssmKey;
167	CSSM_CC_HANDLE handle = 0;
168	CSSM_DATA out, in, rem;
169	int fret = 0;
170	CSSM_SIZE outlen = 0;
171	char remdata[1024];
172	size_t keysize;
173
174	if (padding != RSA_PKCS1_PADDING) {
175		return (-1);
176	}
177
178	memset(&creds, 0, sizeof(creds));
179
180	fret = load_key(cspHandle, rsa, (algMode == CSSM_ALGMODE_PUBLIC_KEY),
181		&cssmKey, &keysize);
182	if (fret) {
183		return (-2);
184	}
185
186	fret = CSSM_CSP_CreateAsymmetricContext(cspHandle,
187		CSSM_ALGID_RSA,
188		&creds,
189		&cssmKey,
190		CSSM_PADDING_PKCS1,
191		&handle);
192	if (fret) {
193		abort();
194	}
195
196	{
197		CSSM_CONTEXT_ATTRIBUTE attr;
198
199		attr.AttributeType = CSSM_ATTRIBUTE_MODE;
200		attr.AttributeLength = sizeof(attr.Attribute.Uint32);
201		attr.Attribute.Uint32 = algMode;
202
203		fret = CSSM_UpdateContextAttributes(handle, 1, &attr);
204		if (fret) {
205			abort();
206		}
207	}
208
209	in.Data = (uint8 *)from;
210	in.Length = flen;
211
212	out.Data = (uint8 *)to;
213	out.Length = keysize;
214
215	rem.Data = (uint8 *)remdata;
216	rem.Length = sizeof(remdata);
217
218	cret = func(handle, &in, 1, &out, 1, &outlen, &rem);
219	if (cret) {
220		/* cssmErrorString(cret); */
221		fret = -1;
222	} else{
223		fret = outlen;
224	}
225
226	if (handle) {
227		CSSM_DeleteContext(handle);
228	}
229	unload_key(&cssmKey);
230
231	return (fret);
232}
233
234
235/*
236 *
237 */
238static int
239cdsa_rsa_public_encrypt(int flen, const unsigned char *from,
240    unsigned char *to, RSA *rsa, int padding)
241{
242	return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PUBLIC_KEY, CSSM_EncryptData));
243}
244
245
246static int
247cdsa_rsa_public_decrypt(int flen, const unsigned char *from,
248    unsigned char *to, RSA *rsa, int padding)
249{
250	return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PUBLIC_KEY, CSSM_DecryptData));
251}
252
253
254static int
255cdsa_rsa_private_encrypt(int flen, const unsigned char *from,
256    unsigned char *to, RSA *rsa, int padding)
257{
258	return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PRIVATE_KEY, CSSM_EncryptData));
259}
260
261
262static int
263cdsa_rsa_private_decrypt(int flen, const unsigned char *from,
264    unsigned char *to, RSA *rsa, int padding)
265{
266	return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PRIVATE_KEY, CSSM_DecryptData));
267}
268
269
270static int
271cdsa_dsa_generate_key(DSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
272{
273	CSSM_CSP_HANDLE cspHandle = _cs_get_cdsa_csphandle();
274	uint32_t pubAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA;
275	uint32_t privAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA;
276	CSSM_CC_HANDLE handle = 0;
277	CSSM_RETURN ret;
278	size_t len;
279	const unsigned char *p;
280	CSSM_KEY priv_key, pub_key;
281	AlgorithmIdentifier ai;
282
283	memset(&priv_key, 0, sizeof(priv_key));
284	memset(&pub_key, 0, sizeof(pub_key));
285	memset(&ai, 0, sizeof(ai));
286
287	ret = CSSM_CSP_CreateKeyGenContext(cspHandle,
288		CSSM_ALGID_DSA,
289		bits,
290		NULL,                           /* Seed */
291		NULL,                           /* Salt */
292		NULL,                           /* StartDate */
293		NULL,                           /* EndDate */
294		NULL,                           /* Params */
295		&handle);
296	if (ret) {
297		return (0);
298	}
299
300	{
301		CSSM_CONTEXT_ATTRIBUTE attr;
302
303		/* optional format specifiers */
304		attr.AttributeType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT;
305		attr.AttributeLength = sizeof(attr.Attribute.Uint32);
306		attr.Attribute.Uint32 = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
307
308		ret = CSSM_UpdateContextAttributes(handle, 1, &attr);
309		if (ret) {
310			abort();
311		}
312
313		attr.AttributeType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT;
314		ret = CSSM_UpdateContextAttributes(handle, 1, &attr);
315		if (ret) {
316			abort();
317		}
318	}
319
320	ret = CSSM_GenerateKeyPair(handle,
321	        /* pubkey */
322		CSSM_KEYUSE_DERIVE,
323		pubAttr,
324		&_cs_labelData,
325		&pub_key,
326
327	        /* private key */
328		CSSM_KEYUSE_DERIVE,
329		privAttr,
330		&_cs_labelData,
331		NULL,                           /* CredAndAclEntry */
332		&priv_key);
333
334	CSSM_DeleteContext(handle);
335	if (ret) {
336		return (0);
337	}
338
339	ret = decode_AlgorithmIdentifier(priv_key.KeyData.Data,
340		priv_key.KeyData.Length, &ai, NULL);
341	if (ret || (ai.parameters == NULL)) {
342		p = priv_key.KeyData.Data;
343		len = priv_key.KeyData.Length;
344	} else {
345		p = ai.parameters->data;
346		len = ai.parameters->length;
347	}
348
349	ret = (d2i_DSAPrivateKey(dsa, &p, len) == NULL) ? 0 : 1;
350	free_AlgorithmIdentifier(&ai);
351
352	CSSM_FreeKey(cspHandle, NULL, &pub_key, CSSM_FALSE);
353	CSSM_FreeKey(cspHandle, NULL, &priv_key, CSSM_FALSE);
354
355	return (ret);
356}
357
358
359#endif /* #if 0 */
360
361static DSA_SIG *
362cdsa_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
363{
364	return (NULL);
365}
366
367
368static int
369cdsa_dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
370{
371	return (1);
372}
373
374
375static int
376cdsa_dsa_do_verify(const unsigned char *dgst, int dgst_len,
377    DSA_SIG *sig, DSA *dsa)
378{
379	return (1);
380}
381
382
383static int
384cdsa_dsa_init(DSA *dsa)
385{
386	return (1);
387}
388
389
390static int
391cdsa_dsa_finish(DSA *dsa)
392{
393	return (1);
394}
395
396
397static int
398cdsa_dsa_paramgen(DSA *dsa, int bits, unsigned char *seed, int seed_len,
399    int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
400{
401	return (1);
402}
403
404
405static int
406cdsa_dsa_keygen(DSA *dsa)
407{
408	return (1);
409}
410
411
412const DSA_METHOD _ossl_dsa_cdsa_method =
413{
414	.name		= "cryptoshim cdsa DSA",
415	.dsa_do_sign	= cdsa_dsa_do_sign,
416	.dsa_sign_setup = cdsa_dsa_sign_setup,
417	.dsa_do_verify	= cdsa_dsa_do_verify,
418	.init		= cdsa_dsa_init,
419	.finish		= cdsa_dsa_finish,
420	0,
421	NULL,
422	.dsa_paramgen	= cdsa_dsa_paramgen,
423	.dsa_keygen	= cdsa_dsa_keygen
424};
425#endif /* HAVE_CDSA */
426
427const DSA_METHOD *
428DSA_cdsa_method(void)
429{
430#ifdef HAVE_CDSA
431	return (&_ossl_dsa_cdsa_method);
432
433#else
434	return (NULL);
435#endif
436}
437