xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/netpgpverify/rsa.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*-
2  * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "config.h"
26 
27 #include <sys/types.h>
28 #include <sys/syslog.h>
29 
30 #ifdef _KERNEL
31 # include <sys/kmem.h>
32 # define logmessage	log
33 #else
34 # include <stdio.h>
35 # include <stdlib.h>
36 # include <string.h>
37 # include <unistd.h>
38 #endif
39 
40 #include "misc.h"
41 #include "digest.h"
42 #include "rsa.h"
43 
44 #ifndef USE_ARG
45 #define USE_ARG(x)	/*LINTED*/(void)&(x)
46 #endif
47 
48 #define RSA_MAX_MODULUS_BITS	16384
49 #define RSA_SMALL_MODULUS_BITS	3072
50 #define RSA_MAX_PUBEXP_BITS	64 /* exponent limit enforced for "large" modulus only */
51 
52 static int
53 rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num)
54 {
55 	USE_ARG(num);
56 	if (flen > tlen) {
57 		printf("r too large\n");
58 		return -1;
59 	}
60 	(void) memset(to, 0x0, tlen - flen);
61 	(void) memcpy(to + tlen - flen, from, flen);
62 	return tlen;
63 }
64 
65 static int
66 lowlevel_rsa_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa)
67 {
68 	BIGNUM	*decbn;
69 	BIGNUM	*signedbn;
70 	uint8_t	*decbuf;
71 	int	 nbytes;
72 	int	 signc;
73 	int	 signedbytes;
74 	int	 r;
75 
76 	decbuf = NULL;
77 	r = -1;
78 	decbn = BN_new();
79 	signedbn = BN_new();
80 	nbytes = BN_num_bytes(rsa->n);
81 	decbuf = netpgp_allocate(1, nbytes);
82 	/* add no padding */
83 	memcpy(decbuf, plain, plainc);
84 	BN_bin2bn(decbuf, nbytes, decbn);
85 	if (BN_cmp(decbn, rsa->n) >= 0) {
86 		printf("decbn too big\n");
87 		goto err;
88 	}
89 	if (!BN_mod_exp(signedbn, decbn, rsa->d, rsa->n, NULL)) {
90 		printf("bad mod_exp\n");
91 		goto err;
92 	}
93 	signedbytes = BN_num_bytes(signedbn);
94 	signc = BN_bn2bin(signedbn, &encbuf[nbytes - signedbytes]);
95 	memset(encbuf, 0x0, nbytes - signc);
96 	r = nbytes;
97 err:
98 	netpgp_deallocate(decbuf, nbytes);
99 	BN_clear_free(decbn);
100 	BN_clear_free(signedbn);
101 	return r;
102 }
103 
104 static int
105 lowlevel_rsa_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa)
106 {
107 	BIGNUM	*decbn;
108 	BIGNUM	*encbn;
109 	uint8_t	*decbuf;
110 	int	 nbytes;
111 	int	 encc;
112 	int	 r;
113 	int	 i;
114 
115 	r = -1;
116 	decbn = BN_new();
117 	encbn = BN_new();
118 	nbytes = BN_num_bytes(rsa->n);
119 	decbuf = netpgp_allocate(1, nbytes);
120 	(void) memcpy(decbuf, plain, plainc);
121 	if (BN_bin2bn(decbuf, nbytes, decbn) == NULL) {
122 		printf("bin2bn failed\n");
123 		goto err;
124 	}
125 	if (BN_cmp(decbn, rsa->n) >= 0) {
126 		printf("BN_cmp failed\n");
127 		goto err;
128 	}
129 	if (!BN_mod_exp(encbn, decbn, rsa->e, rsa->n, NULL)) {
130 		printf("BN_mod_exp failed\n");
131 		goto err;
132 	}
133 	encc = BN_num_bytes(encbn);
134 	i = BN_bn2bin(encbn, &encbuf[nbytes - encc]);
135 	(void) memset(encbuf, 0x0, nbytes - i);
136 	r = nbytes;
137 err:
138 	if (decbuf) {
139 		memset(decbuf, 0x0, nbytes);
140 		netpgp_deallocate(decbuf, nbytes);
141 	}
142 	BN_clear_free(decbn);
143 	BN_clear_free(encbn);
144 	return r;
145 }
146 
147 static int
148 lowlevel_rsa_private_decrypt(int enclen, const unsigned char *encbuf, unsigned char *to, RSA *rsa)
149 {
150 	BIGNUM	*encbn;
151 	BIGNUM	*decbn;
152 	uint8_t	*buf;
153 	int	 nbytes;
154 	int	 j;
155 	int	 r;
156 
157 	r = -1;
158 	decbn = encbn = NULL;
159 	buf = NULL;
160 	if (BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) {
161 		return -1;
162 	}
163 	if (BN_cmp(rsa->n, rsa->e) <= 0) {
164 		return -1;
165 	}
166 	encbn = BN_new();
167 	decbn = BN_new();
168 	nbytes = BN_num_bytes(rsa->n);
169 	buf = netpgp_allocate(1, nbytes);
170 	if (enclen > nbytes) {
171 		printf("bad enclen\n");
172 		goto err;
173 	}
174 	BN_bin2bn(encbuf, enclen, encbn);
175 	if (BN_cmp(encbn, rsa->n) >= 0) {
176 		printf("bad encbn\n");
177 		goto err;
178 	}
179 	BN_mod_exp(decbn, encbn, rsa->d, rsa->n, NULL);
180 	j = BN_bn2bin(decbn, buf);
181 	r = rsa_padding_check_none(to, nbytes, buf, j, nbytes);
182 err:
183 	BN_clear_free(encbn);
184 	BN_clear_free(decbn);
185 	netpgp_deallocate(buf, nbytes);
186 	return r;
187 }
188 
189 static int
190 lowlevel_rsa_public_decrypt(const uint8_t *encbuf, int enclen, uint8_t *dec, const rsa_pubkey_t *rsa)
191 {
192 	uint8_t		*decbuf;
193 	BIGNUM		*decbn;
194 	BIGNUM		*encbn;
195 	int		 decbytes;
196 	int		 nbytes;
197 	int		 r;
198 
199 	nbytes = 0;
200 	r = -1;
201 	decbuf = NULL;
202 	decbn = encbn = NULL;
203 	if (BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) {
204 		printf("rsa r modulus too large\n");
205 		goto err;
206 	}
207 	if (BN_cmp(rsa->n, rsa->e) <= 0) {
208 		printf("rsa r bad n value\n");
209 		goto err;
210 	}
211 	if (BN_num_bits(rsa->n) > RSA_SMALL_MODULUS_BITS &&
212 	    BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) {
213 		printf("rsa r bad exponent limit\n");
214 		goto err;
215 	}
216 	if ((encbn = BN_new()) == NULL ||
217 	    (decbn = BN_new()) == NULL ||
218 	    (decbuf = netpgp_allocate(1, nbytes = BN_num_bytes(rsa->n))) == NULL) {
219 		printf("allocation failure\n");
220 		goto err;
221 	}
222 	if (enclen > nbytes) {
223 		printf("rsa r > mod len\n");
224 		goto err;
225 	}
226 	if (BN_bin2bn(encbuf, enclen, encbn) == NULL) {
227 		printf("null encrypted BN\n");
228 		goto err;
229 	}
230 	if (BN_cmp(encbn, rsa->n) >= 0) {
231 		printf("rsa r data too large for modulus\n");
232 		goto err;
233 	}
234 	if (BN_mod_exp(decbn, encbn, rsa->e, rsa->n, NULL) < 0) {
235 		printf("BN_mod_exp < 0\n");
236 		goto err;
237 	}
238 	decbytes = BN_num_bytes(decbn);
239 	(void) BN_bn2bin(decbn, decbuf);
240 	if ((r = rsa_padding_check_none(dec, nbytes, decbuf, decbytes, 0)) < 0) {
241 		printf("rsa r padding check failed\n");
242 	}
243 err:
244 	BN_free(encbn);
245 	BN_free(decbn);
246 	if (decbuf != NULL) {
247 		(void) memset(decbuf, 0x0, nbytes);
248 		netpgp_deallocate(decbuf, nbytes);
249 	}
250 	return r;
251 }
252 
253 #if 0
254 /**
255   @file rsa_make_key.c
256   RSA key generation, Tom St Denis
257 */
258 
259 /**
260    Create an RSA key
261    @param prng     An active PRNG state
262    @param wprng    The index of the PRNG desired
263    @param size     The size of the modulus (key size) desired (octets)
264    @param e        The "e" value (public key).  e==65537 is a good choice
265    @param key      [out] Destination of a newly created private key pair
266    @return CRYPT_OK if successful, upon error all allocated ram is freed
267 */
268 static int
269 rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
270 {
271 	void *p, *q, *tmp1, *tmp2, *tmp3;
272 	int    err;
273 
274 	LTC_ARGCHK(ltc_mp.name != NULL);
275 	LTC_ARGCHK(key         != NULL);
276 
277 	if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
278 		return CRYPT_INVALID_KEYSIZE;
279 	}
280 
281 	if ((e < 3) || ((e & 1) == 0)) {
282 		return CRYPT_INVALID_ARG;
283 	}
284 
285 	if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
286 		return err;
287 	}
288 
289 	if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) {
290 		return err;
291 	}
292 
293 	/* make primes p and q (optimization provided by Wayne Scott) */
294 		/* tmp3 = e */
295 	if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) {
296 		goto errkey;
297 	}
298 
299 	/* make prime "p" */
300 	do {
301 		if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) {
302 			goto errkey;
303 		}
304 		/* tmp1 = p-1 */
305 		if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK) {
306 			goto errkey;
307 		}
308 		/* tmp2 = gcd(p-1, e) */
309 		if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK) {
310 			goto errkey;
311 		}
312 	} while (mp_cmp_d( tmp2, 1) != 0);
313 	/* while e divides p-1 */
314 
315 	/* make prime "q" */
316 	do {
317 		if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) {
318 			goto errkey;
319 		}
320 		/* tmp1 = q-1 */
321 		if ((err = mp_sub_d( q, 1,  tmp1)) != CRYPT_OK) {
322 			goto errkey;
323 		}
324 		/* tmp2 = gcd(q-1, e) */
325 		if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK) {
326 			goto errkey;
327 		}
328 	} while (mp_cmp_d( tmp2, 1) != 0);
329 	/* while e divides q-1 */
330 
331 	/* tmp1 = lcm(p-1, q-1) */
332 		/* tmp2 = p-1 */
333 	if ((err = mp_sub_d( p, 1,  tmp2)) != CRYPT_OK) {
334 		goto errkey;
335 	}
336 	/* tmp1 = q-1 (previous do/while loop) */
337 		/* tmp1 = lcm(p-1, q-1) */
338 	if ((err = mp_lcm( tmp1,  tmp2,  tmp1)) != CRYPT_OK) {
339 		goto errkey;
340 	}
341 
342 	/* make key */
343 	if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
344 		goto errkey;
345 	}
346 
347 	/* key->e =  e */
348 	if ((err = mp_set_int( key->e, e)) != CRYPT_OK) {
349 		goto errkey;
350 	}
351 	/* key->d = 1/e mod lcm(p-1,q-1) */
352 	if ((err = mp_invmod( key->e,  tmp1,  key->d)) != CRYPT_OK) {
353 		goto errkey;
354 	}
355 	/* key->N = pq */
356 	if ((err = mp_mul( p,  q,  key->N)) != CRYPT_OK) {
357 		goto errkey;
358 	}
359 
360 	/* optimize for CRT now */
361 	/* find d mod q-1 and d mod p-1 */
362 	/* tmp1 = q-1 */
363 	if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK) {
364 		goto errkey;
365 	}
366 	/* tmp2 = p-1 */
367 	if ((err = mp_sub_d( q, 1,  tmp2)) != CRYPT_OK) {
368 		goto errkey;
369 	}
370 	/* dP = d mod p-1 */
371 	if ((err = mp_mod( key->d,  tmp1,  key->dP)) != CRYPT_OK) {
372 		goto errkey;
373 	}
374 	/* dQ = d mod q-1 */
375 	if ((err = mp_mod( key->d,  tmp2,  key->dQ)) != CRYPT_OK) {
376 		goto errkey;
377 	}
378 	/* qP = 1/q mod p */
379 	if ((err = mp_invmod( q,  p,  key->qP)) != CRYPT_OK) {
380 		got oerrkey;
381 	}
382 
383 	if ((err = mp_copy( p,  key->p)) != CRYPT_OK) {
384 		goto errkey;
385 		}
386 	if ((err = mp_copy( q,  key->q)) != CRYPT_OK) {
387 		goto errkey;
388 	}
389 
390 	/* set key type (in this case it's CRT optimized) */
391 	key->type = PK_PRIVATE;
392 
393 	/* return ok and free temps */
394 	err = CRYPT_OK;
395 	goto cleanup;
396 errkey:
397 	mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
398 cleanup:
399 	mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL);
400 	return err;
401 }
402 #endif
403 
404 #define HASHBUF_LEN	512
405 
406 #define DSA_MAX_MODULUS_BITS	10000
407 
408 static int
409 dsa_do_verify(const unsigned char *calculated, int dgst_len, const dsasig_t *sig, mpi_dsa_t *dsa)
410 {
411 	BIGNUM		 *M;
412 	BIGNUM		 *W;
413 	BIGNUM		 *t1;
414 	int		 ret = -1;
415 	int		 qbits;
416 
417 	if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
418 		return 0;
419 	}
420 	M = W = t1 = NULL;
421 	qbits = BN_num_bits(dsa->q);
422 	switch(qbits) {
423 	case 160:
424 	case 224:
425 	case 256:
426 		/* openssl sources say these are the valid values */
427 		/* according to FIPS 186-3 */
428 		break;
429 	default:
430 		printf("dsa: bad # of Q bits\n");
431 		return 0;
432 	}
433 	if (BN_num_bits(dsa->p) > DSA_MAX_MODULUS_BITS) {
434 		printf("dsa: p too large\n");
435 		return 0;
436 	}
437 	/* no love for SHA512? */
438 	if (dgst_len > SHA256_DIGEST_LENGTH) {
439 		printf("dsa: digest too long\n");
440 		return 0;
441 	}
442 	ret = 0;
443 	if ((M = BN_new()) == NULL ||
444 	    (W = BN_new()) == NULL ||
445 	    (t1 = BN_new()) == NULL) {
446 		goto err;
447 	}
448 	if (BN_is_zero(sig->r) ||
449 	    BN_is_negative(sig->r) ||
450 	    BN_cmp(sig->r, dsa->q) >= 0) {
451 		goto err;
452 	}
453 	if (BN_is_zero(sig->s) ||
454 	    BN_is_negative(sig->s) ||
455 	    BN_cmp(sig->s, dsa->q) >= 0) {
456 		goto err;
457 	}
458 	if (BN_mod_inverse(W, sig->s, dsa->q, NULL) != MP_OKAY) {
459 		goto err;
460 	}
461 	if (dgst_len > qbits / 8) {
462 		dgst_len = qbits / 8;
463 	}
464 	if (BN_bin2bn(calculated, dgst_len, M) == NULL) {
465 		goto err;
466 	}
467 	if (!BN_mod_mul(M, M, W, dsa->q, NULL)) {
468 		goto err;
469 	}
470 	if (!BN_mod_mul(W, sig->r, W, dsa->q, NULL)) {
471 		goto err;
472 	}
473 	if (!BN_mod_exp(dsa->p, t1, dsa->g, M, NULL)) {
474 		goto err;
475 	}
476 	if (!BN_div(NULL, M, t1, dsa->q, NULL)) {
477 		goto err;
478 	}
479 	ret = (BN_cmp(M, sig->r) == 0);
480 err:
481 	if (M) {
482 		BN_free(M);
483 	}
484 	if (W) {
485 		BN_free(W);
486 	}
487 	if (t1) {
488 		BN_free(t1);
489 	}
490 	return ret;
491 }
492 
493 /*************************************************************************/
494 
495 int
496 RSA_size(const RSA *rsa)
497 {
498 	return (rsa == NULL) ? 0 : BN_num_bits(rsa->n);
499 }
500 
501 int
502 DSA_size(const DSA *dsa)
503 {
504 	return (dsa == NULL) ? 0 : BN_num_bits(dsa->p);
505 }
506 
507 unsigned
508 dsa_verify(const signature_t *signature, const dsa_pubkey_t *pubdsa, const uint8_t *calculated, size_t hash_length)
509 {
510 	mpi_dsa_t	odsa;
511 	dsasig_t	osig;
512 	unsigned	qlen;
513 	int             ret;
514 
515 	if (signature == NULL || pubdsa == NULL || calculated == NULL) {
516 		return -1;
517 	}
518 	(void) memset(&osig, 0x0, sizeof(osig));
519 	(void) memset(&odsa, 0x0, sizeof(odsa));
520 	BN_copy(osig.r, signature->dsa.r);
521 	BN_copy(osig.s, signature->dsa.s);
522 	odsa.p = pubdsa->p;
523 	odsa.q = pubdsa->q;
524 	odsa.g = pubdsa->g;
525 	odsa.pub_key = pubdsa->y;
526 	if ((qlen = BN_num_bytes(odsa.q)) < hash_length) {
527 		hash_length = qlen;
528 	}
529 	ret = dsa_do_verify(calculated, (int)hash_length, &signature->dsa, &odsa);
530 	if (ret < 0) {
531 		return 0;
532 	}
533 	BN_free(odsa.p);
534 	BN_free(odsa.q);
535 	BN_free(odsa.g);
536 	BN_free(odsa.pub_key);
537 	odsa.p = odsa.q = odsa.g = odsa.pub_key = NULL;
538 	BN_free(osig.r);
539 	BN_free(osig.s);
540 	osig.r = osig.s = NULL;
541 	return (unsigned)ret;
542 }
543 
544 RSA *
545 RSA_new(void)
546 {
547 	return netpgp_allocate(1, sizeof(RSA));
548 }
549 
550 void
551 RSA_free(RSA *rsa)
552 {
553 	if (rsa) {
554 		netpgp_deallocate(rsa, sizeof(*rsa));
555 	}
556 }
557 
558 int
559 RSA_check_key(RSA *rsa)
560 {
561 	BIGNUM	*calcn;
562 	int	 ret;
563 
564 	ret = 0;
565 	if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->n == NULL) {
566 		return -1;
567 	}
568 	/* check that p and q are coprime, and that n = p*q. */
569 	if (!BN_is_prime(rsa->p, 1, NULL, NULL, NULL) ||
570 	    !BN_is_prime(rsa->q, 1, NULL, NULL, NULL)) {
571 		return 0;
572 	}
573 	calcn = BN_new();
574         BN_mul(calcn, rsa->p, rsa->q, NULL);
575 	if (BN_cmp(calcn, rsa->n) != 0) {
576 		goto errout;
577 	}
578 	/* XXX - check that d*e = 1 mod (p-1*q-1) */
579 	ret = 1;
580 errout:
581 	BN_clear_free(calcn);
582 	return ret;
583 }
584 
585 RSA *
586 RSA_generate_key(int num, unsigned long e, void (*callback)(int,int,void *), void *cb_arg)
587 {
588 	/* STUBBED */
589 	USE_ARG(num);
590 	USE_ARG(e);
591 	USE_ARG(callback);
592 	USE_ARG(cb_arg);
593 	printf("RSA_generate_key stubbed\n");
594 	return RSA_new();
595 }
596 
597 /* encrypt */
598 int
599 RSA_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa, int padding)
600 {
601 	USE_ARG(padding);
602 	if (plain == NULL || encbuf == NULL || rsa == NULL) {
603 		return -1;
604 	}
605 	return lowlevel_rsa_public_encrypt(plainc, plain, encbuf, rsa);
606 }
607 
608 /* decrypt */
609 int
610 RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
611 {
612 	USE_ARG(padding);
613 	if (from == NULL || to == NULL || rsa == NULL) {
614 		return -1;
615 	}
616 	return lowlevel_rsa_private_decrypt(flen, from, to, rsa);
617 }
618 
619 /* sign */
620 int
621 RSA_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa, int padding)
622 {
623 	USE_ARG(padding);
624 	if (plain == NULL || encbuf == NULL || rsa == NULL) {
625 		return -1;
626 	}
627 	return lowlevel_rsa_private_encrypt(plainc, plain, encbuf, rsa);
628 }
629 
630 /* verify */
631 int
632 RSA_public_decrypt(int enclen, const unsigned char *enc, unsigned char *dec, RSA *rsa, int padding)
633 {
634 	rsa_pubkey_t	pub;
635 	int		ret;
636 
637 	if (enc == NULL || dec == NULL || rsa == NULL) {
638 		return 0;
639 	}
640 	USE_ARG(padding);
641 	(void) memset(&pub, 0x0, sizeof(pub));
642 	pub.n = BN_dup(rsa->n);
643 	pub.e = BN_dup(rsa->e);
644 	ret = lowlevel_rsa_public_decrypt(enc, enclen, dec, &pub);
645 	BN_free(pub.n);
646 	BN_free(pub.e);
647 	return ret;
648 }
649 
650 /***********************************************************************/
651 
652 DSA *
653 DSA_new(void)
654 {
655 	return netpgp_allocate(1, sizeof(DSA));
656 }
657 
658 void
659 DSA_free(DSA *dsa)
660 {
661 	if (dsa) {
662 		netpgp_deallocate(dsa, sizeof(*dsa));
663 	}
664 }
665 
666 DSA_SIG *
667 DSA_SIG_new(void)
668 {
669 	return netpgp_allocate(1, sizeof(DSA_SIG));
670 }
671 
672 void
673 DSA_SIG_free(DSA_SIG *sig)
674 {
675 	if (sig) {
676 		netpgp_deallocate(sig, sizeof(*sig));
677 	}
678 }
679 
680 DSA_SIG *
681 DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
682 {
683 	/* STUBBED */
684 	USE_ARG(dgst);
685 	USE_ARG(dlen);
686 	USE_ARG(dsa);
687 	printf("DSA_do_sign stubbed\n");
688 	return DSA_SIG_new();
689 }
690 
691 int
692 DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa)
693 {
694 	if (dgst == NULL || dgst_len == 0 || sig == NULL || dsa == NULL) {
695 		return -1;
696 	}
697 	return dsa_do_verify(dgst, dgst_len, sig, dsa);
698 }
699