1*ebfedea0SLionel Sambuc /*-
2*ebfedea0SLionel Sambuc * Copyright (c) 2009 The NetBSD Foundation, Inc.
3*ebfedea0SLionel Sambuc * All rights reserved.
4*ebfedea0SLionel Sambuc *
5*ebfedea0SLionel Sambuc * This code is derived from software contributed to The NetBSD Foundation
6*ebfedea0SLionel Sambuc * by Alistair Crooks (agc@NetBSD.org)
7*ebfedea0SLionel Sambuc *
8*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
9*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
10*ebfedea0SLionel Sambuc * are met:
11*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
12*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
13*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
14*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
15*ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
16*ebfedea0SLionel Sambuc *
17*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18*ebfedea0SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19*ebfedea0SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20*ebfedea0SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21*ebfedea0SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*ebfedea0SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*ebfedea0SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*ebfedea0SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*ebfedea0SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*ebfedea0SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*ebfedea0SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
28*ebfedea0SLionel Sambuc */
29*ebfedea0SLionel Sambuc /*
30*ebfedea0SLionel Sambuc * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31*ebfedea0SLionel Sambuc * All rights reserved.
32*ebfedea0SLionel Sambuc * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33*ebfedea0SLionel Sambuc * their moral rights under the UK Copyright Design and Patents Act 1988 to
34*ebfedea0SLionel Sambuc * be recorded as the authors of this copyright work.
35*ebfedea0SLionel Sambuc *
36*ebfedea0SLionel Sambuc * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37*ebfedea0SLionel Sambuc * use this file except in compliance with the License.
38*ebfedea0SLionel Sambuc *
39*ebfedea0SLionel Sambuc * You may obtain a copy of the License at
40*ebfedea0SLionel Sambuc * http://www.apache.org/licenses/LICENSE-2.0
41*ebfedea0SLionel Sambuc *
42*ebfedea0SLionel Sambuc * Unless required by applicable law or agreed to in writing, software
43*ebfedea0SLionel Sambuc * distributed under the License is distributed on an "AS IS" BASIS,
44*ebfedea0SLionel Sambuc * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45*ebfedea0SLionel Sambuc *
46*ebfedea0SLionel Sambuc * See the License for the specific language governing permissions and
47*ebfedea0SLionel Sambuc * limitations under the License.
48*ebfedea0SLionel Sambuc */
49*ebfedea0SLionel Sambuc
50*ebfedea0SLionel Sambuc /** \file
51*ebfedea0SLionel Sambuc */
52*ebfedea0SLionel Sambuc #include "config.h"
53*ebfedea0SLionel Sambuc
54*ebfedea0SLionel Sambuc #ifdef HAVE_SYS_CDEFS_H
55*ebfedea0SLionel Sambuc #include <sys/cdefs.h>
56*ebfedea0SLionel Sambuc #endif
57*ebfedea0SLionel Sambuc
58*ebfedea0SLionel Sambuc #if defined(__NetBSD__)
59*ebfedea0SLionel Sambuc __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60*ebfedea0SLionel Sambuc __RCSID("$NetBSD: openssl_crypto.c,v 1.33 2010/11/07 08:39:59 agc Exp $");
61*ebfedea0SLionel Sambuc #endif
62*ebfedea0SLionel Sambuc
63*ebfedea0SLionel Sambuc #ifdef HAVE_OPENSSL_DSA_H
64*ebfedea0SLionel Sambuc #include <openssl/dsa.h>
65*ebfedea0SLionel Sambuc #endif
66*ebfedea0SLionel Sambuc
67*ebfedea0SLionel Sambuc #ifdef HAVE_OPENSSL_RSA_H
68*ebfedea0SLionel Sambuc #include <openssl/rsa.h>
69*ebfedea0SLionel Sambuc #endif
70*ebfedea0SLionel Sambuc
71*ebfedea0SLionel Sambuc #ifdef HAVE_OPENSSL_ERR_H
72*ebfedea0SLionel Sambuc #include <openssl/err.h>
73*ebfedea0SLionel Sambuc #endif
74*ebfedea0SLionel Sambuc
75*ebfedea0SLionel Sambuc #include <openssl/pem.h>
76*ebfedea0SLionel Sambuc #include <openssl/evp.h>
77*ebfedea0SLionel Sambuc
78*ebfedea0SLionel Sambuc #include <stdlib.h>
79*ebfedea0SLionel Sambuc #include <string.h>
80*ebfedea0SLionel Sambuc
81*ebfedea0SLionel Sambuc #ifdef HAVE_UNISTD_H
82*ebfedea0SLionel Sambuc #include <unistd.h>
83*ebfedea0SLionel Sambuc #endif
84*ebfedea0SLionel Sambuc
85*ebfedea0SLionel Sambuc #include "crypto.h"
86*ebfedea0SLionel Sambuc #include "keyring.h"
87*ebfedea0SLionel Sambuc #include "readerwriter.h"
88*ebfedea0SLionel Sambuc #include "netpgpdefs.h"
89*ebfedea0SLionel Sambuc #include "netpgpdigest.h"
90*ebfedea0SLionel Sambuc #include "packet.h"
91*ebfedea0SLionel Sambuc
92*ebfedea0SLionel Sambuc
93*ebfedea0SLionel Sambuc static void
test_seckey(const pgp_seckey_t * seckey)94*ebfedea0SLionel Sambuc test_seckey(const pgp_seckey_t *seckey)
95*ebfedea0SLionel Sambuc {
96*ebfedea0SLionel Sambuc RSA *test = RSA_new();
97*ebfedea0SLionel Sambuc
98*ebfedea0SLionel Sambuc test->n = BN_dup(seckey->pubkey.key.rsa.n);
99*ebfedea0SLionel Sambuc test->e = BN_dup(seckey->pubkey.key.rsa.e);
100*ebfedea0SLionel Sambuc
101*ebfedea0SLionel Sambuc test->d = BN_dup(seckey->key.rsa.d);
102*ebfedea0SLionel Sambuc test->p = BN_dup(seckey->key.rsa.p);
103*ebfedea0SLionel Sambuc test->q = BN_dup(seckey->key.rsa.q);
104*ebfedea0SLionel Sambuc
105*ebfedea0SLionel Sambuc if (RSA_check_key(test) != 1) {
106*ebfedea0SLionel Sambuc (void) fprintf(stderr,
107*ebfedea0SLionel Sambuc "test_seckey: RSA_check_key failed\n");
108*ebfedea0SLionel Sambuc }
109*ebfedea0SLionel Sambuc RSA_free(test);
110*ebfedea0SLionel Sambuc }
111*ebfedea0SLionel Sambuc
112*ebfedea0SLionel Sambuc static int
md5_init(pgp_hash_t * hash)113*ebfedea0SLionel Sambuc md5_init(pgp_hash_t *hash)
114*ebfedea0SLionel Sambuc {
115*ebfedea0SLionel Sambuc if (hash->data) {
116*ebfedea0SLionel Sambuc (void) fprintf(stderr, "md5_init: hash data non-null\n");
117*ebfedea0SLionel Sambuc }
118*ebfedea0SLionel Sambuc if ((hash->data = calloc(1, sizeof(MD5_CTX))) == NULL) {
119*ebfedea0SLionel Sambuc (void) fprintf(stderr, "md5_init: bad alloc\n");
120*ebfedea0SLionel Sambuc return 0;
121*ebfedea0SLionel Sambuc }
122*ebfedea0SLionel Sambuc MD5_Init(hash->data);
123*ebfedea0SLionel Sambuc return 1;
124*ebfedea0SLionel Sambuc }
125*ebfedea0SLionel Sambuc
126*ebfedea0SLionel Sambuc static void
md5_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)127*ebfedea0SLionel Sambuc md5_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
128*ebfedea0SLionel Sambuc {
129*ebfedea0SLionel Sambuc MD5_Update(hash->data, data, length);
130*ebfedea0SLionel Sambuc }
131*ebfedea0SLionel Sambuc
132*ebfedea0SLionel Sambuc static unsigned
md5_finish(pgp_hash_t * hash,uint8_t * out)133*ebfedea0SLionel Sambuc md5_finish(pgp_hash_t *hash, uint8_t *out)
134*ebfedea0SLionel Sambuc {
135*ebfedea0SLionel Sambuc MD5_Final(out, hash->data);
136*ebfedea0SLionel Sambuc free(hash->data);
137*ebfedea0SLionel Sambuc hash->data = NULL;
138*ebfedea0SLionel Sambuc return 16;
139*ebfedea0SLionel Sambuc }
140*ebfedea0SLionel Sambuc
141*ebfedea0SLionel Sambuc static const pgp_hash_t md5 = {
142*ebfedea0SLionel Sambuc PGP_HASH_MD5,
143*ebfedea0SLionel Sambuc MD5_DIGEST_LENGTH,
144*ebfedea0SLionel Sambuc "MD5",
145*ebfedea0SLionel Sambuc md5_init,
146*ebfedea0SLionel Sambuc md5_add,
147*ebfedea0SLionel Sambuc md5_finish,
148*ebfedea0SLionel Sambuc NULL
149*ebfedea0SLionel Sambuc };
150*ebfedea0SLionel Sambuc
151*ebfedea0SLionel Sambuc /**
152*ebfedea0SLionel Sambuc \ingroup Core_Crypto
153*ebfedea0SLionel Sambuc \brief Initialise to MD5
154*ebfedea0SLionel Sambuc \param hash Hash to initialise
155*ebfedea0SLionel Sambuc */
156*ebfedea0SLionel Sambuc void
pgp_hash_md5(pgp_hash_t * hash)157*ebfedea0SLionel Sambuc pgp_hash_md5(pgp_hash_t *hash)
158*ebfedea0SLionel Sambuc {
159*ebfedea0SLionel Sambuc *hash = md5;
160*ebfedea0SLionel Sambuc }
161*ebfedea0SLionel Sambuc
162*ebfedea0SLionel Sambuc static int
sha1_init(pgp_hash_t * hash)163*ebfedea0SLionel Sambuc sha1_init(pgp_hash_t *hash)
164*ebfedea0SLionel Sambuc {
165*ebfedea0SLionel Sambuc if (hash->data) {
166*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha1_init: hash data non-null\n");
167*ebfedea0SLionel Sambuc }
168*ebfedea0SLionel Sambuc if ((hash->data = calloc(1, sizeof(SHA_CTX))) == NULL) {
169*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha1_init: bad alloc\n");
170*ebfedea0SLionel Sambuc return 0;
171*ebfedea0SLionel Sambuc }
172*ebfedea0SLionel Sambuc SHA1_Init(hash->data);
173*ebfedea0SLionel Sambuc return 1;
174*ebfedea0SLionel Sambuc }
175*ebfedea0SLionel Sambuc
176*ebfedea0SLionel Sambuc static void
sha1_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)177*ebfedea0SLionel Sambuc sha1_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
178*ebfedea0SLionel Sambuc {
179*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
180*ebfedea0SLionel Sambuc hexdump(stderr, "sha1_add", data, length);
181*ebfedea0SLionel Sambuc }
182*ebfedea0SLionel Sambuc SHA1_Update(hash->data, data, length);
183*ebfedea0SLionel Sambuc }
184*ebfedea0SLionel Sambuc
185*ebfedea0SLionel Sambuc static unsigned
sha1_finish(pgp_hash_t * hash,uint8_t * out)186*ebfedea0SLionel Sambuc sha1_finish(pgp_hash_t *hash, uint8_t *out)
187*ebfedea0SLionel Sambuc {
188*ebfedea0SLionel Sambuc SHA1_Final(out, hash->data);
189*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
190*ebfedea0SLionel Sambuc hexdump(stderr, "sha1_finish", out, PGP_SHA1_HASH_SIZE);
191*ebfedea0SLionel Sambuc }
192*ebfedea0SLionel Sambuc free(hash->data);
193*ebfedea0SLionel Sambuc hash->data = NULL;
194*ebfedea0SLionel Sambuc return PGP_SHA1_HASH_SIZE;
195*ebfedea0SLionel Sambuc }
196*ebfedea0SLionel Sambuc
197*ebfedea0SLionel Sambuc static const pgp_hash_t sha1 = {
198*ebfedea0SLionel Sambuc PGP_HASH_SHA1,
199*ebfedea0SLionel Sambuc PGP_SHA1_HASH_SIZE,
200*ebfedea0SLionel Sambuc "SHA1",
201*ebfedea0SLionel Sambuc sha1_init,
202*ebfedea0SLionel Sambuc sha1_add,
203*ebfedea0SLionel Sambuc sha1_finish,
204*ebfedea0SLionel Sambuc NULL
205*ebfedea0SLionel Sambuc };
206*ebfedea0SLionel Sambuc
207*ebfedea0SLionel Sambuc /**
208*ebfedea0SLionel Sambuc \ingroup Core_Crypto
209*ebfedea0SLionel Sambuc \brief Initialise to SHA1
210*ebfedea0SLionel Sambuc \param hash Hash to initialise
211*ebfedea0SLionel Sambuc */
212*ebfedea0SLionel Sambuc void
pgp_hash_sha1(pgp_hash_t * hash)213*ebfedea0SLionel Sambuc pgp_hash_sha1(pgp_hash_t *hash)
214*ebfedea0SLionel Sambuc {
215*ebfedea0SLionel Sambuc *hash = sha1;
216*ebfedea0SLionel Sambuc }
217*ebfedea0SLionel Sambuc
218*ebfedea0SLionel Sambuc static int
sha256_init(pgp_hash_t * hash)219*ebfedea0SLionel Sambuc sha256_init(pgp_hash_t *hash)
220*ebfedea0SLionel Sambuc {
221*ebfedea0SLionel Sambuc if (hash->data) {
222*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha256_init: hash data non-null\n");
223*ebfedea0SLionel Sambuc }
224*ebfedea0SLionel Sambuc if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
225*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha256_init: bad alloc\n");
226*ebfedea0SLionel Sambuc return 0;
227*ebfedea0SLionel Sambuc }
228*ebfedea0SLionel Sambuc SHA256_Init(hash->data);
229*ebfedea0SLionel Sambuc return 1;
230*ebfedea0SLionel Sambuc }
231*ebfedea0SLionel Sambuc
232*ebfedea0SLionel Sambuc static void
sha256_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)233*ebfedea0SLionel Sambuc sha256_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
234*ebfedea0SLionel Sambuc {
235*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
236*ebfedea0SLionel Sambuc hexdump(stderr, "sha256_add", data, length);
237*ebfedea0SLionel Sambuc }
238*ebfedea0SLionel Sambuc SHA256_Update(hash->data, data, length);
239*ebfedea0SLionel Sambuc }
240*ebfedea0SLionel Sambuc
241*ebfedea0SLionel Sambuc static unsigned
sha256_finish(pgp_hash_t * hash,uint8_t * out)242*ebfedea0SLionel Sambuc sha256_finish(pgp_hash_t *hash, uint8_t *out)
243*ebfedea0SLionel Sambuc {
244*ebfedea0SLionel Sambuc SHA256_Final(out, hash->data);
245*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
246*ebfedea0SLionel Sambuc hexdump(stderr, "sha1_finish", out, SHA256_DIGEST_LENGTH);
247*ebfedea0SLionel Sambuc }
248*ebfedea0SLionel Sambuc free(hash->data);
249*ebfedea0SLionel Sambuc hash->data = NULL;
250*ebfedea0SLionel Sambuc return SHA256_DIGEST_LENGTH;
251*ebfedea0SLionel Sambuc }
252*ebfedea0SLionel Sambuc
253*ebfedea0SLionel Sambuc static const pgp_hash_t sha256 = {
254*ebfedea0SLionel Sambuc PGP_HASH_SHA256,
255*ebfedea0SLionel Sambuc SHA256_DIGEST_LENGTH,
256*ebfedea0SLionel Sambuc "SHA256",
257*ebfedea0SLionel Sambuc sha256_init,
258*ebfedea0SLionel Sambuc sha256_add,
259*ebfedea0SLionel Sambuc sha256_finish,
260*ebfedea0SLionel Sambuc NULL
261*ebfedea0SLionel Sambuc };
262*ebfedea0SLionel Sambuc
263*ebfedea0SLionel Sambuc void
pgp_hash_sha256(pgp_hash_t * hash)264*ebfedea0SLionel Sambuc pgp_hash_sha256(pgp_hash_t *hash)
265*ebfedea0SLionel Sambuc {
266*ebfedea0SLionel Sambuc *hash = sha256;
267*ebfedea0SLionel Sambuc }
268*ebfedea0SLionel Sambuc
269*ebfedea0SLionel Sambuc /*
270*ebfedea0SLionel Sambuc * SHA384
271*ebfedea0SLionel Sambuc */
272*ebfedea0SLionel Sambuc static int
sha384_init(pgp_hash_t * hash)273*ebfedea0SLionel Sambuc sha384_init(pgp_hash_t *hash)
274*ebfedea0SLionel Sambuc {
275*ebfedea0SLionel Sambuc if (hash->data) {
276*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha384_init: hash data non-null\n");
277*ebfedea0SLionel Sambuc }
278*ebfedea0SLionel Sambuc if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
279*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha384_init: bad alloc\n");
280*ebfedea0SLionel Sambuc return 0;
281*ebfedea0SLionel Sambuc }
282*ebfedea0SLionel Sambuc SHA384_Init(hash->data);
283*ebfedea0SLionel Sambuc return 1;
284*ebfedea0SLionel Sambuc }
285*ebfedea0SLionel Sambuc
286*ebfedea0SLionel Sambuc static void
sha384_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)287*ebfedea0SLionel Sambuc sha384_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
288*ebfedea0SLionel Sambuc {
289*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
290*ebfedea0SLionel Sambuc hexdump(stderr, "sha384_add", data, length);
291*ebfedea0SLionel Sambuc }
292*ebfedea0SLionel Sambuc SHA384_Update(hash->data, data, length);
293*ebfedea0SLionel Sambuc }
294*ebfedea0SLionel Sambuc
295*ebfedea0SLionel Sambuc static unsigned
sha384_finish(pgp_hash_t * hash,uint8_t * out)296*ebfedea0SLionel Sambuc sha384_finish(pgp_hash_t *hash, uint8_t *out)
297*ebfedea0SLionel Sambuc {
298*ebfedea0SLionel Sambuc SHA384_Final(out, hash->data);
299*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
300*ebfedea0SLionel Sambuc hexdump(stderr, "sha384_finish", out, SHA384_DIGEST_LENGTH);
301*ebfedea0SLionel Sambuc }
302*ebfedea0SLionel Sambuc free(hash->data);
303*ebfedea0SLionel Sambuc hash->data = NULL;
304*ebfedea0SLionel Sambuc return SHA384_DIGEST_LENGTH;
305*ebfedea0SLionel Sambuc }
306*ebfedea0SLionel Sambuc
307*ebfedea0SLionel Sambuc static const pgp_hash_t sha384 = {
308*ebfedea0SLionel Sambuc PGP_HASH_SHA384,
309*ebfedea0SLionel Sambuc SHA384_DIGEST_LENGTH,
310*ebfedea0SLionel Sambuc "SHA384",
311*ebfedea0SLionel Sambuc sha384_init,
312*ebfedea0SLionel Sambuc sha384_add,
313*ebfedea0SLionel Sambuc sha384_finish,
314*ebfedea0SLionel Sambuc NULL
315*ebfedea0SLionel Sambuc };
316*ebfedea0SLionel Sambuc
317*ebfedea0SLionel Sambuc void
pgp_hash_sha384(pgp_hash_t * hash)318*ebfedea0SLionel Sambuc pgp_hash_sha384(pgp_hash_t *hash)
319*ebfedea0SLionel Sambuc {
320*ebfedea0SLionel Sambuc *hash = sha384;
321*ebfedea0SLionel Sambuc }
322*ebfedea0SLionel Sambuc
323*ebfedea0SLionel Sambuc /*
324*ebfedea0SLionel Sambuc * SHA512
325*ebfedea0SLionel Sambuc */
326*ebfedea0SLionel Sambuc static int
sha512_init(pgp_hash_t * hash)327*ebfedea0SLionel Sambuc sha512_init(pgp_hash_t *hash)
328*ebfedea0SLionel Sambuc {
329*ebfedea0SLionel Sambuc if (hash->data) {
330*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha512_init: hash data non-null\n");
331*ebfedea0SLionel Sambuc }
332*ebfedea0SLionel Sambuc if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
333*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha512_init: bad alloc\n");
334*ebfedea0SLionel Sambuc return 0;
335*ebfedea0SLionel Sambuc }
336*ebfedea0SLionel Sambuc SHA512_Init(hash->data);
337*ebfedea0SLionel Sambuc return 1;
338*ebfedea0SLionel Sambuc }
339*ebfedea0SLionel Sambuc
340*ebfedea0SLionel Sambuc static void
sha512_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)341*ebfedea0SLionel Sambuc sha512_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
342*ebfedea0SLionel Sambuc {
343*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
344*ebfedea0SLionel Sambuc hexdump(stderr, "sha512_add", data, length);
345*ebfedea0SLionel Sambuc }
346*ebfedea0SLionel Sambuc SHA512_Update(hash->data, data, length);
347*ebfedea0SLionel Sambuc }
348*ebfedea0SLionel Sambuc
349*ebfedea0SLionel Sambuc static unsigned
sha512_finish(pgp_hash_t * hash,uint8_t * out)350*ebfedea0SLionel Sambuc sha512_finish(pgp_hash_t *hash, uint8_t *out)
351*ebfedea0SLionel Sambuc {
352*ebfedea0SLionel Sambuc SHA512_Final(out, hash->data);
353*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
354*ebfedea0SLionel Sambuc hexdump(stderr, "sha512_finish", out, SHA512_DIGEST_LENGTH);
355*ebfedea0SLionel Sambuc }
356*ebfedea0SLionel Sambuc free(hash->data);
357*ebfedea0SLionel Sambuc hash->data = NULL;
358*ebfedea0SLionel Sambuc return SHA512_DIGEST_LENGTH;
359*ebfedea0SLionel Sambuc }
360*ebfedea0SLionel Sambuc
361*ebfedea0SLionel Sambuc static const pgp_hash_t sha512 = {
362*ebfedea0SLionel Sambuc PGP_HASH_SHA512,
363*ebfedea0SLionel Sambuc SHA512_DIGEST_LENGTH,
364*ebfedea0SLionel Sambuc "SHA512",
365*ebfedea0SLionel Sambuc sha512_init,
366*ebfedea0SLionel Sambuc sha512_add,
367*ebfedea0SLionel Sambuc sha512_finish,
368*ebfedea0SLionel Sambuc NULL
369*ebfedea0SLionel Sambuc };
370*ebfedea0SLionel Sambuc
371*ebfedea0SLionel Sambuc void
pgp_hash_sha512(pgp_hash_t * hash)372*ebfedea0SLionel Sambuc pgp_hash_sha512(pgp_hash_t *hash)
373*ebfedea0SLionel Sambuc {
374*ebfedea0SLionel Sambuc *hash = sha512;
375*ebfedea0SLionel Sambuc }
376*ebfedea0SLionel Sambuc
377*ebfedea0SLionel Sambuc /*
378*ebfedea0SLionel Sambuc * SHA224
379*ebfedea0SLionel Sambuc */
380*ebfedea0SLionel Sambuc
381*ebfedea0SLionel Sambuc static int
sha224_init(pgp_hash_t * hash)382*ebfedea0SLionel Sambuc sha224_init(pgp_hash_t *hash)
383*ebfedea0SLionel Sambuc {
384*ebfedea0SLionel Sambuc if (hash->data) {
385*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha224_init: hash data non-null\n");
386*ebfedea0SLionel Sambuc }
387*ebfedea0SLionel Sambuc if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
388*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sha256_init: bad alloc\n");
389*ebfedea0SLionel Sambuc return 0;
390*ebfedea0SLionel Sambuc }
391*ebfedea0SLionel Sambuc SHA224_Init(hash->data);
392*ebfedea0SLionel Sambuc return 1;
393*ebfedea0SLionel Sambuc }
394*ebfedea0SLionel Sambuc
395*ebfedea0SLionel Sambuc static void
sha224_add(pgp_hash_t * hash,const uint8_t * data,unsigned length)396*ebfedea0SLionel Sambuc sha224_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
397*ebfedea0SLionel Sambuc {
398*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
399*ebfedea0SLionel Sambuc hexdump(stderr, "sha224_add", data, length);
400*ebfedea0SLionel Sambuc }
401*ebfedea0SLionel Sambuc SHA224_Update(hash->data, data, length);
402*ebfedea0SLionel Sambuc }
403*ebfedea0SLionel Sambuc
404*ebfedea0SLionel Sambuc static unsigned
sha224_finish(pgp_hash_t * hash,uint8_t * out)405*ebfedea0SLionel Sambuc sha224_finish(pgp_hash_t *hash, uint8_t *out)
406*ebfedea0SLionel Sambuc {
407*ebfedea0SLionel Sambuc SHA224_Final(out, hash->data);
408*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
409*ebfedea0SLionel Sambuc hexdump(stderr, "sha224_finish", out, SHA224_DIGEST_LENGTH);
410*ebfedea0SLionel Sambuc }
411*ebfedea0SLionel Sambuc free(hash->data);
412*ebfedea0SLionel Sambuc hash->data = NULL;
413*ebfedea0SLionel Sambuc return SHA224_DIGEST_LENGTH;
414*ebfedea0SLionel Sambuc }
415*ebfedea0SLionel Sambuc
416*ebfedea0SLionel Sambuc static const pgp_hash_t sha224 = {
417*ebfedea0SLionel Sambuc PGP_HASH_SHA224,
418*ebfedea0SLionel Sambuc SHA224_DIGEST_LENGTH,
419*ebfedea0SLionel Sambuc "SHA224",
420*ebfedea0SLionel Sambuc sha224_init,
421*ebfedea0SLionel Sambuc sha224_add,
422*ebfedea0SLionel Sambuc sha224_finish,
423*ebfedea0SLionel Sambuc NULL
424*ebfedea0SLionel Sambuc };
425*ebfedea0SLionel Sambuc
426*ebfedea0SLionel Sambuc void
pgp_hash_sha224(pgp_hash_t * hash)427*ebfedea0SLionel Sambuc pgp_hash_sha224(pgp_hash_t *hash)
428*ebfedea0SLionel Sambuc {
429*ebfedea0SLionel Sambuc *hash = sha224;
430*ebfedea0SLionel Sambuc }
431*ebfedea0SLionel Sambuc
432*ebfedea0SLionel Sambuc unsigned
pgp_dsa_verify(const uint8_t * hash,size_t hash_length,const pgp_dsa_sig_t * sig,const pgp_dsa_pubkey_t * dsa)433*ebfedea0SLionel Sambuc pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
434*ebfedea0SLionel Sambuc const pgp_dsa_sig_t *sig,
435*ebfedea0SLionel Sambuc const pgp_dsa_pubkey_t *dsa)
436*ebfedea0SLionel Sambuc {
437*ebfedea0SLionel Sambuc unsigned qlen;
438*ebfedea0SLionel Sambuc DSA_SIG *osig;
439*ebfedea0SLionel Sambuc DSA *odsa;
440*ebfedea0SLionel Sambuc int ret;
441*ebfedea0SLionel Sambuc
442*ebfedea0SLionel Sambuc osig = DSA_SIG_new();
443*ebfedea0SLionel Sambuc osig->r = sig->r;
444*ebfedea0SLionel Sambuc osig->s = sig->s;
445*ebfedea0SLionel Sambuc
446*ebfedea0SLionel Sambuc odsa = DSA_new();
447*ebfedea0SLionel Sambuc odsa->p = dsa->p;
448*ebfedea0SLionel Sambuc odsa->q = dsa->q;
449*ebfedea0SLionel Sambuc odsa->g = dsa->g;
450*ebfedea0SLionel Sambuc odsa->pub_key = dsa->y;
451*ebfedea0SLionel Sambuc
452*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
453*ebfedea0SLionel Sambuc hexdump(stderr, "input hash", hash, hash_length);
454*ebfedea0SLionel Sambuc (void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q));
455*ebfedea0SLionel Sambuc }
456*ebfedea0SLionel Sambuc if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) {
457*ebfedea0SLionel Sambuc hash_length = qlen;
458*ebfedea0SLionel Sambuc }
459*ebfedea0SLionel Sambuc ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
460*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
461*ebfedea0SLionel Sambuc (void) fprintf(stderr, "ret=%d\n", ret);
462*ebfedea0SLionel Sambuc }
463*ebfedea0SLionel Sambuc if (ret < 0) {
464*ebfedea0SLionel Sambuc (void) fprintf(stderr, "pgp_dsa_verify: DSA verification\n");
465*ebfedea0SLionel Sambuc return 0;
466*ebfedea0SLionel Sambuc }
467*ebfedea0SLionel Sambuc
468*ebfedea0SLionel Sambuc odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
469*ebfedea0SLionel Sambuc DSA_free(odsa);
470*ebfedea0SLionel Sambuc
471*ebfedea0SLionel Sambuc osig->r = osig->s = NULL;
472*ebfedea0SLionel Sambuc DSA_SIG_free(osig);
473*ebfedea0SLionel Sambuc
474*ebfedea0SLionel Sambuc return (unsigned)ret;
475*ebfedea0SLionel Sambuc }
476*ebfedea0SLionel Sambuc
477*ebfedea0SLionel Sambuc /**
478*ebfedea0SLionel Sambuc \ingroup Core_Crypto
479*ebfedea0SLionel Sambuc \brief Recovers message digest from the signature
480*ebfedea0SLionel Sambuc \param out Where to write decrypted data to
481*ebfedea0SLionel Sambuc \param in Encrypted data
482*ebfedea0SLionel Sambuc \param length Length of encrypted data
483*ebfedea0SLionel Sambuc \param pubkey RSA public key
484*ebfedea0SLionel Sambuc \return size of recovered message digest
485*ebfedea0SLionel Sambuc */
486*ebfedea0SLionel Sambuc int
pgp_rsa_public_decrypt(uint8_t * out,const uint8_t * in,size_t length,const pgp_rsa_pubkey_t * pubkey)487*ebfedea0SLionel Sambuc pgp_rsa_public_decrypt(uint8_t *out,
488*ebfedea0SLionel Sambuc const uint8_t *in,
489*ebfedea0SLionel Sambuc size_t length,
490*ebfedea0SLionel Sambuc const pgp_rsa_pubkey_t *pubkey)
491*ebfedea0SLionel Sambuc {
492*ebfedea0SLionel Sambuc RSA *orsa;
493*ebfedea0SLionel Sambuc int n;
494*ebfedea0SLionel Sambuc
495*ebfedea0SLionel Sambuc orsa = RSA_new();
496*ebfedea0SLionel Sambuc orsa->n = pubkey->n;
497*ebfedea0SLionel Sambuc orsa->e = pubkey->e;
498*ebfedea0SLionel Sambuc
499*ebfedea0SLionel Sambuc n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
500*ebfedea0SLionel Sambuc
501*ebfedea0SLionel Sambuc orsa->n = orsa->e = NULL;
502*ebfedea0SLionel Sambuc RSA_free(orsa);
503*ebfedea0SLionel Sambuc
504*ebfedea0SLionel Sambuc return n;
505*ebfedea0SLionel Sambuc }
506*ebfedea0SLionel Sambuc
507*ebfedea0SLionel Sambuc /**
508*ebfedea0SLionel Sambuc \ingroup Core_Crypto
509*ebfedea0SLionel Sambuc \brief Signs data with RSA
510*ebfedea0SLionel Sambuc \param out Where to write signature
511*ebfedea0SLionel Sambuc \param in Data to sign
512*ebfedea0SLionel Sambuc \param length Length of data
513*ebfedea0SLionel Sambuc \param seckey RSA secret key
514*ebfedea0SLionel Sambuc \param pubkey RSA public key
515*ebfedea0SLionel Sambuc \return number of bytes decrypted
516*ebfedea0SLionel Sambuc */
517*ebfedea0SLionel Sambuc 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)518*ebfedea0SLionel Sambuc pgp_rsa_private_encrypt(uint8_t *out,
519*ebfedea0SLionel Sambuc const uint8_t *in,
520*ebfedea0SLionel Sambuc size_t length,
521*ebfedea0SLionel Sambuc const pgp_rsa_seckey_t *seckey,
522*ebfedea0SLionel Sambuc const pgp_rsa_pubkey_t *pubkey)
523*ebfedea0SLionel Sambuc {
524*ebfedea0SLionel Sambuc RSA *orsa;
525*ebfedea0SLionel Sambuc int n;
526*ebfedea0SLionel Sambuc
527*ebfedea0SLionel Sambuc orsa = RSA_new();
528*ebfedea0SLionel Sambuc orsa->n = BN_dup(pubkey->n);
529*ebfedea0SLionel Sambuc orsa->d = seckey->d;
530*ebfedea0SLionel Sambuc orsa->p = seckey->q; /* p and q are round the other way in openssl */
531*ebfedea0SLionel Sambuc orsa->q = seckey->p;
532*ebfedea0SLionel Sambuc
533*ebfedea0SLionel Sambuc /* debug */
534*ebfedea0SLionel Sambuc orsa->e = BN_dup(pubkey->e);
535*ebfedea0SLionel Sambuc /* If this isn't set, it's very likely that the programmer hasn't */
536*ebfedea0SLionel Sambuc /* decrypted the secret key. RSA_check_key segfaults in that case. */
537*ebfedea0SLionel Sambuc /* Use pgp_decrypt_seckey() to do that. */
538*ebfedea0SLionel Sambuc if (orsa->d == NULL) {
539*ebfedea0SLionel Sambuc (void) fprintf(stderr, "orsa is not set\n");
540*ebfedea0SLionel Sambuc return 0;
541*ebfedea0SLionel Sambuc }
542*ebfedea0SLionel Sambuc if (RSA_check_key(orsa) != 1) {
543*ebfedea0SLionel Sambuc (void) fprintf(stderr, "RSA_check_key is not set\n");
544*ebfedea0SLionel Sambuc return 0;
545*ebfedea0SLionel Sambuc }
546*ebfedea0SLionel Sambuc /* end debug */
547*ebfedea0SLionel Sambuc
548*ebfedea0SLionel Sambuc n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
549*ebfedea0SLionel Sambuc
550*ebfedea0SLionel Sambuc orsa->n = orsa->d = orsa->p = orsa->q = NULL;
551*ebfedea0SLionel Sambuc RSA_free(orsa);
552*ebfedea0SLionel Sambuc
553*ebfedea0SLionel Sambuc return n;
554*ebfedea0SLionel Sambuc }
555*ebfedea0SLionel Sambuc
556*ebfedea0SLionel Sambuc /**
557*ebfedea0SLionel Sambuc \ingroup Core_Crypto
558*ebfedea0SLionel Sambuc \brief Decrypts RSA-encrypted data
559*ebfedea0SLionel Sambuc \param out Where to write the plaintext
560*ebfedea0SLionel Sambuc \param in Encrypted data
561*ebfedea0SLionel Sambuc \param length Length of encrypted data
562*ebfedea0SLionel Sambuc \param seckey RSA secret key
563*ebfedea0SLionel Sambuc \param pubkey RSA public key
564*ebfedea0SLionel Sambuc \return size of recovered plaintext
565*ebfedea0SLionel Sambuc */
566*ebfedea0SLionel Sambuc 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)567*ebfedea0SLionel Sambuc pgp_rsa_private_decrypt(uint8_t *out,
568*ebfedea0SLionel Sambuc const uint8_t *in,
569*ebfedea0SLionel Sambuc size_t length,
570*ebfedea0SLionel Sambuc const pgp_rsa_seckey_t *seckey,
571*ebfedea0SLionel Sambuc const pgp_rsa_pubkey_t *pubkey)
572*ebfedea0SLionel Sambuc {
573*ebfedea0SLionel Sambuc RSA *keypair;
574*ebfedea0SLionel Sambuc int n;
575*ebfedea0SLionel Sambuc char errbuf[1024];
576*ebfedea0SLionel Sambuc
577*ebfedea0SLionel Sambuc keypair = RSA_new();
578*ebfedea0SLionel Sambuc keypair->n = pubkey->n; /* XXX: do we need n? */
579*ebfedea0SLionel Sambuc keypair->d = seckey->d;
580*ebfedea0SLionel Sambuc keypair->p = seckey->q;
581*ebfedea0SLionel Sambuc keypair->q = seckey->p;
582*ebfedea0SLionel Sambuc
583*ebfedea0SLionel Sambuc /* debug */
584*ebfedea0SLionel Sambuc keypair->e = pubkey->e;
585*ebfedea0SLionel Sambuc if (RSA_check_key(keypair) != 1) {
586*ebfedea0SLionel Sambuc (void) fprintf(stderr, "RSA_check_key is not set\n");
587*ebfedea0SLionel Sambuc return 0;
588*ebfedea0SLionel Sambuc }
589*ebfedea0SLionel Sambuc /* end debug */
590*ebfedea0SLionel Sambuc
591*ebfedea0SLionel Sambuc n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING);
592*ebfedea0SLionel Sambuc
593*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
594*ebfedea0SLionel Sambuc printf("pgp_rsa_private_decrypt: n=%d\n",n);
595*ebfedea0SLionel Sambuc }
596*ebfedea0SLionel Sambuc
597*ebfedea0SLionel Sambuc errbuf[0] = '\0';
598*ebfedea0SLionel Sambuc if (n == -1) {
599*ebfedea0SLionel Sambuc unsigned long err = ERR_get_error();
600*ebfedea0SLionel Sambuc
601*ebfedea0SLionel Sambuc ERR_error_string(err, &errbuf[0]);
602*ebfedea0SLionel Sambuc (void) fprintf(stderr, "openssl error : %s\n", errbuf);
603*ebfedea0SLionel Sambuc }
604*ebfedea0SLionel Sambuc keypair->n = keypair->d = keypair->p = keypair->q = NULL;
605*ebfedea0SLionel Sambuc RSA_free(keypair);
606*ebfedea0SLionel Sambuc
607*ebfedea0SLionel Sambuc return n;
608*ebfedea0SLionel Sambuc }
609*ebfedea0SLionel Sambuc
610*ebfedea0SLionel Sambuc /**
611*ebfedea0SLionel Sambuc \ingroup Core_Crypto
612*ebfedea0SLionel Sambuc \brief RSA-encrypts data
613*ebfedea0SLionel Sambuc \param out Where to write the encrypted data
614*ebfedea0SLionel Sambuc \param in Plaintext
615*ebfedea0SLionel Sambuc \param length Size of plaintext
616*ebfedea0SLionel Sambuc \param pubkey RSA Public Key
617*ebfedea0SLionel Sambuc */
618*ebfedea0SLionel Sambuc int
pgp_rsa_public_encrypt(uint8_t * out,const uint8_t * in,size_t length,const pgp_rsa_pubkey_t * pubkey)619*ebfedea0SLionel Sambuc pgp_rsa_public_encrypt(uint8_t *out,
620*ebfedea0SLionel Sambuc const uint8_t *in,
621*ebfedea0SLionel Sambuc size_t length,
622*ebfedea0SLionel Sambuc const pgp_rsa_pubkey_t *pubkey)
623*ebfedea0SLionel Sambuc {
624*ebfedea0SLionel Sambuc RSA *orsa;
625*ebfedea0SLionel Sambuc int n;
626*ebfedea0SLionel Sambuc
627*ebfedea0SLionel Sambuc /* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */
628*ebfedea0SLionel Sambuc
629*ebfedea0SLionel Sambuc orsa = RSA_new();
630*ebfedea0SLionel Sambuc orsa->n = pubkey->n;
631*ebfedea0SLionel Sambuc orsa->e = pubkey->e;
632*ebfedea0SLionel Sambuc
633*ebfedea0SLionel Sambuc /* printf("len: %ld\n", length); */
634*ebfedea0SLionel Sambuc /* pgp_print_bn("n: ", orsa->n); */
635*ebfedea0SLionel Sambuc /* pgp_print_bn("e: ", orsa->e); */
636*ebfedea0SLionel Sambuc n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
637*ebfedea0SLionel Sambuc
638*ebfedea0SLionel Sambuc if (n == -1) {
639*ebfedea0SLionel Sambuc BIO *fd_out;
640*ebfedea0SLionel Sambuc
641*ebfedea0SLionel Sambuc fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
642*ebfedea0SLionel Sambuc ERR_print_errors(fd_out);
643*ebfedea0SLionel Sambuc }
644*ebfedea0SLionel Sambuc orsa->n = orsa->e = NULL;
645*ebfedea0SLionel Sambuc RSA_free(orsa);
646*ebfedea0SLionel Sambuc
647*ebfedea0SLionel Sambuc return n;
648*ebfedea0SLionel Sambuc }
649*ebfedea0SLionel Sambuc
650*ebfedea0SLionel Sambuc /**
651*ebfedea0SLionel Sambuc \ingroup Core_Crypto
652*ebfedea0SLionel Sambuc \brief Finalise openssl
653*ebfedea0SLionel Sambuc \note Would usually call pgp_finish() instead
654*ebfedea0SLionel Sambuc \sa pgp_finish()
655*ebfedea0SLionel Sambuc */
656*ebfedea0SLionel Sambuc void
pgp_crypto_finish(void)657*ebfedea0SLionel Sambuc pgp_crypto_finish(void)
658*ebfedea0SLionel Sambuc {
659*ebfedea0SLionel Sambuc CRYPTO_cleanup_all_ex_data();
660*ebfedea0SLionel Sambuc ERR_remove_state((unsigned long)0);
661*ebfedea0SLionel Sambuc }
662*ebfedea0SLionel Sambuc
663*ebfedea0SLionel Sambuc /**
664*ebfedea0SLionel Sambuc \ingroup Core_Hashes
665*ebfedea0SLionel Sambuc \brief Get Hash name
666*ebfedea0SLionel Sambuc \param hash Hash struct
667*ebfedea0SLionel Sambuc \return Hash name
668*ebfedea0SLionel Sambuc */
669*ebfedea0SLionel Sambuc const char *
pgp_text_from_hash(pgp_hash_t * hash)670*ebfedea0SLionel Sambuc pgp_text_from_hash(pgp_hash_t *hash)
671*ebfedea0SLionel Sambuc {
672*ebfedea0SLionel Sambuc return hash->name;
673*ebfedea0SLionel Sambuc }
674*ebfedea0SLionel Sambuc
675*ebfedea0SLionel Sambuc /**
676*ebfedea0SLionel Sambuc \ingroup HighLevel_KeyGenerate
677*ebfedea0SLionel Sambuc \brief Generates an RSA keypair
678*ebfedea0SLionel Sambuc \param numbits Modulus size
679*ebfedea0SLionel Sambuc \param e Public Exponent
680*ebfedea0SLionel Sambuc \param keydata Pointer to keydata struct to hold new key
681*ebfedea0SLionel Sambuc \return 1 if key generated successfully; otherwise 0
682*ebfedea0SLionel Sambuc \note It is the caller's responsibility to call pgp_keydata_free(keydata)
683*ebfedea0SLionel Sambuc */
684*ebfedea0SLionel Sambuc static unsigned
rsa_generate_keypair(pgp_key_t * keydata,const int numbits,const unsigned long e,const char * hashalg,const char * cipher)685*ebfedea0SLionel Sambuc rsa_generate_keypair(pgp_key_t *keydata,
686*ebfedea0SLionel Sambuc const int numbits,
687*ebfedea0SLionel Sambuc const unsigned long e,
688*ebfedea0SLionel Sambuc const char *hashalg,
689*ebfedea0SLionel Sambuc const char *cipher)
690*ebfedea0SLionel Sambuc {
691*ebfedea0SLionel Sambuc pgp_seckey_t *seckey;
692*ebfedea0SLionel Sambuc RSA *rsa;
693*ebfedea0SLionel Sambuc BN_CTX *ctx;
694*ebfedea0SLionel Sambuc pgp_output_t *output;
695*ebfedea0SLionel Sambuc pgp_memory_t *mem;
696*ebfedea0SLionel Sambuc
697*ebfedea0SLionel Sambuc ctx = BN_CTX_new();
698*ebfedea0SLionel Sambuc pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
699*ebfedea0SLionel Sambuc seckey = pgp_get_writable_seckey(keydata);
700*ebfedea0SLionel Sambuc
701*ebfedea0SLionel Sambuc /* generate the key pair */
702*ebfedea0SLionel Sambuc
703*ebfedea0SLionel Sambuc rsa = RSA_generate_key(numbits, e, NULL, NULL);
704*ebfedea0SLionel Sambuc
705*ebfedea0SLionel Sambuc /* populate pgp key from ssl key */
706*ebfedea0SLionel Sambuc
707*ebfedea0SLionel Sambuc seckey->pubkey.version = PGP_V4;
708*ebfedea0SLionel Sambuc seckey->pubkey.birthtime = time(NULL);
709*ebfedea0SLionel Sambuc seckey->pubkey.days_valid = 0;
710*ebfedea0SLionel Sambuc seckey->pubkey.alg = PGP_PKA_RSA;
711*ebfedea0SLionel Sambuc
712*ebfedea0SLionel Sambuc seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
713*ebfedea0SLionel Sambuc seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
714*ebfedea0SLionel Sambuc
715*ebfedea0SLionel Sambuc seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
716*ebfedea0SLionel Sambuc seckey->s2k_specifier = PGP_S2KS_SALTED;
717*ebfedea0SLionel Sambuc /* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */
718*ebfedea0SLionel Sambuc if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
719*ebfedea0SLionel Sambuc seckey->hash_alg = PGP_HASH_SHA1;
720*ebfedea0SLionel Sambuc }
721*ebfedea0SLionel Sambuc seckey->alg = pgp_str_to_cipher(cipher);
722*ebfedea0SLionel Sambuc seckey->octetc = 0;
723*ebfedea0SLionel Sambuc seckey->checksum = 0;
724*ebfedea0SLionel Sambuc
725*ebfedea0SLionel Sambuc seckey->key.rsa.d = BN_dup(rsa->d);
726*ebfedea0SLionel Sambuc seckey->key.rsa.p = BN_dup(rsa->p);
727*ebfedea0SLionel Sambuc seckey->key.rsa.q = BN_dup(rsa->q);
728*ebfedea0SLionel Sambuc seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
729*ebfedea0SLionel Sambuc if (seckey->key.rsa.u == NULL) {
730*ebfedea0SLionel Sambuc (void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
731*ebfedea0SLionel Sambuc return 0;
732*ebfedea0SLionel Sambuc }
733*ebfedea0SLionel Sambuc BN_CTX_free(ctx);
734*ebfedea0SLionel Sambuc
735*ebfedea0SLionel Sambuc RSA_free(rsa);
736*ebfedea0SLionel Sambuc
737*ebfedea0SLionel Sambuc pgp_keyid(keydata->sigid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
738*ebfedea0SLionel Sambuc pgp_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
739*ebfedea0SLionel Sambuc
740*ebfedea0SLionel Sambuc /* Generate checksum */
741*ebfedea0SLionel Sambuc
742*ebfedea0SLionel Sambuc output = NULL;
743*ebfedea0SLionel Sambuc mem = NULL;
744*ebfedea0SLionel Sambuc
745*ebfedea0SLionel Sambuc pgp_setup_memory_write(&output, &mem, 128);
746*ebfedea0SLionel Sambuc
747*ebfedea0SLionel Sambuc pgp_push_checksum_writer(output, seckey);
748*ebfedea0SLionel Sambuc
749*ebfedea0SLionel Sambuc switch (seckey->pubkey.alg) {
750*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
751*ebfedea0SLionel Sambuc return pgp_write_mpi(output, seckey->key.dsa.x);
752*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
753*ebfedea0SLionel Sambuc case PGP_PKA_RSA_ENCRYPT_ONLY:
754*ebfedea0SLionel Sambuc case PGP_PKA_RSA_SIGN_ONLY:
755*ebfedea0SLionel Sambuc if (!pgp_write_mpi(output, seckey->key.rsa.d) ||
756*ebfedea0SLionel Sambuc !pgp_write_mpi(output, seckey->key.rsa.p) ||
757*ebfedea0SLionel Sambuc !pgp_write_mpi(output, seckey->key.rsa.q) ||
758*ebfedea0SLionel Sambuc !pgp_write_mpi(output, seckey->key.rsa.u)) {
759*ebfedea0SLionel Sambuc return 0;
760*ebfedea0SLionel Sambuc }
761*ebfedea0SLionel Sambuc break;
762*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL:
763*ebfedea0SLionel Sambuc return pgp_write_mpi(output, seckey->key.elgamal.x);
764*ebfedea0SLionel Sambuc
765*ebfedea0SLionel Sambuc default:
766*ebfedea0SLionel Sambuc (void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
767*ebfedea0SLionel Sambuc return 0;
768*ebfedea0SLionel Sambuc }
769*ebfedea0SLionel Sambuc
770*ebfedea0SLionel Sambuc /* close rather than pop, since its the only one on the stack */
771*ebfedea0SLionel Sambuc pgp_writer_close(output);
772*ebfedea0SLionel Sambuc pgp_teardown_memory_write(output, mem);
773*ebfedea0SLionel Sambuc
774*ebfedea0SLionel Sambuc /* should now have checksum in seckey struct */
775*ebfedea0SLionel Sambuc
776*ebfedea0SLionel Sambuc /* test */
777*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
778*ebfedea0SLionel Sambuc test_seckey(seckey);
779*ebfedea0SLionel Sambuc }
780*ebfedea0SLionel Sambuc
781*ebfedea0SLionel Sambuc return 1;
782*ebfedea0SLionel Sambuc }
783*ebfedea0SLionel Sambuc
784*ebfedea0SLionel Sambuc /**
785*ebfedea0SLionel Sambuc \ingroup HighLevel_KeyGenerate
786*ebfedea0SLionel Sambuc \brief Creates a self-signed RSA keypair
787*ebfedea0SLionel Sambuc \param numbits Modulus size
788*ebfedea0SLionel Sambuc \param e Public Exponent
789*ebfedea0SLionel Sambuc \param userid User ID
790*ebfedea0SLionel Sambuc \return The new keypair or NULL
791*ebfedea0SLionel Sambuc
792*ebfedea0SLionel Sambuc \note It is the caller's responsibility to call pgp_keydata_free(keydata)
793*ebfedea0SLionel Sambuc \sa rsa_generate_keypair()
794*ebfedea0SLionel Sambuc \sa pgp_keydata_free()
795*ebfedea0SLionel Sambuc */
796*ebfedea0SLionel Sambuc pgp_key_t *
pgp_rsa_new_selfsign_key(const int numbits,const unsigned long e,uint8_t * userid,const char * hashalg,const char * cipher)797*ebfedea0SLionel Sambuc pgp_rsa_new_selfsign_key(const int numbits,
798*ebfedea0SLionel Sambuc const unsigned long e,
799*ebfedea0SLionel Sambuc uint8_t *userid,
800*ebfedea0SLionel Sambuc const char *hashalg,
801*ebfedea0SLionel Sambuc const char *cipher)
802*ebfedea0SLionel Sambuc {
803*ebfedea0SLionel Sambuc pgp_key_t *keydata;
804*ebfedea0SLionel Sambuc
805*ebfedea0SLionel Sambuc keydata = pgp_keydata_new();
806*ebfedea0SLionel Sambuc if (!rsa_generate_keypair(keydata, numbits, e, hashalg, cipher) ||
807*ebfedea0SLionel Sambuc !pgp_add_selfsigned_userid(keydata, userid)) {
808*ebfedea0SLionel Sambuc pgp_keydata_free(keydata);
809*ebfedea0SLionel Sambuc return NULL;
810*ebfedea0SLionel Sambuc }
811*ebfedea0SLionel Sambuc return keydata;
812*ebfedea0SLionel Sambuc }
813*ebfedea0SLionel Sambuc
814*ebfedea0SLionel Sambuc DSA_SIG *
pgp_dsa_sign(uint8_t * hashbuf,unsigned hashsize,const pgp_dsa_seckey_t * secdsa,const pgp_dsa_pubkey_t * pubdsa)815*ebfedea0SLionel Sambuc pgp_dsa_sign(uint8_t *hashbuf,
816*ebfedea0SLionel Sambuc unsigned hashsize,
817*ebfedea0SLionel Sambuc const pgp_dsa_seckey_t *secdsa,
818*ebfedea0SLionel Sambuc const pgp_dsa_pubkey_t *pubdsa)
819*ebfedea0SLionel Sambuc {
820*ebfedea0SLionel Sambuc DSA_SIG *dsasig;
821*ebfedea0SLionel Sambuc DSA *odsa;
822*ebfedea0SLionel Sambuc
823*ebfedea0SLionel Sambuc odsa = DSA_new();
824*ebfedea0SLionel Sambuc odsa->p = pubdsa->p;
825*ebfedea0SLionel Sambuc odsa->q = pubdsa->q;
826*ebfedea0SLionel Sambuc odsa->g = pubdsa->g;
827*ebfedea0SLionel Sambuc odsa->pub_key = pubdsa->y;
828*ebfedea0SLionel Sambuc odsa->priv_key = secdsa->x;
829*ebfedea0SLionel Sambuc
830*ebfedea0SLionel Sambuc dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
831*ebfedea0SLionel Sambuc
832*ebfedea0SLionel Sambuc odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
833*ebfedea0SLionel Sambuc DSA_free(odsa);
834*ebfedea0SLionel Sambuc
835*ebfedea0SLionel Sambuc return dsasig;
836*ebfedea0SLionel Sambuc }
837*ebfedea0SLionel Sambuc
838*ebfedea0SLionel Sambuc int
openssl_read_pem_seckey(const char * f,pgp_key_t * key,const char * type,int verbose)839*ebfedea0SLionel Sambuc openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose)
840*ebfedea0SLionel Sambuc {
841*ebfedea0SLionel Sambuc FILE *fp;
842*ebfedea0SLionel Sambuc char prompt[BUFSIZ];
843*ebfedea0SLionel Sambuc char *pass;
844*ebfedea0SLionel Sambuc DSA *dsa;
845*ebfedea0SLionel Sambuc RSA *rsa;
846*ebfedea0SLionel Sambuc int ok;
847*ebfedea0SLionel Sambuc
848*ebfedea0SLionel Sambuc OpenSSL_add_all_algorithms();
849*ebfedea0SLionel Sambuc if ((fp = fopen(f, "r")) == NULL) {
850*ebfedea0SLionel Sambuc if (verbose) {
851*ebfedea0SLionel Sambuc (void) fprintf(stderr, "can't open '%s'\n", f);
852*ebfedea0SLionel Sambuc }
853*ebfedea0SLionel Sambuc return 0;
854*ebfedea0SLionel Sambuc }
855*ebfedea0SLionel Sambuc ok = 1;
856*ebfedea0SLionel Sambuc if (strcmp(type, "ssh-rsa") == 0) {
857*ebfedea0SLionel Sambuc if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
858*ebfedea0SLionel Sambuc (void) snprintf(prompt, sizeof(prompt), "netpgp PEM %s passphrase: ", f);
859*ebfedea0SLionel Sambuc do {
860*ebfedea0SLionel Sambuc pass = getpass(prompt);
861*ebfedea0SLionel Sambuc rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, pass);
862*ebfedea0SLionel Sambuc } while (rsa == NULL);
863*ebfedea0SLionel Sambuc }
864*ebfedea0SLionel Sambuc key->key.seckey.key.rsa.d = rsa->d;
865*ebfedea0SLionel Sambuc key->key.seckey.key.rsa.p = rsa->p;
866*ebfedea0SLionel Sambuc key->key.seckey.key.rsa.q = rsa->q;
867*ebfedea0SLionel Sambuc key->key.seckey.key.rsa.d = rsa->d;
868*ebfedea0SLionel Sambuc } else if (strcmp(type, "ssh-dss") == 0) {
869*ebfedea0SLionel Sambuc if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
870*ebfedea0SLionel Sambuc ok = 0;
871*ebfedea0SLionel Sambuc } else {
872*ebfedea0SLionel Sambuc key->key.seckey.key.dsa.x = dsa->priv_key;
873*ebfedea0SLionel Sambuc }
874*ebfedea0SLionel Sambuc } else {
875*ebfedea0SLionel Sambuc ok = 0;
876*ebfedea0SLionel Sambuc }
877*ebfedea0SLionel Sambuc (void) fclose(fp);
878*ebfedea0SLionel Sambuc return ok;
879*ebfedea0SLionel Sambuc }
880*ebfedea0SLionel Sambuc
881*ebfedea0SLionel Sambuc /*
882*ebfedea0SLionel Sambuc * Decide the number of bits in the random componont k
883*ebfedea0SLionel Sambuc *
884*ebfedea0SLionel Sambuc * It should be in the same range as p for signing (which
885*ebfedea0SLionel Sambuc * is deprecated), but can be much smaller for encrypting.
886*ebfedea0SLionel Sambuc *
887*ebfedea0SLionel Sambuc * Until I research it further, I just mimic gpg behaviour.
888*ebfedea0SLionel Sambuc * It has a special mapping table, for values <= 5120,
889*ebfedea0SLionel Sambuc * above that it uses 'arbitrary high number'. Following
890*ebfedea0SLionel Sambuc * algorihm hovers 10-70 bits above gpg values. And for
891*ebfedea0SLionel Sambuc * larger p, it uses gpg's algorihm.
892*ebfedea0SLionel Sambuc *
893*ebfedea0SLionel Sambuc * The point is - if k gets large, encryption will be
894*ebfedea0SLionel Sambuc * really slow. It does not matter for decryption.
895*ebfedea0SLionel Sambuc */
896*ebfedea0SLionel Sambuc static int
decide_k_bits(int p_bits)897*ebfedea0SLionel Sambuc decide_k_bits(int p_bits)
898*ebfedea0SLionel Sambuc {
899*ebfedea0SLionel Sambuc return (p_bits <= 5120) ? p_bits / 10 + 160 : (p_bits / 8 + 200) * 3 / 2;
900*ebfedea0SLionel Sambuc }
901*ebfedea0SLionel Sambuc
902*ebfedea0SLionel Sambuc 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)903*ebfedea0SLionel Sambuc pgp_elgamal_public_encrypt(uint8_t *g_to_k, uint8_t *encm,
904*ebfedea0SLionel Sambuc const uint8_t *in,
905*ebfedea0SLionel Sambuc size_t size,
906*ebfedea0SLionel Sambuc const pgp_elgamal_pubkey_t *pubkey)
907*ebfedea0SLionel Sambuc {
908*ebfedea0SLionel Sambuc int ret = 0;
909*ebfedea0SLionel Sambuc int k_bits;
910*ebfedea0SLionel Sambuc BIGNUM *m;
911*ebfedea0SLionel Sambuc BIGNUM *p;
912*ebfedea0SLionel Sambuc BIGNUM *g;
913*ebfedea0SLionel Sambuc BIGNUM *y;
914*ebfedea0SLionel Sambuc BIGNUM *k;
915*ebfedea0SLionel Sambuc BIGNUM *yk;
916*ebfedea0SLionel Sambuc BIGNUM *c1;
917*ebfedea0SLionel Sambuc BIGNUM *c2;
918*ebfedea0SLionel Sambuc BN_CTX *tmp;
919*ebfedea0SLionel Sambuc
920*ebfedea0SLionel Sambuc m = BN_bin2bn(in, (int)size, NULL);
921*ebfedea0SLionel Sambuc p = pubkey->p;
922*ebfedea0SLionel Sambuc g = pubkey->g;
923*ebfedea0SLionel Sambuc y = pubkey->y;
924*ebfedea0SLionel Sambuc k = BN_new();
925*ebfedea0SLionel Sambuc yk = BN_new();
926*ebfedea0SLionel Sambuc c1 = BN_new();
927*ebfedea0SLionel Sambuc c2 = BN_new();
928*ebfedea0SLionel Sambuc tmp = BN_CTX_new();
929*ebfedea0SLionel Sambuc if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp) {
930*ebfedea0SLionel Sambuc goto done;
931*ebfedea0SLionel Sambuc }
932*ebfedea0SLionel Sambuc /*
933*ebfedea0SLionel Sambuc * generate k
934*ebfedea0SLionel Sambuc */
935*ebfedea0SLionel Sambuc k_bits = decide_k_bits(BN_num_bits(p));
936*ebfedea0SLionel Sambuc if (!BN_rand(k, k_bits, 0, 0)) {
937*ebfedea0SLionel Sambuc goto done;
938*ebfedea0SLionel Sambuc }
939*ebfedea0SLionel Sambuc /*
940*ebfedea0SLionel Sambuc * c1 = g^k c2 = m * y^k
941*ebfedea0SLionel Sambuc */
942*ebfedea0SLionel Sambuc if (!BN_mod_exp(c1, g, k, p, tmp)) {
943*ebfedea0SLionel Sambuc goto done;
944*ebfedea0SLionel Sambuc }
945*ebfedea0SLionel Sambuc if (!BN_mod_exp(yk, y, k, p, tmp)) {
946*ebfedea0SLionel Sambuc goto done;
947*ebfedea0SLionel Sambuc }
948*ebfedea0SLionel Sambuc if (!BN_mod_mul(c2, m, yk, p, tmp)) {
949*ebfedea0SLionel Sambuc goto done;
950*ebfedea0SLionel Sambuc }
951*ebfedea0SLionel Sambuc /* result */
952*ebfedea0SLionel Sambuc BN_bn2bin(c1, g_to_k);
953*ebfedea0SLionel Sambuc ret = BN_num_bytes(c1); /* c1 = g^k */
954*ebfedea0SLionel Sambuc BN_bn2bin(c2, encm);
955*ebfedea0SLionel Sambuc ret += BN_num_bytes(c2); /* c2 = m * y^k */
956*ebfedea0SLionel Sambuc done:
957*ebfedea0SLionel Sambuc if (tmp) {
958*ebfedea0SLionel Sambuc BN_CTX_free(tmp);
959*ebfedea0SLionel Sambuc }
960*ebfedea0SLionel Sambuc if (c2) {
961*ebfedea0SLionel Sambuc BN_clear_free(c2);
962*ebfedea0SLionel Sambuc }
963*ebfedea0SLionel Sambuc if (c1) {
964*ebfedea0SLionel Sambuc BN_clear_free(c1);
965*ebfedea0SLionel Sambuc }
966*ebfedea0SLionel Sambuc if (yk) {
967*ebfedea0SLionel Sambuc BN_clear_free(yk);
968*ebfedea0SLionel Sambuc }
969*ebfedea0SLionel Sambuc if (k) {
970*ebfedea0SLionel Sambuc BN_clear_free(k);
971*ebfedea0SLionel Sambuc }
972*ebfedea0SLionel Sambuc if (g) {
973*ebfedea0SLionel Sambuc BN_clear_free(g);
974*ebfedea0SLionel Sambuc }
975*ebfedea0SLionel Sambuc return ret;
976*ebfedea0SLionel Sambuc }
977*ebfedea0SLionel Sambuc
978*ebfedea0SLionel Sambuc 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)979*ebfedea0SLionel Sambuc pgp_elgamal_private_decrypt(uint8_t *out,
980*ebfedea0SLionel Sambuc const uint8_t *g_to_k,
981*ebfedea0SLionel Sambuc const uint8_t *in,
982*ebfedea0SLionel Sambuc size_t length,
983*ebfedea0SLionel Sambuc const pgp_elgamal_seckey_t *seckey,
984*ebfedea0SLionel Sambuc const pgp_elgamal_pubkey_t *pubkey)
985*ebfedea0SLionel Sambuc {
986*ebfedea0SLionel Sambuc BIGNUM *bndiv;
987*ebfedea0SLionel Sambuc BIGNUM *c1x;
988*ebfedea0SLionel Sambuc BN_CTX *tmp;
989*ebfedea0SLionel Sambuc BIGNUM *c1;
990*ebfedea0SLionel Sambuc BIGNUM *c2;
991*ebfedea0SLionel Sambuc BIGNUM *p;
992*ebfedea0SLionel Sambuc BIGNUM *x;
993*ebfedea0SLionel Sambuc BIGNUM *m;
994*ebfedea0SLionel Sambuc int ret;
995*ebfedea0SLionel Sambuc
996*ebfedea0SLionel Sambuc ret = 0;
997*ebfedea0SLionel Sambuc /* c1 and c2 are in g_to_k and in, respectively*/
998*ebfedea0SLionel Sambuc c1 = BN_bin2bn(g_to_k, (int)length, NULL);
999*ebfedea0SLionel Sambuc c2 = BN_bin2bn(in, (int)length, NULL);
1000*ebfedea0SLionel Sambuc /* other bits */
1001*ebfedea0SLionel Sambuc p = pubkey->p;
1002*ebfedea0SLionel Sambuc x = seckey->x;
1003*ebfedea0SLionel Sambuc c1x = BN_new();
1004*ebfedea0SLionel Sambuc bndiv = BN_new();
1005*ebfedea0SLionel Sambuc m = BN_new();
1006*ebfedea0SLionel Sambuc tmp = BN_CTX_new();
1007*ebfedea0SLionel Sambuc if (!c1 || !c2 || !p || !x || !c1x || !bndiv || !m || !tmp) {
1008*ebfedea0SLionel Sambuc goto done;
1009*ebfedea0SLionel Sambuc }
1010*ebfedea0SLionel Sambuc /*
1011*ebfedea0SLionel Sambuc * m = c2 / (c1^x)
1012*ebfedea0SLionel Sambuc */
1013*ebfedea0SLionel Sambuc if (!BN_mod_exp(c1x, c1, x, p, tmp)) {
1014*ebfedea0SLionel Sambuc goto done;
1015*ebfedea0SLionel Sambuc }
1016*ebfedea0SLionel Sambuc if (!BN_mod_inverse(bndiv, c1x, p, tmp)) {
1017*ebfedea0SLionel Sambuc goto done;
1018*ebfedea0SLionel Sambuc }
1019*ebfedea0SLionel Sambuc if (!BN_mod_mul(m, c2, bndiv, p, tmp)) {
1020*ebfedea0SLionel Sambuc goto done;
1021*ebfedea0SLionel Sambuc }
1022*ebfedea0SLionel Sambuc /* result */
1023*ebfedea0SLionel Sambuc ret = BN_bn2bin(m, out);
1024*ebfedea0SLionel Sambuc done:
1025*ebfedea0SLionel Sambuc if (tmp) {
1026*ebfedea0SLionel Sambuc BN_CTX_free(tmp);
1027*ebfedea0SLionel Sambuc }
1028*ebfedea0SLionel Sambuc if (m) {
1029*ebfedea0SLionel Sambuc BN_clear_free(m);
1030*ebfedea0SLionel Sambuc }
1031*ebfedea0SLionel Sambuc if (bndiv) {
1032*ebfedea0SLionel Sambuc BN_clear_free(bndiv);
1033*ebfedea0SLionel Sambuc }
1034*ebfedea0SLionel Sambuc if (c1x) {
1035*ebfedea0SLionel Sambuc BN_clear_free(c1x);
1036*ebfedea0SLionel Sambuc }
1037*ebfedea0SLionel Sambuc if (x) {
1038*ebfedea0SLionel Sambuc BN_clear_free(x);
1039*ebfedea0SLionel Sambuc }
1040*ebfedea0SLionel Sambuc if (p) {
1041*ebfedea0SLionel Sambuc BN_clear_free(p);
1042*ebfedea0SLionel Sambuc }
1043*ebfedea0SLionel Sambuc if (c1) {
1044*ebfedea0SLionel Sambuc BN_clear_free(c1);
1045*ebfedea0SLionel Sambuc }
1046*ebfedea0SLionel Sambuc if (c2) {
1047*ebfedea0SLionel Sambuc BN_clear_free(c2);
1048*ebfedea0SLionel Sambuc }
1049*ebfedea0SLionel Sambuc return ret;
1050*ebfedea0SLionel Sambuc }
1051