xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c (revision 0294a66b694d2a57b43f64b66c7a4aee89316c4e)
12232f800Sagc /*-
22232f800Sagc  * Copyright (c) 2009 The NetBSD Foundation, Inc.
32232f800Sagc  * All rights reserved.
42232f800Sagc  *
52232f800Sagc  * This code is derived from software contributed to The NetBSD Foundation
62232f800Sagc  * by Alistair Crooks (agc@NetBSD.org)
72232f800Sagc  *
82232f800Sagc  * Redistribution and use in source and binary forms, with or without
92232f800Sagc  * modification, are permitted provided that the following conditions
102232f800Sagc  * are met:
112232f800Sagc  * 1. Redistributions of source code must retain the above copyright
122232f800Sagc  *    notice, this list of conditions and the following disclaimer.
132232f800Sagc  * 2. Redistributions in binary form must reproduce the above copyright
142232f800Sagc  *    notice, this list of conditions and the following disclaimer in the
152232f800Sagc  *    documentation and/or other materials provided with the distribution.
162232f800Sagc  *
172232f800Sagc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
182232f800Sagc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
192232f800Sagc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
202232f800Sagc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
212232f800Sagc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
222232f800Sagc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
232232f800Sagc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
242232f800Sagc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
252232f800Sagc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
262232f800Sagc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
272232f800Sagc  * POSSIBILITY OF SUCH DAMAGE.
282232f800Sagc  */
2993bf6008Sagc /*
3093bf6008Sagc  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
3193bf6008Sagc  * All rights reserved.
3293bf6008Sagc  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
3393bf6008Sagc  * their moral rights under the UK Copyright Design and Patents Act 1988 to
3493bf6008Sagc  * be recorded as the authors of this copyright work.
3593bf6008Sagc  *
3693bf6008Sagc  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
3793bf6008Sagc  * use this file except in compliance with the License.
3893bf6008Sagc  *
3993bf6008Sagc  * You may obtain a copy of the License at
4093bf6008Sagc  *     http://www.apache.org/licenses/LICENSE-2.0
4193bf6008Sagc  *
4293bf6008Sagc  * Unless required by applicable law or agreed to in writing, software
4393bf6008Sagc  * distributed under the License is distributed on an "AS IS" BASIS,
4493bf6008Sagc  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4593bf6008Sagc  *
4693bf6008Sagc  * See the License for the specific language governing permissions and
4793bf6008Sagc  * limitations under the License.
4893bf6008Sagc  */
4993bf6008Sagc 
5093bf6008Sagc /** \file
5193bf6008Sagc  */
5293bf6008Sagc #include "config.h"
5393bf6008Sagc 
5457324b9fSagc #ifdef HAVE_SYS_CDEFS_H
5557324b9fSagc #include <sys/cdefs.h>
5657324b9fSagc #endif
5757324b9fSagc 
5857324b9fSagc #if defined(__NetBSD__)
5957324b9fSagc __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60*0294a66bSjhigh __RCSID("$NetBSD: openssl_crypto.c,v 1.35 2022/08/26 19:18:38 jhigh Exp $");
6193bf6008Sagc #endif
6293bf6008Sagc 
6393bf6008Sagc #ifdef HAVE_OPENSSL_DSA_H
6493bf6008Sagc #include <openssl/dsa.h>
6593bf6008Sagc #endif
6693bf6008Sagc 
6793bf6008Sagc #ifdef HAVE_OPENSSL_RSA_H
6893bf6008Sagc #include <openssl/rsa.h>
6993bf6008Sagc #endif
7093bf6008Sagc 
7193bf6008Sagc #ifdef HAVE_OPENSSL_ERR_H
7293bf6008Sagc #include <openssl/err.h>
7393bf6008Sagc #endif
7493bf6008Sagc 
7591c29c74Sagc #include <openssl/pem.h>
7691c29c74Sagc #include <openssl/evp.h>
7791c29c74Sagc 
7893bf6008Sagc #include <stdlib.h>
7991c29c74Sagc #include <string.h>
8073f34b00Sagc 
8173f34b00Sagc #ifdef HAVE_UNISTD_H
8273f34b00Sagc #include <unistd.h>
8373f34b00Sagc #endif
8493bf6008Sagc 
8593bf6008Sagc #include "crypto.h"
8693bf6008Sagc #include "keyring.h"
8793bf6008Sagc #include "readerwriter.h"
8893bf6008Sagc #include "netpgpdefs.h"
896715e11aSagc #include "netpgpdigest.h"
90*0294a66bSjhigh #include "netpgpsdk.h"
914b3a3e18Sagc #include "packet.h"
9293bf6008Sagc 
93c9d078dcSchristos static void
takeRSA(const RSA * orsa,pgp_rsa_pubkey_t * pk,pgp_rsa_seckey_t * sk)94c9d078dcSchristos takeRSA(const RSA *orsa, pgp_rsa_pubkey_t *pk, pgp_rsa_seckey_t *sk)
95c9d078dcSchristos {
96c9d078dcSchristos 	const BIGNUM *n, *e, *d, *q, *p;
97c9d078dcSchristos #if OPENSSL_VERSION_NUMBER >= 0x10100000L
98c9d078dcSchristos 	RSA_get0_key(orsa, &n, &e, &d);
99c9d078dcSchristos 	RSA_get0_factors(orsa, &q, &p);
100c9d078dcSchristos #else
101c9d078dcSchristos 	n = orsa->n;
102c9d078dcSchristos 	e = orsa->e;
103c9d078dcSchristos 	d = orsa->d;
104c9d078dcSchristos 	p = orsa->p;
105c9d078dcSchristos 	q = orsa->q;
106c9d078dcSchristos #endif
107c9d078dcSchristos 	if (sk) {
108c9d078dcSchristos 		sk->d = BN_dup(d);
109c9d078dcSchristos 		sk->p = BN_dup(p);
110c9d078dcSchristos 		sk->q = BN_dup(q);
111c9d078dcSchristos 	}
112c9d078dcSchristos 	if (pk) {
113c9d078dcSchristos 		pk->n = BN_dup(n);
114c9d078dcSchristos 		pk->e = BN_dup(e);
115c9d078dcSchristos 	}
116c9d078dcSchristos }
117c9d078dcSchristos 
118c9d078dcSchristos static RSA *
makeRSA(const pgp_rsa_pubkey_t * pubkey,const pgp_rsa_seckey_t * seckey)119c9d078dcSchristos makeRSA(const pgp_rsa_pubkey_t *pubkey, const pgp_rsa_seckey_t *seckey)
120c9d078dcSchristos {
121c9d078dcSchristos 	BIGNUM	*n, *e, *d, *p, *q;
122c9d078dcSchristos 	RSA *orsa;
123c9d078dcSchristos 
124c9d078dcSchristos 	orsa = RSA_new();
125c9d078dcSchristos 	n = BN_dup(pubkey->n);
126c9d078dcSchristos 	e = BN_dup(pubkey->e);
127c9d078dcSchristos 
128c9d078dcSchristos 	if (seckey) {
129c9d078dcSchristos 		d = BN_dup(seckey->d);
130c9d078dcSchristos 		p = BN_dup(seckey->p);
131c9d078dcSchristos 		q = BN_dup(seckey->q);
132c9d078dcSchristos 	} else {
133c9d078dcSchristos 		d = p = q = NULL;
134c9d078dcSchristos 	}
135c9d078dcSchristos 
136c9d078dcSchristos #if OPENSSL_VERSION_NUMBER >= 0x10100000L
137c9d078dcSchristos 	RSA_set0_key(orsa, n, e, d);
138c9d078dcSchristos 	RSA_set0_factors(orsa, p, q);
139c9d078dcSchristos #else
140c9d078dcSchristos 	BN_free(orsa->n);
141c9d078dcSchristos 	BN_free(orsa->e);
142c9d078dcSchristos 	orsa->n = n;
143c9d078dcSchristos 	orsa->e = e;
144c9d078dcSchristos 	if (d) {
145c9d078dcSchristos 		BN_free(orsa->d);
146c9d078dcSchristos 		orsa->d = d;
147c9d078dcSchristos 	}
148c9d078dcSchristos 	if (p) {
149c9d078dcSchristos 		BN_free(orsa->p);
150c9d078dcSchristos 		orsa->p = p;
151c9d078dcSchristos 	}
152c9d078dcSchristos 	if (q) {
153c9d078dcSchristos 		BN_free(orsa->q);
154c9d078dcSchristos 		orsa->q = q;
155c9d078dcSchristos 	}
156c9d078dcSchristos #endif
157c9d078dcSchristos 	return orsa;
158c9d078dcSchristos }
159c9d078dcSchristos 
160c9d078dcSchristos static DSA_SIG *
makeDSA_SIG(const pgp_dsa_sig_t * sig)161c9d078dcSchristos makeDSA_SIG(const pgp_dsa_sig_t *sig)
162c9d078dcSchristos {
163c9d078dcSchristos 	DSA_SIG        *osig;
164c9d078dcSchristos 	BIGNUM	       *r, *s;
165c9d078dcSchristos 
166c9d078dcSchristos 	osig = DSA_SIG_new();
167c9d078dcSchristos 	r = BN_dup(sig->r);
168c9d078dcSchristos 	s = BN_dup(sig->s);
169c9d078dcSchristos 
170c9d078dcSchristos #if OPENSSL_VERSION_NUMBER >= 0x10100000L
171c9d078dcSchristos 	DSA_SIG_set0(osig, r, s);
172c9d078dcSchristos #else
173c9d078dcSchristos 	BN_free(osig->r);
174c9d078dcSchristos 	BN_free(osig->s);
175c9d078dcSchristos 	osig->r = r;
176c9d078dcSchristos 	osig->s = s;
177c9d078dcSchristos #endif
178c9d078dcSchristos 
179c9d078dcSchristos 	return osig;
180c9d078dcSchristos }
181c9d078dcSchristos 
182c9d078dcSchristos static DSA *
makeDSA(const pgp_dsa_pubkey_t * dsa,const pgp_dsa_seckey_t * secdsa)183c9d078dcSchristos makeDSA(const pgp_dsa_pubkey_t *dsa, const pgp_dsa_seckey_t *secdsa)
184c9d078dcSchristos {
185c9d078dcSchristos 	DSA            *odsa;
186c9d078dcSchristos 	BIGNUM	       *p, *q, *g, *y, *x;
187c9d078dcSchristos 
188c9d078dcSchristos 	odsa = DSA_new();
189c9d078dcSchristos 
190c9d078dcSchristos 	p = BN_dup(dsa->p);
191c9d078dcSchristos 	q = BN_dup(dsa->q);
192c9d078dcSchristos 	g = BN_dup(dsa->g);
193c9d078dcSchristos 	y = BN_dup(dsa->y);
194c9d078dcSchristos 	x = secdsa ? secdsa->x : NULL;
195c9d078dcSchristos 
196c9d078dcSchristos #if OPENSSL_VERSION_NUMBER >= 0x10100000L
197c9d078dcSchristos 	DSA_set0_key(odsa, y, x);
198c9d078dcSchristos #else
199c9d078dcSchristos 	BN_free(odsa->p);
200c9d078dcSchristos 	BN_free(odsa->q);
201c9d078dcSchristos 	BN_free(odsa->g);
202c9d078dcSchristos 	BN_free(odsa->pub_key);
203c9d078dcSchristos 	odsa->p = p;
204c9d078dcSchristos 	odsa->q = q;
205c9d078dcSchristos 	odsa->g = g;
206c9d078dcSchristos 	odsa->pub_key = y;
207c9d078dcSchristos 	if (x) {
208c9d078dcSchristos 		BN_free(odsa->priv_key);
209c9d078dcSchristos 		odsa->priv_key = x;
210c9d078dcSchristos 	}
211c9d078dcSchristos #endif
212c9d078dcSchristos 	return odsa;
213c9d078dcSchristos }
214c9d078dcSchristos 
215c9d078dcSchristos static void
takeDSA(const DSA * odsa,pgp_dsa_seckey_t * sk)216c9d078dcSchristos takeDSA(const DSA *odsa, pgp_dsa_seckey_t *sk)
217c9d078dcSchristos {
218c9d078dcSchristos 	const BIGNUM *x;
219c9d078dcSchristos #if OPENSSL_VERSION_NUMBER >= 0x10100000L
220c9d078dcSchristos 	DSA_get0_key(odsa, NULL, &x);
221c9d078dcSchristos #else
222c9d078dcSchristos 	x = odsa->priv_key;
223c9d078dcSchristos #endif
224c9d078dcSchristos 	sk->x = BN_dup(x);
225c9d078dcSchristos }
22693bf6008Sagc 
227*0294a66bSjhigh static ECDSA_SIG *
makeECDSADSA_SIG(const pgp_ecdsa_sig_t * sig)228*0294a66bSjhigh makeECDSADSA_SIG(const pgp_ecdsa_sig_t *sig)
229*0294a66bSjhigh {
230*0294a66bSjhigh 	ECDSA_SIG        *osig;
231*0294a66bSjhigh 	BIGNUM         *r, *s;
232*0294a66bSjhigh 
233*0294a66bSjhigh 	osig = ECDSA_SIG_new();
234*0294a66bSjhigh 	r = BN_dup(sig->r);
235*0294a66bSjhigh 	s = BN_dup(sig->s);
236*0294a66bSjhigh 
237*0294a66bSjhigh #if OPENSSL_VERSION_NUMBER >= 0x10100000L
238*0294a66bSjhigh 	ECDSA_SIG_set0(osig, r, s);
239*0294a66bSjhigh #else
240*0294a66bSjhigh 	BN_free(osig->r);
241*0294a66bSjhigh 	BN_free(osig->s);
242*0294a66bSjhigh 	osig->r = r;
243*0294a66bSjhigh 	osig->s = s;
244*0294a66bSjhigh #endif
245*0294a66bSjhigh 
246*0294a66bSjhigh 	return osig;
247*0294a66bSjhigh }
248*0294a66bSjhigh 
249*0294a66bSjhigh static EC_KEY *
makeECDSA(const pgp_ecdsa_pubkey_t * ecdsa,const pgp_ecdsa_seckey_t * sececdsa)250*0294a66bSjhigh makeECDSA(const pgp_ecdsa_pubkey_t *ecdsa, const pgp_ecdsa_seckey_t *sececdsa)
251*0294a66bSjhigh {
252*0294a66bSjhigh 	EC_KEY 		*key;
253*0294a66bSjhigh 	BIGNUM 		*x;
254*0294a66bSjhigh 	BIGNUM 		*y;
255*0294a66bSjhigh 	EC_GROUP 	*group;
256*0294a66bSjhigh 	EC_POINT 	*pub_key;
257*0294a66bSjhigh 	EC_POINT 	*point;
258*0294a66bSjhigh 	int nid;
259*0294a66bSjhigh 
260*0294a66bSjhigh 	key = EC_KEY_new();
261*0294a66bSjhigh 	x = BN_new();
262*0294a66bSjhigh 	y = BN_new();
263*0294a66bSjhigh 
264*0294a66bSjhigh 	nid = ecdsa_nid(ecdsa);
265*0294a66bSjhigh 	if (nid == -1) {
266*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to determine NID\n");
267*0294a66bSjhigh 		return 0;
268*0294a66bSjhigh 	}
269*0294a66bSjhigh 
270*0294a66bSjhigh 	group = EC_GROUP_new_by_curve_name(nid);
271*0294a66bSjhigh 	if (group == NULL) {
272*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to get group for specified NID\n");
273*0294a66bSjhigh 		return 0;
274*0294a66bSjhigh 	}
275*0294a66bSjhigh 
276*0294a66bSjhigh 	pub_key = EC_POINT_new(group);
277*0294a66bSjhigh 	if (pub_key == NULL) {
278*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to alloc point\n");
279*0294a66bSjhigh 		return 0;
280*0294a66bSjhigh 	}
281*0294a66bSjhigh 
282*0294a66bSjhigh 	point = EC_POINT_bn2point(group, ecdsa->p, NULL, NULL);
283*0294a66bSjhigh 	if (point == NULL) {
284*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to conv BN to point\n");
285*0294a66bSjhigh 		return 0;
286*0294a66bSjhigh 	}
287*0294a66bSjhigh 
288*0294a66bSjhigh 
289*0294a66bSjhigh 	if ((EC_POINT_get_affine_coordinates(group, point, x, y, NULL)) == 0) {
290*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to get coordinates from point\n");
291*0294a66bSjhigh 		return 0;
292*0294a66bSjhigh 	}
293*0294a66bSjhigh 
294*0294a66bSjhigh 	if ((EC_POINT_set_affine_coordinates(group, pub_key, x, y, NULL)) == 0) {
295*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to set coordinates from point\n");
296*0294a66bSjhigh 		return 0;
297*0294a66bSjhigh 	}
298*0294a66bSjhigh 
299*0294a66bSjhigh 	if ((EC_KEY_set_group(key, group)) == 0) {
300*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to set group for key\n");
301*0294a66bSjhigh 		return 0;
302*0294a66bSjhigh 	}
303*0294a66bSjhigh 
304*0294a66bSjhigh 	if ((EC_KEY_set_public_key(key, pub_key)) == 0) {
305*0294a66bSjhigh 		(void) fprintf(stderr,"makeECDSA: failed to set pubkey for key\n");
306*0294a66bSjhigh 		return 0;
307*0294a66bSjhigh 	}
308*0294a66bSjhigh 
309*0294a66bSjhigh 	if (sececdsa) {
310*0294a66bSjhigh 		if ((EC_KEY_set_private_key(key, sececdsa->x)) == 0) {
311*0294a66bSjhigh 			(void) fprintf(stderr,"makeECDSA: failed to set seckey for key\n");
312*0294a66bSjhigh 			return 0;
313*0294a66bSjhigh 		}
314*0294a66bSjhigh 
315*0294a66bSjhigh 		if ((EC_POINT_mul(group, pub_key, sececdsa->x, NULL, NULL, NULL)) == 0) {
316*0294a66bSjhigh 			(void) fprintf(stderr,"makeECDSA: failed to calculate generator\n");
317*0294a66bSjhigh 			return 0;
318*0294a66bSjhigh 		}
319*0294a66bSjhigh 	}
320*0294a66bSjhigh 
321*0294a66bSjhigh 	return key;
322*0294a66bSjhigh }
323*0294a66bSjhigh 
32493bf6008Sagc static void
test_seckey(const pgp_seckey_t * seckey)325fc1f8641Sagc test_seckey(const pgp_seckey_t *seckey)
32693bf6008Sagc {
327c9d078dcSchristos 	RSA *test = makeRSA(&seckey->pubkey.key.rsa, &seckey->key.rsa);
32893bf6008Sagc 
329bcfd8565Sagc 	if (RSA_check_key(test) != 1) {
330bcfd8565Sagc 		(void) fprintf(stderr,
3313326c4c5Sagc 			"test_seckey: RSA_check_key failed\n");
332bcfd8565Sagc 	}
33393bf6008Sagc 	RSA_free(test);
33493bf6008Sagc }
33593bf6008Sagc 
3367affbacaSagc static int
md5_init(pgp_hash_t * hash)337fc1f8641Sagc md5_init(pgp_hash_t *hash)
33893bf6008Sagc {
339bcfd8565Sagc 	if (hash->data) {
340bcfd8565Sagc 		(void) fprintf(stderr, "md5_init: hash data non-null\n");
341bcfd8565Sagc 	}
3427affbacaSagc 	if ((hash->data = calloc(1, sizeof(MD5_CTX))) == NULL) {
3437affbacaSagc 		(void) fprintf(stderr, "md5_init: bad alloc\n");
3447affbacaSagc 		return 0;
3457affbacaSagc 	}
34693bf6008Sagc 	MD5_Init(hash->data);
3477affbacaSagc 	return 1;
34893bf6008Sagc }
34993bf6008Sagc 
35093bf6008Sagc static void
md5_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)351fc1f8641Sagc md5_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
35293bf6008Sagc {
35393bf6008Sagc 	MD5_Update(hash->data, data, length);
35493bf6008Sagc }
35593bf6008Sagc 
35693bf6008Sagc static unsigned
md5_finish(pgp_hash_t * hash,uint8_t * out)357fc1f8641Sagc md5_finish(pgp_hash_t *hash, uint8_t *out)
35893bf6008Sagc {
35993bf6008Sagc 	MD5_Final(out, hash->data);
36093bf6008Sagc 	free(hash->data);
36193bf6008Sagc 	hash->data = NULL;
36293bf6008Sagc 	return 16;
36393bf6008Sagc }
36493bf6008Sagc 
365fc1f8641Sagc static const pgp_hash_t md5 = {
366fc1f8641Sagc 	PGP_HASH_MD5,
367b1b58706Sagc 	MD5_DIGEST_LENGTH,
368b1b58706Sagc 	"MD5",
369b1b58706Sagc 	md5_init,
370b1b58706Sagc 	md5_add,
371b1b58706Sagc 	md5_finish,
372b1b58706Sagc 	NULL
373b1b58706Sagc };
37493bf6008Sagc 
37593bf6008Sagc /**
37693bf6008Sagc    \ingroup Core_Crypto
37793bf6008Sagc    \brief Initialise to MD5
37893bf6008Sagc    \param hash Hash to initialise
37993bf6008Sagc */
38093bf6008Sagc void
pgp_hash_md5(pgp_hash_t * hash)381fc1f8641Sagc pgp_hash_md5(pgp_hash_t *hash)
38293bf6008Sagc {
38393bf6008Sagc 	*hash = md5;
38493bf6008Sagc }
38593bf6008Sagc 
3867affbacaSagc static int
sha1_init(pgp_hash_t * hash)387fc1f8641Sagc sha1_init(pgp_hash_t *hash)
38893bf6008Sagc {
389bcfd8565Sagc 	if (hash->data) {
390bcfd8565Sagc 		(void) fprintf(stderr, "sha1_init: hash data non-null\n");
391bcfd8565Sagc 	}
3927affbacaSagc 	if ((hash->data = calloc(1, sizeof(SHA_CTX))) == NULL) {
3937affbacaSagc 		(void) fprintf(stderr, "sha1_init: bad alloc\n");
3947affbacaSagc 		return 0;
3957affbacaSagc 	}
39693bf6008Sagc 	SHA1_Init(hash->data);
3977affbacaSagc 	return 1;
39893bf6008Sagc }
39993bf6008Sagc 
40093bf6008Sagc static void
sha1_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)401fc1f8641Sagc sha1_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
40293bf6008Sagc {
403fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
40469d4f30fSagc 		hexdump(stderr, "sha1_add", data, length);
40593bf6008Sagc 	}
40693bf6008Sagc 	SHA1_Update(hash->data, data, length);
40793bf6008Sagc }
40893bf6008Sagc 
40993bf6008Sagc static unsigned
sha1_finish(pgp_hash_t * hash,uint8_t * out)410fc1f8641Sagc sha1_finish(pgp_hash_t *hash, uint8_t *out)
41193bf6008Sagc {
41293bf6008Sagc 	SHA1_Final(out, hash->data);
413fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
414fc1f8641Sagc 		hexdump(stderr, "sha1_finish", out, PGP_SHA1_HASH_SIZE);
41593bf6008Sagc 	}
416b491010dSagc 	free(hash->data);
41793bf6008Sagc 	hash->data = NULL;
418fc1f8641Sagc 	return PGP_SHA1_HASH_SIZE;
41993bf6008Sagc }
42093bf6008Sagc 
421fc1f8641Sagc static const pgp_hash_t sha1 = {
422fc1f8641Sagc 	PGP_HASH_SHA1,
423fc1f8641Sagc 	PGP_SHA1_HASH_SIZE,
424b1b58706Sagc 	"SHA1",
425b1b58706Sagc 	sha1_init,
426b1b58706Sagc 	sha1_add,
427b1b58706Sagc 	sha1_finish,
428b1b58706Sagc 	NULL
429b1b58706Sagc };
43093bf6008Sagc 
43193bf6008Sagc /**
43293bf6008Sagc    \ingroup Core_Crypto
43393bf6008Sagc    \brief Initialise to SHA1
43493bf6008Sagc    \param hash Hash to initialise
43593bf6008Sagc */
43693bf6008Sagc void
pgp_hash_sha1(pgp_hash_t * hash)437fc1f8641Sagc pgp_hash_sha1(pgp_hash_t *hash)
43893bf6008Sagc {
43993bf6008Sagc 	*hash = sha1;
44093bf6008Sagc }
44193bf6008Sagc 
4427affbacaSagc static int
sha256_init(pgp_hash_t * hash)443fc1f8641Sagc sha256_init(pgp_hash_t *hash)
44493bf6008Sagc {
445bcfd8565Sagc 	if (hash->data) {
446bcfd8565Sagc 		(void) fprintf(stderr, "sha256_init: hash data non-null\n");
447bcfd8565Sagc 	}
4487affbacaSagc 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
4497affbacaSagc 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
4507affbacaSagc 		return 0;
4517affbacaSagc 	}
45293bf6008Sagc 	SHA256_Init(hash->data);
4537affbacaSagc 	return 1;
45493bf6008Sagc }
45593bf6008Sagc 
45693bf6008Sagc static void
sha256_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)457fc1f8641Sagc sha256_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
45893bf6008Sagc {
459fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
46069d4f30fSagc 		hexdump(stderr, "sha256_add", data, length);
46193bf6008Sagc 	}
46293bf6008Sagc 	SHA256_Update(hash->data, data, length);
46393bf6008Sagc }
46493bf6008Sagc 
46593bf6008Sagc static unsigned
sha256_finish(pgp_hash_t * hash,uint8_t * out)466fc1f8641Sagc sha256_finish(pgp_hash_t *hash, uint8_t *out)
46793bf6008Sagc {
46893bf6008Sagc 	SHA256_Final(out, hash->data);
469fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
47069d4f30fSagc 		hexdump(stderr, "sha1_finish", out, SHA256_DIGEST_LENGTH);
47193bf6008Sagc 	}
472b491010dSagc 	free(hash->data);
47393bf6008Sagc 	hash->data = NULL;
47493bf6008Sagc 	return SHA256_DIGEST_LENGTH;
47593bf6008Sagc }
47693bf6008Sagc 
477fc1f8641Sagc static const pgp_hash_t sha256 = {
478fc1f8641Sagc 	PGP_HASH_SHA256,
479b1b58706Sagc 	SHA256_DIGEST_LENGTH,
480b1b58706Sagc 	"SHA256",
481b1b58706Sagc 	sha256_init,
482b1b58706Sagc 	sha256_add,
483b1b58706Sagc 	sha256_finish,
484b1b58706Sagc 	NULL
485b1b58706Sagc };
48693bf6008Sagc 
48793bf6008Sagc void
pgp_hash_sha256(pgp_hash_t * hash)488fc1f8641Sagc pgp_hash_sha256(pgp_hash_t *hash)
48993bf6008Sagc {
49093bf6008Sagc 	*hash = sha256;
49193bf6008Sagc }
49293bf6008Sagc 
49393bf6008Sagc /*
49493bf6008Sagc  * SHA384
49593bf6008Sagc  */
4967affbacaSagc static int
sha384_init(pgp_hash_t * hash)497fc1f8641Sagc sha384_init(pgp_hash_t *hash)
49893bf6008Sagc {
499bcfd8565Sagc 	if (hash->data) {
500bcfd8565Sagc 		(void) fprintf(stderr, "sha384_init: hash data non-null\n");
501bcfd8565Sagc 	}
5027affbacaSagc 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
50369d4f30fSagc 		(void) fprintf(stderr, "sha384_init: bad alloc\n");
5047affbacaSagc 		return 0;
5057affbacaSagc 	}
50693bf6008Sagc 	SHA384_Init(hash->data);
5077affbacaSagc 	return 1;
50893bf6008Sagc }
50993bf6008Sagc 
51093bf6008Sagc static void
sha384_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)511fc1f8641Sagc sha384_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
51293bf6008Sagc {
513fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
51469d4f30fSagc 		hexdump(stderr, "sha384_add", data, length);
51593bf6008Sagc 	}
51693bf6008Sagc 	SHA384_Update(hash->data, data, length);
51793bf6008Sagc }
51893bf6008Sagc 
51993bf6008Sagc static unsigned
sha384_finish(pgp_hash_t * hash,uint8_t * out)520fc1f8641Sagc sha384_finish(pgp_hash_t *hash, uint8_t *out)
52193bf6008Sagc {
52293bf6008Sagc 	SHA384_Final(out, hash->data);
523fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
52469d4f30fSagc 		hexdump(stderr, "sha384_finish", out, SHA384_DIGEST_LENGTH);
52593bf6008Sagc 	}
526b491010dSagc 	free(hash->data);
52793bf6008Sagc 	hash->data = NULL;
52893bf6008Sagc 	return SHA384_DIGEST_LENGTH;
52993bf6008Sagc }
53093bf6008Sagc 
531fc1f8641Sagc static const pgp_hash_t sha384 = {
532fc1f8641Sagc 	PGP_HASH_SHA384,
533b1b58706Sagc 	SHA384_DIGEST_LENGTH,
534b1b58706Sagc 	"SHA384",
535b1b58706Sagc 	sha384_init,
536b1b58706Sagc 	sha384_add,
537b1b58706Sagc 	sha384_finish,
538b1b58706Sagc 	NULL
539b1b58706Sagc };
54093bf6008Sagc 
54193bf6008Sagc void
pgp_hash_sha384(pgp_hash_t * hash)542fc1f8641Sagc pgp_hash_sha384(pgp_hash_t *hash)
54393bf6008Sagc {
54493bf6008Sagc 	*hash = sha384;
54593bf6008Sagc }
54693bf6008Sagc 
54793bf6008Sagc /*
54893bf6008Sagc  * SHA512
54993bf6008Sagc  */
5507affbacaSagc static int
sha512_init(pgp_hash_t * hash)551fc1f8641Sagc sha512_init(pgp_hash_t *hash)
55293bf6008Sagc {
553bcfd8565Sagc 	if (hash->data) {
554bcfd8565Sagc 		(void) fprintf(stderr, "sha512_init: hash data non-null\n");
555bcfd8565Sagc 	}
5567affbacaSagc 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
5577affbacaSagc 		(void) fprintf(stderr, "sha512_init: bad alloc\n");
5587affbacaSagc 		return 0;
5597affbacaSagc 	}
56093bf6008Sagc 	SHA512_Init(hash->data);
5617affbacaSagc 	return 1;
56293bf6008Sagc }
56393bf6008Sagc 
56493bf6008Sagc static void
sha512_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)565fc1f8641Sagc sha512_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
56693bf6008Sagc {
567fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
56869d4f30fSagc 		hexdump(stderr, "sha512_add", data, length);
56993bf6008Sagc 	}
57093bf6008Sagc 	SHA512_Update(hash->data, data, length);
57193bf6008Sagc }
57293bf6008Sagc 
57393bf6008Sagc static unsigned
sha512_finish(pgp_hash_t * hash,uint8_t * out)574fc1f8641Sagc sha512_finish(pgp_hash_t *hash, uint8_t *out)
57593bf6008Sagc {
57693bf6008Sagc 	SHA512_Final(out, hash->data);
577fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
57869d4f30fSagc 		hexdump(stderr, "sha512_finish", out, SHA512_DIGEST_LENGTH);
57993bf6008Sagc 	}
580b491010dSagc 	free(hash->data);
58193bf6008Sagc 	hash->data = NULL;
58293bf6008Sagc 	return SHA512_DIGEST_LENGTH;
58393bf6008Sagc }
58493bf6008Sagc 
585fc1f8641Sagc static const pgp_hash_t sha512 = {
586fc1f8641Sagc 	PGP_HASH_SHA512,
587b1b58706Sagc 	SHA512_DIGEST_LENGTH,
588b1b58706Sagc 	"SHA512",
589b1b58706Sagc 	sha512_init,
590b1b58706Sagc 	sha512_add,
591b1b58706Sagc 	sha512_finish,
592b1b58706Sagc 	NULL
593b1b58706Sagc };
59493bf6008Sagc 
59593bf6008Sagc void
pgp_hash_sha512(pgp_hash_t * hash)596fc1f8641Sagc pgp_hash_sha512(pgp_hash_t *hash)
59793bf6008Sagc {
59893bf6008Sagc 	*hash = sha512;
59993bf6008Sagc }
60093bf6008Sagc 
60193bf6008Sagc /*
60293bf6008Sagc  * SHA224
60393bf6008Sagc  */
60493bf6008Sagc 
6057affbacaSagc static int
sha224_init(pgp_hash_t * hash)606fc1f8641Sagc sha224_init(pgp_hash_t *hash)
60793bf6008Sagc {
608bcfd8565Sagc 	if (hash->data) {
609bcfd8565Sagc 		(void) fprintf(stderr, "sha224_init: hash data non-null\n");
610bcfd8565Sagc 	}
6117affbacaSagc 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
6127affbacaSagc 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
6137affbacaSagc 		return 0;
6147affbacaSagc 	}
61593bf6008Sagc 	SHA224_Init(hash->data);
6167affbacaSagc 	return 1;
61793bf6008Sagc }
61893bf6008Sagc 
61993bf6008Sagc static void
sha224_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)620fc1f8641Sagc sha224_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
62193bf6008Sagc {
622fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
62369d4f30fSagc 		hexdump(stderr, "sha224_add", data, length);
62493bf6008Sagc 	}
62593bf6008Sagc 	SHA224_Update(hash->data, data, length);
62693bf6008Sagc }
62793bf6008Sagc 
62893bf6008Sagc static unsigned
sha224_finish(pgp_hash_t * hash,uint8_t * out)629fc1f8641Sagc sha224_finish(pgp_hash_t *hash, uint8_t *out)
63093bf6008Sagc {
63193bf6008Sagc 	SHA224_Final(out, hash->data);
632fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
63369d4f30fSagc 		hexdump(stderr, "sha224_finish", out, SHA224_DIGEST_LENGTH);
63493bf6008Sagc 	}
635b491010dSagc 	free(hash->data);
63693bf6008Sagc 	hash->data = NULL;
63793bf6008Sagc 	return SHA224_DIGEST_LENGTH;
63893bf6008Sagc }
63993bf6008Sagc 
640fc1f8641Sagc static const pgp_hash_t sha224 = {
641fc1f8641Sagc 	PGP_HASH_SHA224,
642b1b58706Sagc 	SHA224_DIGEST_LENGTH,
643b1b58706Sagc 	"SHA224",
644b1b58706Sagc 	sha224_init,
645b1b58706Sagc 	sha224_add,
646b1b58706Sagc 	sha224_finish,
647b1b58706Sagc 	NULL
648b1b58706Sagc };
64993bf6008Sagc 
65093bf6008Sagc void
pgp_hash_sha224(pgp_hash_t * hash)651fc1f8641Sagc pgp_hash_sha224(pgp_hash_t *hash)
65293bf6008Sagc {
65393bf6008Sagc 	*hash = sha224;
65493bf6008Sagc }
65593bf6008Sagc 
6564b3a3e18Sagc unsigned
pgp_dsa_verify(const uint8_t * hash,size_t hash_length,const pgp_dsa_sig_t * sig,const pgp_dsa_pubkey_t * dsa)657fc1f8641Sagc pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
658fc1f8641Sagc 	       const pgp_dsa_sig_t *sig,
659fc1f8641Sagc 	       const pgp_dsa_pubkey_t *dsa)
66093bf6008Sagc {
6610df5e957Sagc 	unsigned	qlen;
662c9d078dcSchristos 	DSA_SIG        *osig = makeDSA_SIG(sig);
663c9d078dcSchristos 	DSA	       *odsa = makeDSA(dsa, NULL);
66493bf6008Sagc 	int             ret;
66593bf6008Sagc 
666fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
66747561e26Sagc 		hexdump(stderr, "input hash", hash, hash_length);
668c9d078dcSchristos 		(void) fprintf(stderr, "Q=%d\n", BN_num_bytes(dsa->q));
66993bf6008Sagc 	}
670c9d078dcSchristos 	if ((qlen = (unsigned)BN_num_bytes(dsa->q)) < hash_length) {
67193bf6008Sagc 		hash_length = qlen;
672b1b58706Sagc 	}
673efdd9dbaSagc 	ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
674fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
675b1b58706Sagc 		(void) fprintf(stderr, "ret=%d\n", ret);
67693bf6008Sagc 	}
677bcfd8565Sagc 	if (ret < 0) {
678fc1f8641Sagc 		(void) fprintf(stderr, "pgp_dsa_verify: DSA verification\n");
679bcfd8565Sagc 		return 0;
680bcfd8565Sagc 	}
68193bf6008Sagc 
68293bf6008Sagc 	DSA_free(odsa);
68393bf6008Sagc 	DSA_SIG_free(osig);
68493bf6008Sagc 
685b491010dSagc 	return (unsigned)ret;
68693bf6008Sagc }
68793bf6008Sagc 
688*0294a66bSjhigh unsigned
pgp_ecdsa_verify(const uint8_t * hash,size_t hash_length,const pgp_ecdsa_sig_t * sig,const pgp_ecdsa_pubkey_t * ecdsa)689*0294a66bSjhigh pgp_ecdsa_verify(const uint8_t *hash, size_t hash_length,
690*0294a66bSjhigh 		 const pgp_ecdsa_sig_t *sig,
691*0294a66bSjhigh 		 const pgp_ecdsa_pubkey_t *ecdsa)
692*0294a66bSjhigh {
693*0294a66bSjhigh 	unsigned        qlen;
694*0294a66bSjhigh 	ECDSA_SIG        *osig = makeECDSADSA_SIG(sig);
695*0294a66bSjhigh 	EC_KEY          *oecdsa = makeECDSA(ecdsa, NULL);
696*0294a66bSjhigh 	int             ret;
697*0294a66bSjhigh 
698*0294a66bSjhigh 	if (pgp_get_debug_level(__FILE__)) {
699*0294a66bSjhigh 		hexdump(stderr, "input hash", hash, hash_length);
700*0294a66bSjhigh 	}
701*0294a66bSjhigh 
702*0294a66bSjhigh 	ret = ECDSA_do_verify(hash, (int)hash_length, osig, oecdsa);
703*0294a66bSjhigh 
704*0294a66bSjhigh 	if (pgp_get_debug_level(__FILE__)) {
705*0294a66bSjhigh 		(void) fprintf(stderr, "ret=%d\n", ret);
706*0294a66bSjhigh 	}
707*0294a66bSjhigh 
708*0294a66bSjhigh 	if (ret <= 0) {
709*0294a66bSjhigh 		(void) fprintf(stderr, "pgp_ecdsa_verify: ECDSA verification failed\n");
710*0294a66bSjhigh 		return 0;
711*0294a66bSjhigh 	}
712*0294a66bSjhigh 
713*0294a66bSjhigh 	ECDSA_SIG_free(osig);
714*0294a66bSjhigh 
715*0294a66bSjhigh 	return (unsigned)ret;
716*0294a66bSjhigh }
717*0294a66bSjhigh 
71893bf6008Sagc /**
71993bf6008Sagc    \ingroup Core_Crypto
72093bf6008Sagc    \brief Recovers message digest from the signature
72193bf6008Sagc    \param out Where to write decrypted data to
72293bf6008Sagc    \param in Encrypted data
72393bf6008Sagc    \param length Length of encrypted data
7240df5e957Sagc    \param pubkey RSA public key
72593bf6008Sagc    \return size of recovered message digest
72693bf6008Sagc */
72793bf6008Sagc int
pgp_rsa_public_decrypt(uint8_t * out,const uint8_t * in,size_t length,const pgp_rsa_pubkey_t * pubkey)728fc1f8641Sagc pgp_rsa_public_decrypt(uint8_t *out,
729b15ec256Sagc 			const uint8_t *in,
7300df5e957Sagc 			size_t length,
731fc1f8641Sagc 			const pgp_rsa_pubkey_t *pubkey)
73293bf6008Sagc {
733c9d078dcSchristos 	RSA            *orsa = makeRSA(pubkey, NULL);
734c9d078dcSchristos 	int             ret;
73593bf6008Sagc 
736c9d078dcSchristos 	ret = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
73793bf6008Sagc 
73893bf6008Sagc 	RSA_free(orsa);
73993bf6008Sagc 
740c9d078dcSchristos 	return ret;
74193bf6008Sagc }
74293bf6008Sagc 
74393bf6008Sagc /**
74493bf6008Sagc    \ingroup Core_Crypto
74593bf6008Sagc    \brief Signs data with RSA
74693bf6008Sagc    \param out Where to write signature
74793bf6008Sagc    \param in Data to sign
74893bf6008Sagc    \param length Length of data
7490df5e957Sagc    \param seckey RSA secret key
7500df5e957Sagc    \param pubkey RSA public key
75193bf6008Sagc    \return number of bytes decrypted
75293bf6008Sagc */
75393bf6008Sagc int
pgp_rsa_private_encrypt(uint8_t * out,const uint8_t * in,size_t length,const pgp_rsa_seckey_t * seckey,const pgp_rsa_pubkey_t * pubkey)754fc1f8641Sagc pgp_rsa_private_encrypt(uint8_t *out,
755b15ec256Sagc 			const uint8_t *in,
756b1b58706Sagc 			size_t length,
757fc1f8641Sagc 			const pgp_rsa_seckey_t *seckey,
758fc1f8641Sagc 			const pgp_rsa_pubkey_t *pubkey)
75993bf6008Sagc {
760c9d078dcSchristos 	RSA            *orsa = makeRSA(pubkey, seckey);
761c9d078dcSchristos 	int             ret;
76293bf6008Sagc 
763c9d078dcSchristos 	if (seckey->d == NULL) {
764bcfd8565Sagc 		(void) fprintf(stderr, "orsa is not set\n");
765bcfd8565Sagc 		return 0;
766bcfd8565Sagc 	}
767bcfd8565Sagc 	if (RSA_check_key(orsa) != 1) {
768bcfd8565Sagc 		(void) fprintf(stderr, "RSA_check_key is not set\n");
769bcfd8565Sagc 		return 0;
770bcfd8565Sagc 	}
77193bf6008Sagc 	/* end debug */
77293bf6008Sagc 
773c9d078dcSchristos 	ret = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
77493bf6008Sagc 
77593bf6008Sagc 	RSA_free(orsa);
77693bf6008Sagc 
777c9d078dcSchristos 	return ret;
77893bf6008Sagc }
77993bf6008Sagc 
78093bf6008Sagc /**
78193bf6008Sagc \ingroup Core_Crypto
78293bf6008Sagc \brief Decrypts RSA-encrypted data
78393bf6008Sagc \param out Where to write the plaintext
78493bf6008Sagc \param in Encrypted data
78593bf6008Sagc \param length Length of encrypted data
7860df5e957Sagc \param seckey RSA secret key
7870df5e957Sagc \param pubkey RSA public key
78893bf6008Sagc \return size of recovered plaintext
78993bf6008Sagc */
79093bf6008Sagc int
pgp_rsa_private_decrypt(uint8_t * out,const uint8_t * in,size_t length,const pgp_rsa_seckey_t * seckey,const pgp_rsa_pubkey_t * pubkey)791fc1f8641Sagc pgp_rsa_private_decrypt(uint8_t *out,
792b15ec256Sagc 			const uint8_t *in,
7930df5e957Sagc 			size_t length,
794fc1f8641Sagc 			const pgp_rsa_seckey_t *seckey,
795fc1f8641Sagc 			const pgp_rsa_pubkey_t *pubkey)
79693bf6008Sagc {
797c9d078dcSchristos 	RSA            *keypair = makeRSA(pubkey, seckey);
79893bf6008Sagc 	int             n;
79993bf6008Sagc 	char            errbuf[1024];
80093bf6008Sagc 
8010df5e957Sagc 	if (RSA_check_key(keypair) != 1) {
802bcfd8565Sagc 		(void) fprintf(stderr, "RSA_check_key is not set\n");
803bcfd8565Sagc 		return 0;
804bcfd8565Sagc 	}
80593bf6008Sagc 	/* end debug */
80693bf6008Sagc 
8070df5e957Sagc 	n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING);
80893bf6008Sagc 
809fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
810fc1f8641Sagc 		printf("pgp_rsa_private_decrypt: n=%d\n",n);
81193bf6008Sagc 	}
81293bf6008Sagc 
81393bf6008Sagc 	errbuf[0] = '\0';
81493bf6008Sagc 	if (n == -1) {
81593bf6008Sagc 		unsigned long   err = ERR_get_error();
8160df5e957Sagc 
81793bf6008Sagc 		ERR_error_string(err, &errbuf[0]);
8180df5e957Sagc 		(void) fprintf(stderr, "openssl error : %s\n", errbuf);
81993bf6008Sagc 	}
8200df5e957Sagc 	RSA_free(keypair);
82193bf6008Sagc 
82293bf6008Sagc 	return n;
82393bf6008Sagc }
82493bf6008Sagc 
82593bf6008Sagc /**
82693bf6008Sagc    \ingroup Core_Crypto
82793bf6008Sagc    \brief RSA-encrypts data
82893bf6008Sagc    \param out Where to write the encrypted data
82993bf6008Sagc    \param in Plaintext
83093bf6008Sagc    \param length Size of plaintext
8310df5e957Sagc    \param pubkey RSA Public Key
83293bf6008Sagc */
83393bf6008Sagc int
pgp_rsa_public_encrypt(uint8_t * out,const uint8_t * in,size_t length,const pgp_rsa_pubkey_t * pubkey)834fc1f8641Sagc pgp_rsa_public_encrypt(uint8_t *out,
835b15ec256Sagc 			const uint8_t *in,
836b1b58706Sagc 			size_t length,
837fc1f8641Sagc 			const pgp_rsa_pubkey_t *pubkey)
83893bf6008Sagc {
839c9d078dcSchristos 	RSA            *orsa = makeRSA(pubkey, NULL);
84093bf6008Sagc 	int             n;
84193bf6008Sagc 
842fc1f8641Sagc 	/* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */
84393bf6008Sagc 
84493bf6008Sagc 	/* printf("len: %ld\n", length); */
845fc1f8641Sagc 	/* pgp_print_bn("n: ", orsa->n); */
846fc1f8641Sagc 	/* pgp_print_bn("e: ", orsa->e); */
847efdd9dbaSagc 	n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
84893bf6008Sagc 
84993bf6008Sagc 	if (n == -1) {
85093bf6008Sagc 		BIO            *fd_out;
851b1b58706Sagc 
85293bf6008Sagc 		fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
85393bf6008Sagc 		ERR_print_errors(fd_out);
85493bf6008Sagc 	}
85593bf6008Sagc 	RSA_free(orsa);
85693bf6008Sagc 
85793bf6008Sagc 	return n;
85893bf6008Sagc }
85993bf6008Sagc 
86093bf6008Sagc /**
86193bf6008Sagc    \ingroup Core_Crypto
86293bf6008Sagc    \brief Finalise openssl
863fc1f8641Sagc    \note Would usually call pgp_finish() instead
864fc1f8641Sagc    \sa pgp_finish()
86593bf6008Sagc */
86693bf6008Sagc void
pgp_crypto_finish(void)867fc1f8641Sagc pgp_crypto_finish(void)
86893bf6008Sagc {
86993bf6008Sagc 	CRYPTO_cleanup_all_ex_data();
870c9d078dcSchristos #if OPENSSL_VERSION_NUMBER < 0x10100000L
871efdd9dbaSagc 	ERR_remove_state((unsigned long)0);
872c9d078dcSchristos #endif
87393bf6008Sagc }
87493bf6008Sagc 
87593bf6008Sagc /**
87693bf6008Sagc    \ingroup Core_Hashes
87793bf6008Sagc    \brief Get Hash name
87893bf6008Sagc    \param hash Hash struct
87993bf6008Sagc    \return Hash name
88093bf6008Sagc */
88193bf6008Sagc const char     *
pgp_text_from_hash(pgp_hash_t * hash)882fc1f8641Sagc pgp_text_from_hash(pgp_hash_t *hash)
88393bf6008Sagc {
88493bf6008Sagc 	return hash->name;
88593bf6008Sagc }
88693bf6008Sagc 
88793bf6008Sagc /**
88893bf6008Sagc  \ingroup HighLevel_KeyGenerate
88993bf6008Sagc  \brief Generates an RSA keypair
89093bf6008Sagc  \param numbits Modulus size
89193bf6008Sagc  \param e Public Exponent
89293bf6008Sagc  \param keydata Pointer to keydata struct to hold new key
8934b3a3e18Sagc  \return 1 if key generated successfully; otherwise 0
894fc1f8641Sagc  \note It is the caller's responsibility to call pgp_keydata_free(keydata)
89593bf6008Sagc */
89657324b9fSagc static unsigned
rsa_generate_keypair(pgp_key_t * keydata,const int numbits,const unsigned long e,const char * hashalg,const char * cipher)897fc1f8641Sagc rsa_generate_keypair(pgp_key_t *keydata,
89857324b9fSagc 			const int numbits,
899f0264dceSagc 			const unsigned long e,
9003dc7aea1Sagc 			const char *hashalg,
9013dc7aea1Sagc 			const char *cipher)
90293bf6008Sagc {
903fc1f8641Sagc 	pgp_seckey_t *seckey;
904b491010dSagc 	RSA            *rsa;
905b491010dSagc 	BN_CTX         *ctx;
906fc1f8641Sagc 	pgp_output_t *output;
907fc1f8641Sagc 	pgp_memory_t   *mem;
908c9d078dcSchristos 	BIGNUM *bne;
909c9d078dcSchristos 	pgp_rsa_pubkey_t *pk;
910c9d078dcSchristos 	pgp_rsa_seckey_t *sk;
91193bf6008Sagc 
912b491010dSagc 	ctx = BN_CTX_new();
913fc1f8641Sagc 	pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
914fc1f8641Sagc 	seckey = pgp_get_writable_seckey(keydata);
915c9d078dcSchristos 	pk = &seckey->pubkey.key.rsa;
916c9d078dcSchristos 	sk = &seckey->key.rsa;
91793bf6008Sagc 
91893bf6008Sagc 	/* generate the key pair */
91993bf6008Sagc 
920c9d078dcSchristos 	bne = BN_new();
921c9d078dcSchristos 	BN_set_word(bne, e);
922c9d078dcSchristos 
923c9d078dcSchristos 	rsa = RSA_new();
924c9d078dcSchristos 	RSA_generate_key_ex(rsa, numbits, bne, NULL);
925c9d078dcSchristos 	BN_free(bne);
92693bf6008Sagc 
927fc1f8641Sagc 	/* populate pgp key from ssl key */
928c9d078dcSchristos 	takeRSA(rsa, pk, sk);
92993bf6008Sagc 
930fc1f8641Sagc 	seckey->pubkey.version = PGP_V4;
9310c310959Sagc 	seckey->pubkey.birthtime = time(NULL);
9320c310959Sagc 	seckey->pubkey.days_valid = 0;
933fc1f8641Sagc 	seckey->pubkey.alg = PGP_PKA_RSA;
93493bf6008Sagc 
935fc1f8641Sagc 	seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
936fc1f8641Sagc 	seckey->s2k_specifier = PGP_S2KS_SALTED;
937fc1f8641Sagc 	/* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */
938fc1f8641Sagc 	if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
939fc1f8641Sagc 		seckey->hash_alg = PGP_HASH_SHA1;
940f0264dceSagc 	}
941fc1f8641Sagc 	seckey->alg = pgp_str_to_cipher(cipher);
9422232f800Sagc 	seckey->octetc = 0;
9430c310959Sagc 	seckey->checksum = 0;
94493bf6008Sagc 
945c9d078dcSchristos 	sk->u = BN_mod_inverse(NULL, sk->p, sk->q, ctx);
946c9d078dcSchristos 	if (sk->u == NULL) {
9470c310959Sagc 		(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
948bcfd8565Sagc 		return 0;
949bcfd8565Sagc 	}
95093bf6008Sagc 	BN_CTX_free(ctx);
95193bf6008Sagc 
95293bf6008Sagc 	RSA_free(rsa);
95393bf6008Sagc 
954fc1f8641Sagc 	pgp_keyid(keydata->sigid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
955fc1f8641Sagc 	pgp_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
95693bf6008Sagc 
95793bf6008Sagc 	/* Generate checksum */
95893bf6008Sagc 
95957324b9fSagc 	output = NULL;
96093bf6008Sagc 	mem = NULL;
96193bf6008Sagc 
962fc1f8641Sagc 	pgp_setup_memory_write(&output, &mem, 128);
96393bf6008Sagc 
964fc1f8641Sagc 	pgp_push_checksum_writer(output, seckey);
96593bf6008Sagc 
9662232f800Sagc 	switch (seckey->pubkey.alg) {
967fc1f8641Sagc 	case PGP_PKA_DSA:
968fc1f8641Sagc 		return pgp_write_mpi(output, seckey->key.dsa.x);
969fc1f8641Sagc 	case PGP_PKA_RSA:
970fc1f8641Sagc 	case PGP_PKA_RSA_ENCRYPT_ONLY:
971fc1f8641Sagc 	case PGP_PKA_RSA_SIGN_ONLY:
972fc1f8641Sagc 		if (!pgp_write_mpi(output, seckey->key.rsa.d) ||
973fc1f8641Sagc 		    !pgp_write_mpi(output, seckey->key.rsa.p) ||
974fc1f8641Sagc 		    !pgp_write_mpi(output, seckey->key.rsa.q) ||
975fc1f8641Sagc 		    !pgp_write_mpi(output, seckey->key.rsa.u)) {
9764b3a3e18Sagc 			return 0;
977b1b58706Sagc 		}
97893bf6008Sagc 		break;
979fc1f8641Sagc 	case PGP_PKA_ELGAMAL:
980fc1f8641Sagc 		return pgp_write_mpi(output, seckey->key.elgamal.x);
98193bf6008Sagc 
98293bf6008Sagc 	default:
9832232f800Sagc 		(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
9844b3a3e18Sagc 		return 0;
98593bf6008Sagc 	}
98693bf6008Sagc 
98793bf6008Sagc 	/* close rather than pop, since its the only one on the stack */
988fc1f8641Sagc 	pgp_writer_close(output);
989fc1f8641Sagc 	pgp_teardown_memory_write(output, mem);
99093bf6008Sagc 
9910c310959Sagc 	/* should now have checksum in seckey struct */
99293bf6008Sagc 
99393bf6008Sagc 	/* test */
994fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
9950c310959Sagc 		test_seckey(seckey);
996b1b58706Sagc 	}
99793bf6008Sagc 
9984b3a3e18Sagc 	return 1;
99993bf6008Sagc }
100093bf6008Sagc 
100193bf6008Sagc /**
100293bf6008Sagc  \ingroup HighLevel_KeyGenerate
100393bf6008Sagc  \brief Creates a self-signed RSA keypair
100493bf6008Sagc  \param numbits Modulus size
100593bf6008Sagc  \param e Public Exponent
100693bf6008Sagc  \param userid User ID
100793bf6008Sagc  \return The new keypair or NULL
100893bf6008Sagc 
1009fc1f8641Sagc  \note It is the caller's responsibility to call pgp_keydata_free(keydata)
101057324b9fSagc  \sa rsa_generate_keypair()
1011fc1f8641Sagc  \sa pgp_keydata_free()
101293bf6008Sagc */
1013fc1f8641Sagc pgp_key_t  *
pgp_rsa_new_selfsign_key(const int numbits,const unsigned long e,uint8_t * userid,const char * hashalg,const char * cipher)1014fc1f8641Sagc pgp_rsa_new_selfsign_key(const int numbits,
1015b1b58706Sagc 				const unsigned long e,
1016d427c17dSagc 				uint8_t *userid,
10173dc7aea1Sagc 				const char *hashalg,
10183dc7aea1Sagc 				const char *cipher)
101993bf6008Sagc {
1020fc1f8641Sagc 	pgp_key_t  *keydata;
102193bf6008Sagc 
1022fc1f8641Sagc 	keydata = pgp_keydata_new();
10233dc7aea1Sagc 	if (!rsa_generate_keypair(keydata, numbits, e, hashalg, cipher) ||
1024fc1f8641Sagc 	    !pgp_add_selfsigned_userid(keydata, userid)) {
1025fc1f8641Sagc 		pgp_keydata_free(keydata);
102693bf6008Sagc 		return NULL;
102793bf6008Sagc 	}
102893bf6008Sagc 	return keydata;
102993bf6008Sagc }
103093bf6008Sagc 
103193bf6008Sagc DSA_SIG        *
pgp_dsa_sign(uint8_t * hashbuf,unsigned hashsize,const pgp_dsa_seckey_t * secdsa,const pgp_dsa_pubkey_t * pubdsa)1032fc1f8641Sagc pgp_dsa_sign(uint8_t *hashbuf,
1033b1b58706Sagc 		unsigned hashsize,
1034fc1f8641Sagc 		const pgp_dsa_seckey_t *secdsa,
1035fc1f8641Sagc 		const pgp_dsa_pubkey_t *pubdsa)
103693bf6008Sagc {
103793bf6008Sagc 	DSA_SIG        *dsasig;
1038c9d078dcSchristos 	DSA            *odsa = makeDSA(pubdsa, secdsa);
103993bf6008Sagc 
1040efdd9dbaSagc 	dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
104193bf6008Sagc 
104293bf6008Sagc 	DSA_free(odsa);
104393bf6008Sagc 
104493bf6008Sagc 	return dsasig;
104593bf6008Sagc }
104691c29c74Sagc 
1047*0294a66bSjhigh ECDSA_SIG        *
pgp_ecdsa_sign(uint8_t * hashbuf,unsigned hashsize,const pgp_ecdsa_seckey_t * sececdsa,const pgp_ecdsa_pubkey_t * pubecdsa)1048*0294a66bSjhigh pgp_ecdsa_sign(uint8_t *hashbuf,
1049*0294a66bSjhigh 	       unsigned hashsize,
1050*0294a66bSjhigh 	       const pgp_ecdsa_seckey_t *sececdsa,
1051*0294a66bSjhigh 	       const pgp_ecdsa_pubkey_t *pubecdsa)
1052*0294a66bSjhigh {
1053*0294a66bSjhigh 	ECDSA_SIG * ecdsasig;
1054*0294a66bSjhigh 	EC_KEY * eckey = makeECDSA(pubecdsa, sececdsa);
1055*0294a66bSjhigh 
1056*0294a66bSjhigh 	ecdsasig = ECDSA_do_sign(hashbuf, (int)hashsize, eckey);
1057*0294a66bSjhigh 
1058*0294a66bSjhigh 	if (ecdsasig == NULL) {
1059*0294a66bSjhigh 		printf("do_sign returned null\n");
1060*0294a66bSjhigh 		return 0;
1061*0294a66bSjhigh 	}
1062*0294a66bSjhigh 
1063*0294a66bSjhigh 	EC_KEY_free(eckey);
1064*0294a66bSjhigh 
1065*0294a66bSjhigh 	return ecdsasig;
1066*0294a66bSjhigh }
1067*0294a66bSjhigh 
106891c29c74Sagc int
openssl_read_pem_seckey(const char * f,pgp_key_t * key,const char * type,int verbose)1069fc1f8641Sagc openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose)
107091c29c74Sagc {
107191c29c74Sagc 	FILE	*fp;
107273f34b00Sagc 	char	 prompt[BUFSIZ];
107373f34b00Sagc 	char	*pass;
107491c29c74Sagc 	DSA	*dsa;
107591c29c74Sagc 	RSA	*rsa;
107691c29c74Sagc 	int	 ok;
107791c29c74Sagc 
107873f34b00Sagc 	OpenSSL_add_all_algorithms();
107991c29c74Sagc 	if ((fp = fopen(f, "r")) == NULL) {
1080600b302bSagc 		if (verbose) {
108191c29c74Sagc 			(void) fprintf(stderr, "can't open '%s'\n", f);
1082600b302bSagc 		}
108391c29c74Sagc 		return 0;
108491c29c74Sagc 	}
108591c29c74Sagc 	ok = 1;
108691c29c74Sagc 	if (strcmp(type, "ssh-rsa") == 0) {
108791c29c74Sagc 		if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
108873f34b00Sagc 			(void) snprintf(prompt, sizeof(prompt), "netpgp PEM %s passphrase: ", f);
108973f34b00Sagc 			do {
109073f34b00Sagc 				pass = getpass(prompt);
109173f34b00Sagc 				rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, pass);
109273f34b00Sagc 			} while (rsa == NULL);
109373f34b00Sagc 		}
1094c9d078dcSchristos 		takeRSA(rsa, NULL, &key->key.seckey.key.rsa);
109591c29c74Sagc 	} else if (strcmp(type, "ssh-dss") == 0) {
109691c29c74Sagc 		if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
109791c29c74Sagc 			ok = 0;
109891c29c74Sagc 		} else {
1099c9d078dcSchristos 			takeDSA(dsa, &key->key.seckey.key.dsa);
110091c29c74Sagc 		}
110191c29c74Sagc 	} else {
110291c29c74Sagc 		ok = 0;
110391c29c74Sagc 	}
110491c29c74Sagc 	(void) fclose(fp);
110591c29c74Sagc 	return ok;
110691c29c74Sagc }
110773f34b00Sagc 
110837d8b79bSagc /*
110937d8b79bSagc  * Decide the number of bits in the random componont k
111037d8b79bSagc  *
111137d8b79bSagc  * It should be in the same range as p for signing (which
111237d8b79bSagc  * is deprecated), but can be much smaller for encrypting.
111337d8b79bSagc  *
111437d8b79bSagc  * Until I research it further, I just mimic gpg behaviour.
111537d8b79bSagc  * It has a special mapping table, for values <= 5120,
111637d8b79bSagc  * above that it uses 'arbitrary high number'.	Following
111737d8b79bSagc  * algorihm hovers 10-70 bits above gpg values.  And for
111837d8b79bSagc  * larger p, it uses gpg's algorihm.
111937d8b79bSagc  *
112037d8b79bSagc  * The point is - if k gets large, encryption will be
112137d8b79bSagc  * really slow.  It does not matter for decryption.
112237d8b79bSagc  */
112337d8b79bSagc static int
decide_k_bits(int p_bits)112437d8b79bSagc decide_k_bits(int p_bits)
112537d8b79bSagc {
112637d8b79bSagc 	return (p_bits <= 5120) ? p_bits / 10 + 160 : (p_bits / 8 + 200) * 3 / 2;
112737d8b79bSagc }
112837d8b79bSagc 
112937d8b79bSagc int
pgp_elgamal_public_encrypt(uint8_t * g_to_k,uint8_t * encm,const uint8_t * in,size_t size,const pgp_elgamal_pubkey_t * pubkey)1130fc1f8641Sagc pgp_elgamal_public_encrypt(uint8_t *g_to_k, uint8_t *encm,
113137d8b79bSagc 			const uint8_t *in,
113237d8b79bSagc 			size_t size,
1133fc1f8641Sagc 			const pgp_elgamal_pubkey_t *pubkey)
113437d8b79bSagc {
113537d8b79bSagc 	int	ret = 0;
113637d8b79bSagc 	int	k_bits;
113737d8b79bSagc 	BIGNUM	   *m;
113837d8b79bSagc 	BIGNUM	   *p;
113937d8b79bSagc 	BIGNUM	   *g;
114037d8b79bSagc 	BIGNUM	   *y;
114137d8b79bSagc 	BIGNUM	   *k;
114237d8b79bSagc 	BIGNUM	   *yk;
114337d8b79bSagc 	BIGNUM	   *c1;
114437d8b79bSagc 	BIGNUM	   *c2;
114537d8b79bSagc 	BN_CTX	   *tmp;
114637d8b79bSagc 
1147c2430ca2Sagc 	m = BN_bin2bn(in, (int)size, NULL);
114837d8b79bSagc 	p = pubkey->p;
114937d8b79bSagc 	g = pubkey->g;
115037d8b79bSagc 	y = pubkey->y;
115137d8b79bSagc 	k = BN_new();
115237d8b79bSagc 	yk = BN_new();
115337d8b79bSagc 	c1 = BN_new();
115437d8b79bSagc 	c2 = BN_new();
115537d8b79bSagc 	tmp = BN_CTX_new();
115637d8b79bSagc 	if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp) {
115737d8b79bSagc 		goto done;
115837d8b79bSagc 	}
115937d8b79bSagc 	/*
116037d8b79bSagc 	 * generate k
116137d8b79bSagc 	 */
116237d8b79bSagc 	k_bits = decide_k_bits(BN_num_bits(p));
116337d8b79bSagc 	if (!BN_rand(k, k_bits, 0, 0)) {
116437d8b79bSagc 		goto done;
116537d8b79bSagc 	}
116637d8b79bSagc 	/*
116737d8b79bSagc 	 * c1 = g^k c2 = m * y^k
116837d8b79bSagc 	 */
116937d8b79bSagc 	if (!BN_mod_exp(c1, g, k, p, tmp)) {
117037d8b79bSagc 		goto done;
117137d8b79bSagc 	}
117237d8b79bSagc 	if (!BN_mod_exp(yk, y, k, p, tmp)) {
117337d8b79bSagc 		goto done;
117437d8b79bSagc 	}
117537d8b79bSagc 	if (!BN_mod_mul(c2, m, yk, p, tmp)) {
117637d8b79bSagc 		goto done;
117737d8b79bSagc 	}
117837d8b79bSagc 	/* result */
117937d8b79bSagc 	BN_bn2bin(c1, g_to_k);
118037d8b79bSagc 	ret = BN_num_bytes(c1);	/* c1 = g^k */
118137d8b79bSagc 	BN_bn2bin(c2, encm);
118237d8b79bSagc 	ret += BN_num_bytes(c2); /* c2 = m * y^k */
118337d8b79bSagc done:
118437d8b79bSagc 	if (tmp) {
118537d8b79bSagc 		BN_CTX_free(tmp);
118637d8b79bSagc 	}
118737d8b79bSagc 	if (c2) {
118837d8b79bSagc 		BN_clear_free(c2);
118937d8b79bSagc 	}
119037d8b79bSagc 	if (c1) {
119137d8b79bSagc 		BN_clear_free(c1);
119237d8b79bSagc 	}
119337d8b79bSagc 	if (yk) {
119437d8b79bSagc 		BN_clear_free(yk);
119537d8b79bSagc 	}
119637d8b79bSagc 	if (k) {
119737d8b79bSagc 		BN_clear_free(k);
119837d8b79bSagc 	}
119937d8b79bSagc 	if (g) {
120037d8b79bSagc 		BN_clear_free(g);
120137d8b79bSagc 	}
120237d8b79bSagc 	return ret;
120337d8b79bSagc }
120437d8b79bSagc 
120573f34b00Sagc int
pgp_elgamal_private_decrypt(uint8_t * out,const uint8_t * g_to_k,const uint8_t * in,size_t length,const pgp_elgamal_seckey_t * seckey,const pgp_elgamal_pubkey_t * pubkey)1206fc1f8641Sagc pgp_elgamal_private_decrypt(uint8_t *out,
1207c2430ca2Sagc 				const uint8_t *g_to_k,
120873f34b00Sagc 				const uint8_t *in,
120973f34b00Sagc 				size_t length,
1210fc1f8641Sagc 				const pgp_elgamal_seckey_t *seckey,
1211fc1f8641Sagc 				const pgp_elgamal_pubkey_t *pubkey)
121273f34b00Sagc {
121373f34b00Sagc 	BIGNUM	*bndiv;
121473f34b00Sagc 	BIGNUM	*c1x;
121573f34b00Sagc 	BN_CTX	*tmp;
121673f34b00Sagc 	BIGNUM	*c1;
121773f34b00Sagc 	BIGNUM	*c2;
121873f34b00Sagc 	BIGNUM	*p;
121973f34b00Sagc 	BIGNUM	*x;
122073f34b00Sagc 	BIGNUM	*m;
1221c2430ca2Sagc 	int	 ret;
122273f34b00Sagc 
1223c2430ca2Sagc 	ret = 0;
1224c2430ca2Sagc 	/* c1 and c2 are in g_to_k and in, respectively*/
1225c2430ca2Sagc 	c1 = BN_bin2bn(g_to_k, (int)length, NULL);
1226c2430ca2Sagc 	c2 = BN_bin2bn(in, (int)length, NULL);
122773f34b00Sagc 	/* other bits */
122873f34b00Sagc 	p = pubkey->p;
122973f34b00Sagc 	x = seckey->x;
123073f34b00Sagc 	c1x = BN_new();
123173f34b00Sagc 	bndiv = BN_new();
123273f34b00Sagc 	m = BN_new();
123373f34b00Sagc 	tmp = BN_CTX_new();
123473f34b00Sagc 	if (!c1 || !c2 || !p || !x || !c1x || !bndiv || !m || !tmp) {
123573f34b00Sagc 		goto done;
123673f34b00Sagc 	}
123773f34b00Sagc 	/*
123873f34b00Sagc 	 * m = c2 / (c1^x)
123973f34b00Sagc 	 */
124073f34b00Sagc 	if (!BN_mod_exp(c1x, c1, x, p, tmp)) {
124173f34b00Sagc 		goto done;
124273f34b00Sagc 	}
124373f34b00Sagc 	if (!BN_mod_inverse(bndiv, c1x, p, tmp)) {
124473f34b00Sagc 		goto done;
124573f34b00Sagc 	}
124673f34b00Sagc 	if (!BN_mod_mul(m, c2, bndiv, p, tmp)) {
124773f34b00Sagc 		goto done;
124873f34b00Sagc 	}
124973f34b00Sagc 	/* result */
1250c2430ca2Sagc 	ret = BN_bn2bin(m, out);
125173f34b00Sagc done:
125273f34b00Sagc 	if (tmp) {
125373f34b00Sagc 		BN_CTX_free(tmp);
125473f34b00Sagc 	}
125573f34b00Sagc 	if (m) {
125673f34b00Sagc 		BN_clear_free(m);
125773f34b00Sagc 	}
125873f34b00Sagc 	if (bndiv) {
125973f34b00Sagc 		BN_clear_free(bndiv);
126073f34b00Sagc 	}
126173f34b00Sagc 	if (c1x) {
126273f34b00Sagc 		BN_clear_free(c1x);
126373f34b00Sagc 	}
126473f34b00Sagc 	if (x) {
126573f34b00Sagc 		BN_clear_free(x);
126673f34b00Sagc 	}
126773f34b00Sagc 	if (p) {
126873f34b00Sagc 		BN_clear_free(p);
126973f34b00Sagc 	}
127073f34b00Sagc 	if (c1) {
127173f34b00Sagc 		BN_clear_free(c1);
127273f34b00Sagc 	}
127373f34b00Sagc 	if (c2) {
127473f34b00Sagc 		BN_clear_free(c2);
127573f34b00Sagc 	}
127673f34b00Sagc 	return ret;
127773f34b00Sagc }
1278