xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/netpgpverify/rsa.c (revision 05c460ad06fc41fffebf804e499869c302af65e3)
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 
29 #ifdef _KERNEL
30 # include <sys/kmem.h>
31 #else
32 # include <stdio.h>
33 # include <stdlib.h>
34 # include <string.h>
35 # include <unistd.h>
36 #endif
37 
38 #include "misc.h"
39 #include "digest.h"
40 #include "rsa.h"
41 
42 #ifndef USE_ARG
43 #define USE_ARG(x)	/*LINTED*/(void)&(x)
44 #endif
45 
46 #define RSA_MAX_MODULUS_BITS	16384
47 #define RSA_SMALL_MODULUS_BITS	3072
48 #define RSA_MAX_PUBEXP_BITS	64 /* exponent limit enforced for "large" modulus only */
49 
50 static int
rsa_padding_check_none(uint8_t * to,int tlen,const uint8_t * from,int flen,int num)51 rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num)
52 {
53 	USE_ARG(num);
54 	if (flen > tlen) {
55 		printf("r too large\n");
56 		return -1;
57 	}
58 	(void) memset(to, 0x0, tlen - flen);
59 	(void) memcpy(to + tlen - flen, from, flen);
60 	return tlen;
61 }
62 
63 static int
lowlevel_rsa_private_encrypt(int plainc,const unsigned char * plain,unsigned char * encbuf,NETPGPV_RSA * rsa)64 lowlevel_rsa_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, NETPGPV_RSA *rsa)
65 {
66 	PGPV_BIGNUM	*decbn;
67 	PGPV_BIGNUM	*signedbn;
68 	uint8_t	*decbuf;
69 	int	 nbytes;
70 	int	 signc;
71 	int	 signedbytes;
72 	int	 r;
73 
74 	decbuf = NULL;
75 	r = -1;
76 	decbn = PGPV_BN_new();
77 	signedbn = PGPV_BN_new();
78 	nbytes = PGPV_BN_num_bytes(rsa->n);
79 	decbuf = netpgp_allocate(1, nbytes);
80 	/* add no padding */
81 	memcpy(decbuf, plain, plainc);
82 	PGPV_BN_bin2bn(decbuf, nbytes, decbn);
83 	if (PGPV_BN_cmp(decbn, rsa->n) >= 0) {
84 		printf("decbn too big\n");
85 		goto err;
86 	}
87 	if (!PGPV_BN_mod_exp(signedbn, decbn, rsa->d, rsa->n, NULL)) {
88 		printf("bad mod_exp\n");
89 		goto err;
90 	}
91 	signedbytes = PGPV_BN_num_bytes(signedbn);
92 	signc = PGPV_BN_bn2bin(signedbn, &encbuf[nbytes - signedbytes]);
93 	memset(encbuf, 0x0, nbytes - signc);
94 	r = nbytes;
95 err:
96 	netpgp_deallocate(decbuf, nbytes);
97 	PGPV_BN_clear_free(decbn);
98 	PGPV_BN_clear_free(signedbn);
99 	return r;
100 }
101 
102 static int
lowlevel_rsa_public_encrypt(int plainc,const unsigned char * plain,unsigned char * encbuf,NETPGPV_RSA * rsa)103 lowlevel_rsa_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, NETPGPV_RSA *rsa)
104 {
105 	PGPV_BIGNUM	*decbn;
106 	PGPV_BIGNUM	*encbn;
107 	uint8_t	*decbuf;
108 	int	 nbytes;
109 	int	 encc;
110 	int	 r;
111 	int	 i;
112 
113 	r = -1;
114 	decbn = PGPV_BN_new();
115 	encbn = PGPV_BN_new();
116 	nbytes = PGPV_BN_num_bytes(rsa->n);
117 	decbuf = netpgp_allocate(1, nbytes);
118 	(void) memcpy(decbuf, plain, plainc);
119 	if (PGPV_BN_bin2bn(decbuf, nbytes, decbn) == NULL) {
120 		printf("bin2bn failed\n");
121 		goto err;
122 	}
123 	if (PGPV_BN_cmp(decbn, rsa->n) >= 0) {
124 		printf("PGPV_BN_cmp failed\n");
125 		goto err;
126 	}
127 	if (!PGPV_BN_mod_exp(encbn, decbn, rsa->e, rsa->n, NULL)) {
128 		printf("PGPV_BN_mod_exp failed\n");
129 		goto err;
130 	}
131 	encc = PGPV_BN_num_bytes(encbn);
132 	i = PGPV_BN_bn2bin(encbn, &encbuf[nbytes - encc]);
133 	(void) memset(encbuf, 0x0, nbytes - i);
134 	r = nbytes;
135 err:
136 	if (decbuf) {
137 		memset(decbuf, 0x0, nbytes);
138 		netpgp_deallocate(decbuf, nbytes);
139 	}
140 	PGPV_BN_clear_free(decbn);
141 	PGPV_BN_clear_free(encbn);
142 	return r;
143 }
144 
145 static int
lowlevel_rsa_private_decrypt(int enclen,const unsigned char * encbuf,unsigned char * to,NETPGPV_RSA * rsa)146 lowlevel_rsa_private_decrypt(int enclen, const unsigned char *encbuf, unsigned char *to, NETPGPV_RSA *rsa)
147 {
148 	PGPV_BIGNUM	*encbn;
149 	PGPV_BIGNUM	*decbn;
150 	uint8_t	*buf;
151 	int	 nbytes;
152 	int	 j;
153 	int	 r;
154 
155 	r = -1;
156 	decbn = encbn = NULL;
157 	buf = NULL;
158 	if (PGPV_BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) {
159 		return -1;
160 	}
161 	if (PGPV_BN_cmp(rsa->n, rsa->e) <= 0) {
162 		return -1;
163 	}
164 	encbn = PGPV_BN_new();
165 	decbn = PGPV_BN_new();
166 	nbytes = PGPV_BN_num_bytes(rsa->n);
167 	buf = netpgp_allocate(1, nbytes);
168 	if (enclen > nbytes) {
169 		printf("bad enclen\n");
170 		goto err;
171 	}
172 	PGPV_BN_bin2bn(encbuf, enclen, encbn);
173 	if (PGPV_BN_cmp(encbn, rsa->n) >= 0) {
174 		printf("bad encbn\n");
175 		goto err;
176 	}
177 	PGPV_BN_mod_exp(decbn, encbn, rsa->d, rsa->n, NULL);
178 	j = PGPV_BN_bn2bin(decbn, buf);
179 	r = rsa_padding_check_none(to, nbytes, buf, j, nbytes);
180 err:
181 	PGPV_BN_clear_free(encbn);
182 	PGPV_BN_clear_free(decbn);
183 	netpgp_deallocate(buf, nbytes);
184 	return r;
185 }
186 
187 static int
lowlevel_rsa_public_decrypt(const uint8_t * encbuf,int enclen,uint8_t * dec,const netpgpv_rsa_pubkey_t * rsa)188 lowlevel_rsa_public_decrypt(const uint8_t *encbuf, int enclen, uint8_t *dec, const netpgpv_rsa_pubkey_t *rsa)
189 {
190 	uint8_t		*decbuf;
191 	PGPV_BIGNUM		*decbn;
192 	PGPV_BIGNUM		*encbn;
193 	int		 decbytes;
194 	int		 nbytes;
195 	int		 r;
196 
197 	nbytes = 0;
198 	r = -1;
199 	decbuf = NULL;
200 	decbn = encbn = NULL;
201 	if (PGPV_BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) {
202 		printf("rsa r modulus too large\n");
203 		goto err;
204 	}
205 	if (PGPV_BN_cmp(rsa->n, rsa->e) <= 0) {
206 		printf("rsa r bad n value\n");
207 		goto err;
208 	}
209 	if (PGPV_BN_num_bits(rsa->n) > RSA_SMALL_MODULUS_BITS &&
210 	    PGPV_BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) {
211 		printf("rsa r bad exponent limit\n");
212 		goto err;
213 	}
214 	if ((encbn = PGPV_BN_new()) == NULL ||
215 	    (decbn = PGPV_BN_new()) == NULL ||
216 	    (decbuf = netpgp_allocate(1, nbytes = PGPV_BN_num_bytes(rsa->n))) == NULL) {
217 		printf("allocation failure\n");
218 		goto err;
219 	}
220 	if (enclen > nbytes) {
221 		printf("rsa r > mod len\n");
222 		goto err;
223 	}
224 	if (PGPV_BN_bin2bn(encbuf, enclen, encbn) == NULL) {
225 		printf("null encrypted BN\n");
226 		goto err;
227 	}
228 	if (PGPV_BN_cmp(encbn, rsa->n) >= 0) {
229 		printf("rsa r data too large for modulus\n");
230 		goto err;
231 	}
232 	if (PGPV_BN_mod_exp(decbn, encbn, rsa->e, rsa->n, NULL) < 0) {
233 		printf("PGPV_BN_mod_exp < 0\n");
234 		goto err;
235 	}
236 	decbytes = PGPV_BN_num_bytes(decbn);
237 	(void) PGPV_BN_bn2bin(decbn, decbuf);
238 	if ((r = rsa_padding_check_none(dec, nbytes, decbuf, decbytes, 0)) < 0) {
239 		printf("rsa r padding check failed\n");
240 	}
241 err:
242 	PGPV_BN_free(encbn);
243 	PGPV_BN_free(decbn);
244 	if (decbuf != NULL) {
245 		(void) memset(decbuf, 0x0, nbytes);
246 		netpgp_deallocate(decbuf, nbytes);
247 	}
248 	return r;
249 }
250 
251 #if 0
252 /**
253   @file rsa_make_key.c
254   RSA key generation, Tom St Denis
255 */
256 
257 /**
258    Create an RSA key
259    @param prng     An active PRNG state
260    @param wprng    The index of the PRNG desired
261    @param size     The size of the modulus (key size) desired (octets)
262    @param e        The "e" value (public key).  e==65537 is a good choice
263    @param key      [out] Destination of a newly created private key pair
264    @return CRYPT_OK if successful, upon error all allocated ram is freed
265 */
266 static int
267 rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
268 {
269 	void *p, *q, *tmp1, *tmp2, *tmp3;
270 	int    err;
271 
272 	LTC_ARGCHK(ltc_mp.name != NULL);
273 	LTC_ARGCHK(key         != NULL);
274 
275 	if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
276 		return CRYPT_INVALID_KEYSIZE;
277 	}
278 
279 	if ((e < 3) || ((e & 1) == 0)) {
280 		return CRYPT_INVALID_ARG;
281 	}
282 
283 	if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
284 		return err;
285 	}
286 
287 	if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) {
288 		return err;
289 	}
290 
291 	/* make primes p and q (optimization provided by Wayne Scott) */
292 		/* tmp3 = e */
293 	if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) {
294 		goto errkey;
295 	}
296 
297 	/* make prime "p" */
298 	do {
299 		if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) {
300 			goto errkey;
301 		}
302 		/* tmp1 = p-1 */
303 		if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK) {
304 			goto errkey;
305 		}
306 		/* tmp2 = gcd(p-1, e) */
307 		if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK) {
308 			goto errkey;
309 		}
310 	} while (mp_cmp_d( tmp2, 1) != 0);
311 	/* while e divides p-1 */
312 
313 	/* make prime "q" */
314 	do {
315 		if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) {
316 			goto errkey;
317 		}
318 		/* tmp1 = q-1 */
319 		if ((err = mp_sub_d( q, 1,  tmp1)) != CRYPT_OK) {
320 			goto errkey;
321 		}
322 		/* tmp2 = gcd(q-1, e) */
323 		if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK) {
324 			goto errkey;
325 		}
326 	} while (mp_cmp_d( tmp2, 1) != 0);
327 	/* while e divides q-1 */
328 
329 	/* tmp1 = lcm(p-1, q-1) */
330 		/* tmp2 = p-1 */
331 	if ((err = mp_sub_d( p, 1,  tmp2)) != CRYPT_OK) {
332 		goto errkey;
333 	}
334 	/* tmp1 = q-1 (previous do/while loop) */
335 		/* tmp1 = lcm(p-1, q-1) */
336 	if ((err = mp_lcm( tmp1,  tmp2,  tmp1)) != CRYPT_OK) {
337 		goto errkey;
338 	}
339 
340 	/* make key */
341 	if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
342 		goto errkey;
343 	}
344 
345 	/* key->e =  e */
346 	if ((err = mp_set_int( key->e, e)) != CRYPT_OK) {
347 		goto errkey;
348 	}
349 	/* key->d = 1/e mod lcm(p-1,q-1) */
350 	if ((err = mp_invmod( key->e,  tmp1,  key->d)) != CRYPT_OK) {
351 		goto errkey;
352 	}
353 	/* key->N = pq */
354 	if ((err = mp_mul( p,  q,  key->N)) != CRYPT_OK) {
355 		goto errkey;
356 	}
357 
358 	/* optimize for CRT now */
359 	/* find d mod q-1 and d mod p-1 */
360 	/* tmp1 = q-1 */
361 	if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK) {
362 		goto errkey;
363 	}
364 	/* tmp2 = p-1 */
365 	if ((err = mp_sub_d( q, 1,  tmp2)) != CRYPT_OK) {
366 		goto errkey;
367 	}
368 	/* dP = d mod p-1 */
369 	if ((err = mp_mod( key->d,  tmp1,  key->dP)) != CRYPT_OK) {
370 		goto errkey;
371 	}
372 	/* dQ = d mod q-1 */
373 	if ((err = mp_mod( key->d,  tmp2,  key->dQ)) != CRYPT_OK) {
374 		goto errkey;
375 	}
376 	/* qP = 1/q mod p */
377 	if ((err = mp_invmod( q,  p,  key->qP)) != CRYPT_OK) {
378 		got oerrkey;
379 	}
380 
381 	if ((err = mp_copy( p,  key->p)) != CRYPT_OK) {
382 		goto errkey;
383 		}
384 	if ((err = mp_copy( q,  key->q)) != CRYPT_OK) {
385 		goto errkey;
386 	}
387 
388 	/* set key type (in this case it's CRT optimized) */
389 	key->type = PK_PRIVATE;
390 
391 	/* return ok and free temps */
392 	err = CRYPT_OK;
393 	goto cleanup;
394 errkey:
395 	mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
396 cleanup:
397 	mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL);
398 	return err;
399 }
400 #endif
401 
402 #define HASHBUF_LEN	512
403 
404 #define DSA_MAX_MODULUS_BITS	10000
405 
406 static int
dsa_do_verify(const unsigned char * calculated,int dgst_len,const netpgpv_dsasig_t * sig,netpgpv_mpi_dsa_t * dsa)407 dsa_do_verify(const unsigned char *calculated, int dgst_len, const netpgpv_dsasig_t *sig, netpgpv_mpi_dsa_t *dsa)
408 {
409 	PGPV_BIGNUM		 *M;
410 	PGPV_BIGNUM		 *W;
411 	PGPV_BIGNUM		 *t1;
412 	int		 ret = -1;
413 	int		 qbits;
414 
415 	if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
416 		return 0;
417 	}
418 	M = W = t1 = NULL;
419 	qbits = PGPV_BN_num_bits(dsa->q);
420 	switch(qbits) {
421 	case 160:
422 	case 224:
423 	case 256:
424 		/* openssl sources say these are the valid values */
425 		/* according to FIPS 186-3 */
426 		break;
427 	default:
428 		printf("dsa: bad # of Q bits\n");
429 		return 0;
430 	}
431 	if (PGPV_BN_num_bits(dsa->p) > DSA_MAX_MODULUS_BITS) {
432 		printf("dsa: p too large\n");
433 		return 0;
434 	}
435 	/* no love for SHA512? */
436 	if (dgst_len > SHA256_DIGEST_LENGTH) {
437 		printf("dsa: digest too long\n");
438 		return 0;
439 	}
440 	ret = 0;
441 	if ((M = PGPV_BN_new()) == NULL ||
442 	    (W = PGPV_BN_new()) == NULL ||
443 	    (t1 = PGPV_BN_new()) == NULL) {
444 		goto err;
445 	}
446 	if (PGPV_BN_is_zero(sig->r) ||
447 	    PGPV_BN_is_negative(sig->r) ||
448 	    PGPV_BN_cmp(sig->r, dsa->q) >= 0) {
449 		goto err;
450 	}
451 	if (PGPV_BN_is_zero(sig->s) ||
452 	    PGPV_BN_is_negative(sig->s) ||
453 	    PGPV_BN_cmp(sig->s, dsa->q) >= 0) {
454 		goto err;
455 	}
456 	if (PGPV_BN_mod_inverse(W, sig->s, dsa->q, NULL) != MP_OKAY) {
457 		goto err;
458 	}
459 	if (dgst_len > qbits / 8) {
460 		dgst_len = qbits / 8;
461 	}
462 	if (PGPV_BN_bin2bn(calculated, dgst_len, M) == NULL) {
463 		goto err;
464 	}
465 	if (!PGPV_BN_mod_mul(M, M, W, dsa->q, NULL)) {
466 		goto err;
467 	}
468 	if (!PGPV_BN_mod_mul(W, sig->r, W, dsa->q, NULL)) {
469 		goto err;
470 	}
471 	if (!PGPV_BN_mod_exp(dsa->p, t1, dsa->g, M, NULL)) {
472 		goto err;
473 	}
474 	if (!PGPV_BN_div(NULL, M, t1, dsa->q, NULL)) {
475 		goto err;
476 	}
477 	ret = (PGPV_BN_cmp(M, sig->r) == 0);
478 err:
479 	if (M) {
480 		PGPV_BN_free(M);
481 	}
482 	if (W) {
483 		PGPV_BN_free(W);
484 	}
485 	if (t1) {
486 		PGPV_BN_free(t1);
487 	}
488 	return ret;
489 }
490 
491 /*************************************************************************/
492 
493 int
netpgpv_RSA_size(const NETPGPV_RSA * rsa)494 netpgpv_RSA_size(const NETPGPV_RSA *rsa)
495 {
496 	return (rsa == NULL) ? 0 : PGPV_BN_num_bits(rsa->n);
497 }
498 
499 int
netpgpv_DSA_size(const NETPGPV_DSA * dsa)500 netpgpv_DSA_size(const NETPGPV_DSA *dsa)
501 {
502 	return (dsa == NULL) ? 0 : PGPV_BN_num_bits(dsa->p);
503 }
504 
505 unsigned
netpgpv_dsa_verify(const signature_t * signature,const netpgpv_dsa_pubkey_t * pubdsa,const uint8_t * calculated,size_t hash_length)506 netpgpv_dsa_verify(const signature_t *signature,
507 	const netpgpv_dsa_pubkey_t *pubdsa, const uint8_t *calculated,
508 	size_t hash_length)
509 {
510 	netpgpv_mpi_dsa_t	odsa;
511 	netpgpv_dsasig_t	osig;
512 	unsigned		qlen;
513 	int	             ret;
514 
515 	if (signature == NULL || pubdsa == NULL || calculated == NULL) {
516 		return (unsigned)-1;
517 	}
518 	(void) memset(&osig, 0x0, sizeof(osig));
519 	(void) memset(&odsa, 0x0, sizeof(odsa));
520 	PGPV_BN_copy(osig.r, signature->dsa.r);
521 	PGPV_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 = PGPV_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 	PGPV_BN_free(odsa.p);
534 	PGPV_BN_free(odsa.q);
535 	PGPV_BN_free(odsa.g);
536 	PGPV_BN_free(odsa.pub_key);
537 	odsa.p = odsa.q = odsa.g = odsa.pub_key = NULL;
538 	PGPV_BN_free(osig.r);
539 	PGPV_BN_free(osig.s);
540 	osig.r = osig.s = NULL;
541 	return (unsigned)ret;
542 }
543 
544 NETPGPV_RSA *
netpgpv_RSA_new(void)545 netpgpv_RSA_new(void)
546 {
547 	return netpgp_allocate(1, sizeof(NETPGPV_RSA));
548 }
549 
550 void
netpgpv_RSA_free(NETPGPV_RSA * rsa)551 netpgpv_RSA_free(NETPGPV_RSA *rsa)
552 {
553 	if (rsa) {
554 		netpgp_deallocate(rsa, sizeof(*rsa));
555 	}
556 }
557 
558 int
netpgpv_RSA_check_key(NETPGPV_RSA * rsa)559 netpgpv_RSA_check_key(NETPGPV_RSA *rsa)
560 {
561 	PGPV_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 (!PGPV_BN_is_prime(rsa->p, 1, NULL, NULL, NULL) ||
570 	    !PGPV_BN_is_prime(rsa->q, 1, NULL, NULL, NULL)) {
571 		return 0;
572 	}
573 	calcn = PGPV_BN_new();
574         PGPV_BN_mul(calcn, rsa->p, rsa->q, NULL);
575 	if (PGPV_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 	PGPV_BN_clear_free(calcn);
582 	return ret;
583 }
584 
585 NETPGPV_RSA *
netpgpv_RSA_generate_key(int num,unsigned long e,void (* callback)(int,int,void *),void * cb_arg)586 netpgpv_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 netpgpv_RSA_new();
595 }
596 
597 /* encrypt */
598 int
netpgpv_RSA_public_encrypt(int plainc,const unsigned char * plain,unsigned char * encbuf,NETPGPV_RSA * rsa,int padding)599 netpgpv_RSA_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, NETPGPV_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
netpgpv_RSA_private_decrypt(int flen,const unsigned char * from,unsigned char * to,NETPGPV_RSA * rsa,int padding)610 netpgpv_RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, NETPGPV_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
netpgpv_RSA_private_encrypt(int plainc,const unsigned char * plain,unsigned char * encbuf,NETPGPV_RSA * rsa,int padding)621 netpgpv_RSA_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, NETPGPV_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
netpgpv_RSA_public_decrypt(int enclen,const unsigned char * enc,unsigned char * dec,NETPGPV_RSA * rsa,int padding)632 netpgpv_RSA_public_decrypt(int enclen, const unsigned char *enc, unsigned char *dec, NETPGPV_RSA *rsa, int padding)
633 {
634 	netpgpv_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 = PGPV_BN_dup(rsa->n);
643 	pub.e = PGPV_BN_dup(rsa->e);
644 	ret = lowlevel_rsa_public_decrypt(enc, enclen, dec, &pub);
645 	PGPV_BN_free(pub.n);
646 	PGPV_BN_free(pub.e);
647 	return ret;
648 }
649 
650 /***********************************************************************/
651 
652 NETPGPV_DSA *
netpgpv_DSA_new(void)653 netpgpv_DSA_new(void)
654 {
655 	return netpgp_allocate(1, sizeof(NETPGPV_DSA));
656 }
657 
658 void
netpgpv_DSA_free(NETPGPV_DSA * dsa)659 netpgpv_DSA_free(NETPGPV_DSA *dsa)
660 {
661 	if (dsa) {
662 		netpgp_deallocate(dsa, sizeof(*dsa));
663 	}
664 }
665 
666 NETPGPV_DSA_SIG *
netpgpv_DSA_SIG_new(void)667 netpgpv_DSA_SIG_new(void)
668 {
669 	return netpgp_allocate(1, sizeof(NETPGPV_DSA_SIG));
670 }
671 
672 void
netpgpv_DSA_SIG_free(NETPGPV_DSA_SIG * sig)673 netpgpv_DSA_SIG_free(NETPGPV_DSA_SIG *sig)
674 {
675 	if (sig) {
676 		netpgp_deallocate(sig, sizeof(*sig));
677 	}
678 }
679 
680 NETPGPV_DSA_SIG *
netpgpv_DSA_do_sign(const unsigned char * dgst,int dlen,NETPGPV_DSA * dsa)681 netpgpv_DSA_do_sign(const unsigned char *dgst, int dlen, NETPGPV_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 netpgpv_DSA_SIG_new();
689 }
690 
691 int
netpgpv_DSA_do_verify(const unsigned char * dgst,int dgst_len,NETPGPV_DSA_SIG * sig,NETPGPV_DSA * dsa)692 netpgpv_DSA_do_verify(const unsigned char *dgst, int dgst_len, NETPGPV_DSA_SIG *sig, NETPGPV_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