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