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