diff --git a/crypto/external/bsd/netpgp/dist/src/lib/create.c b/crypto/external/bsd/netpgp/dist/src/lib/create.c index 00d85fe59830..a0b60a4cbe7b 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/create.c +++ b/crypto/external/bsd/netpgp/dist/src/lib/create.c @@ -57,7 +57,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: create.c,v 1.38 2010/11/15 08:03:39 agc Exp $"); +__RCSID("$NetBSD: create.c,v 1.39 2022/08/26 19:18:38 jhigh Exp $"); #endif #include @@ -250,6 +250,11 @@ write_pubkey_body(const pgp_pubkey_t *key, pgp_output_t *output) pgp_write_mpi(output, key->key.dsa.g) && pgp_write_mpi(output, key->key.dsa.y); + case PGP_PKA_ECDSA: + return pgp_write(output, &key->key.ecdsa.len, 1) && + pgp_write(output, key->key.ecdsa.oid, key->key.ecdsa.len) && + pgp_write_mpi(output, key->key.ecdsa.p); + case PGP_PKA_RSA: case PGP_PKA_RSA_ENCRYPT_ONLY: case PGP_PKA_RSA_SIGN_ONLY: diff --git a/crypto/external/bsd/netpgp/dist/src/lib/crypto.h b/crypto/external/bsd/netpgp/dist/src/lib/crypto.h index ff631efedf2a..a781ba0e79a6 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/crypto.h +++ b/crypto/external/bsd/netpgp/dist/src/lib/crypto.h @@ -58,7 +58,9 @@ #include "memory.h" #include "packet-parse.h" +#include #include +#include #define PGP_MIN_HASH_SIZE 16 @@ -119,6 +121,10 @@ unsigned pgp_dsa_verify(const uint8_t *, size_t, const pgp_dsa_sig_t *, const pgp_dsa_pubkey_t *); +unsigned pgp_ecdsa_verify(const uint8_t *, size_t, + const pgp_ecdsa_sig_t *, + const pgp_ecdsa_pubkey_t *); + int pgp_rsa_public_decrypt(uint8_t *, const uint8_t *, size_t, const pgp_rsa_pubkey_t *); int pgp_rsa_public_encrypt(uint8_t *, const uint8_t *, size_t, @@ -214,6 +220,10 @@ DSA_SIG *pgp_dsa_sign(uint8_t *, unsigned, const pgp_dsa_seckey_t *, const pgp_dsa_pubkey_t *); +ECDSA_SIG *pgp_ecdsa_sign(uint8_t *, unsigned, + const pgp_ecdsa_seckey_t *, + const pgp_ecdsa_pubkey_t *); + int openssl_read_pem_seckey(const char *, pgp_key_t *, const char *, int); /** pgp_reader_t */ diff --git a/crypto/external/bsd/netpgp/dist/src/lib/misc.c b/crypto/external/bsd/netpgp/dist/src/lib/misc.c index cf25f02ddd9d..0592ff33b496 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/misc.c +++ b/crypto/external/bsd/netpgp/dist/src/lib/misc.c @@ -57,7 +57,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: misc.c,v 1.43 2020/04/18 19:27:48 jhigh Exp $"); +__RCSID("$NetBSD: misc.c,v 1.44 2022/08/26 19:18:38 jhigh Exp $"); #endif #include @@ -96,6 +96,18 @@ __RCSID("$NetBSD: misc.c,v 1.43 2020/04/18 19:27:48 jhigh Exp $"); #define vsnprintf _vsnprintf #endif +struct ecdsa_map { + char *sname; + int nid; + int bits; + int len; + uint8_t oid[8]; +} ecdsa_map[] = { + { "P-256", NID_X9_62_prime256v1, 256, 8, {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07} }, + { "P-384", NID_secp384r1, 384, 5, {0x2B, 0x81, 0x04, 0x00, 0x22} }, + { "P-521", NID_secp521r1, 521, 5, {0x2B, 0x81, 0x04, 0x00, 0x23} }, + { NULL, 0, 0, 0, {0} } +}; typedef struct { pgp_keyring_t *keyring; @@ -1364,3 +1376,75 @@ netpgp_strcasecmp(const char *s1, const char *s2) } return n; } + +int +ecdsa_nid(const pgp_ecdsa_pubkey_t * pub) +{ + int i; + + for (i = 0; ecdsa_map[i].sname; i++ ) { + if (pub->len == ecdsa_map[i].len) { + if (memcmp(pub->oid, ecdsa_map[i].oid, pub->len) == 0) { + return ecdsa_map[i].nid; + } + } + } + return -1; +} + +int +ecdsa_numbits(const pgp_ecdsa_pubkey_t * pub) +{ + int i; + + for (i = 0; ecdsa_map[i].sname; i++ ) { + if (pub->len == ecdsa_map[i].len) { + if (memcmp(pub->oid, ecdsa_map[i].oid, pub->len) == 0) { + return ecdsa_map[i].bits; + } + } + } + return -1; +} + +int +ecdsa_hashsize(const pgp_ecdsa_pubkey_t * pub) +{ + int bits; + + bits = ecdsa_numbits(pub); + + if (bits == -1) { + return -1; + } + + return (bits/8) - (bits%8); +} + +pgp_hash_alg_t +ecdsa_hashalg(const pgp_ecdsa_pubkey_t * pub) +{ + int nid; + + if (pub == NULL) { + return PGP_HASH_UNKNOWN; + } + + nid = ecdsa_nid(pub); + + switch (nid) { + case NID_X9_62_prime256v1: + return PGP_HASH_SHA256; + + case NID_secp384r1: + return PGP_HASH_SHA384; + + case NID_secp521r1: + return PGP_HASH_SHA512; + + default: + (void) fprintf(stderr, "ecdsa_hashalg: unknown NID\n"); + } + + return PGP_HASH_UNKNOWN; +} diff --git a/crypto/external/bsd/netpgp/dist/src/lib/netpgpsdk.h b/crypto/external/bsd/netpgp/dist/src/lib/netpgpsdk.h index 560a6436d415..4829f1ba4fb7 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/netpgpsdk.h +++ b/crypto/external/bsd/netpgp/dist/src/lib/netpgpsdk.h @@ -74,5 +74,9 @@ void netpgp_log(const char *, ...) __printflike(1, 2); int netpgp_strcasecmp(const char *, const char *); char *netpgp_strdup(const char *); +int ecdsa_numbits(const pgp_ecdsa_pubkey_t *); +int ecdsa_nid(const pgp_ecdsa_pubkey_t *); +pgp_hash_alg_t ecdsa_hashalg(const pgp_ecdsa_pubkey_t *); +int ecdsa_hashsize(const pgp_ecdsa_pubkey_t *); #endif diff --git a/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c b/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c index 458292c987e8..b52c83e500b1 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c +++ b/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c @@ -57,7 +57,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: openssl_crypto.c,v 1.34 2018/02/05 23:56:01 christos Exp $"); +__RCSID("$NetBSD: openssl_crypto.c,v 1.35 2022/08/26 19:18:38 jhigh Exp $"); #endif #ifdef HAVE_OPENSSL_DSA_H @@ -87,6 +87,7 @@ __RCSID("$NetBSD: openssl_crypto.c,v 1.34 2018/02/05 23:56:01 christos Exp $"); #include "readerwriter.h" #include "netpgpdefs.h" #include "netpgpdigest.h" +#include "netpgpsdk.h" #include "packet.h" static void @@ -223,6 +224,103 @@ takeDSA(const DSA *odsa, pgp_dsa_seckey_t *sk) sk->x = BN_dup(x); } +static ECDSA_SIG * +makeECDSADSA_SIG(const pgp_ecdsa_sig_t *sig) +{ + ECDSA_SIG *osig; + BIGNUM *r, *s; + + osig = ECDSA_SIG_new(); + r = BN_dup(sig->r); + s = BN_dup(sig->s); + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + ECDSA_SIG_set0(osig, r, s); +#else + BN_free(osig->r); + BN_free(osig->s); + osig->r = r; + osig->s = s; +#endif + + return osig; +} + +static EC_KEY * +makeECDSA(const pgp_ecdsa_pubkey_t *ecdsa, const pgp_ecdsa_seckey_t *sececdsa) +{ + EC_KEY *key; + BIGNUM *x; + BIGNUM *y; + EC_GROUP *group; + EC_POINT *pub_key; + EC_POINT *point; + int nid; + + key = EC_KEY_new(); + x = BN_new(); + y = BN_new(); + + nid = ecdsa_nid(ecdsa); + if (nid == -1) { + (void) fprintf(stderr,"makeECDSA: failed to determine NID\n"); + return 0; + } + + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) { + (void) fprintf(stderr,"makeECDSA: failed to get group for specified NID\n"); + return 0; + } + + pub_key = EC_POINT_new(group); + if (pub_key == NULL) { + (void) fprintf(stderr,"makeECDSA: failed to alloc point\n"); + return 0; + } + + point = EC_POINT_bn2point(group, ecdsa->p, NULL, NULL); + if (point == NULL) { + (void) fprintf(stderr,"makeECDSA: failed to conv BN to point\n"); + return 0; + } + + + if ((EC_POINT_get_affine_coordinates(group, point, x, y, NULL)) == 0) { + (void) fprintf(stderr,"makeECDSA: failed to get coordinates from point\n"); + return 0; + } + + if ((EC_POINT_set_affine_coordinates(group, pub_key, x, y, NULL)) == 0) { + (void) fprintf(stderr,"makeECDSA: failed to set coordinates from point\n"); + return 0; + } + + if ((EC_KEY_set_group(key, group)) == 0) { + (void) fprintf(stderr,"makeECDSA: failed to set group for key\n"); + return 0; + } + + if ((EC_KEY_set_public_key(key, pub_key)) == 0) { + (void) fprintf(stderr,"makeECDSA: failed to set pubkey for key\n"); + return 0; + } + + if (sececdsa) { + if ((EC_KEY_set_private_key(key, sececdsa->x)) == 0) { + (void) fprintf(stderr,"makeECDSA: failed to set seckey for key\n"); + return 0; + } + + if ((EC_POINT_mul(group, pub_key, sececdsa->x, NULL, NULL, NULL)) == 0) { + (void) fprintf(stderr,"makeECDSA: failed to calculate generator\n"); + return 0; + } + } + + return key; +} + static void test_seckey(const pgp_seckey_t *seckey) { @@ -587,6 +685,36 @@ pgp_dsa_verify(const uint8_t *hash, size_t hash_length, return (unsigned)ret; } +unsigned +pgp_ecdsa_verify(const uint8_t *hash, size_t hash_length, + const pgp_ecdsa_sig_t *sig, + const pgp_ecdsa_pubkey_t *ecdsa) +{ + unsigned qlen; + ECDSA_SIG *osig = makeECDSADSA_SIG(sig); + EC_KEY *oecdsa = makeECDSA(ecdsa, NULL); + int ret; + + if (pgp_get_debug_level(__FILE__)) { + hexdump(stderr, "input hash", hash, hash_length); + } + + ret = ECDSA_do_verify(hash, (int)hash_length, osig, oecdsa); + + if (pgp_get_debug_level(__FILE__)) { + (void) fprintf(stderr, "ret=%d\n", ret); + } + + if (ret <= 0) { + (void) fprintf(stderr, "pgp_ecdsa_verify: ECDSA verification failed\n"); + return 0; + } + + ECDSA_SIG_free(osig); + + return (unsigned)ret; +} + /** \ingroup Core_Crypto \brief Recovers message digest from the signature @@ -916,6 +1044,27 @@ pgp_dsa_sign(uint8_t *hashbuf, return dsasig; } +ECDSA_SIG * +pgp_ecdsa_sign(uint8_t *hashbuf, + unsigned hashsize, + const pgp_ecdsa_seckey_t *sececdsa, + const pgp_ecdsa_pubkey_t *pubecdsa) +{ + ECDSA_SIG * ecdsasig; + EC_KEY * eckey = makeECDSA(pubecdsa, sececdsa); + + ecdsasig = ECDSA_do_sign(hashbuf, (int)hashsize, eckey); + + if (ecdsasig == NULL) { + printf("do_sign returned null\n"); + return 0; + } + + EC_KEY_free(eckey); + + return ecdsasig; +} + int openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose) { diff --git a/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c b/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c index 03c4927fd9bb..c5e90e4c277c 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c +++ b/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c @@ -58,7 +58,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: packet-parse.c,v 1.53 2020/10/14 05:19:41 jhigh Exp $"); +__RCSID("$NetBSD: packet-parse.c,v 1.54 2022/08/26 19:18:38 jhigh Exp $"); #endif #include @@ -940,6 +940,11 @@ sig_free(pgp_sig_t *sig) free_BN(&sig->info.sig.dsa.s); break; + case PGP_PKA_ECDSA: + free_BN(&sig->info.sig.ecdsa.r); + free_BN(&sig->info.sig.ecdsa.s); + break; + case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: free_BN(&sig->info.sig.elgamal.r); free_BN(&sig->info.sig.elgamal.s); @@ -1176,6 +1181,10 @@ pgp_pubkey_free(pgp_pubkey_t *p) free_BN(&p->key.dsa.y); break; + case PGP_PKA_ECDSA: + free_BN(&p->key.ecdsa.p); + break; + case PGP_PKA_ELGAMAL: case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: free_BN(&p->key.elgamal.p); @@ -1245,6 +1254,14 @@ parse_pubkey_data(pgp_pubkey_t *key, pgp_region_t *region, } break; + case PGP_PKA_ECDSA: + if (!limread(&key->key.ecdsa.len, 1, region, stream) || + !limread(key->key.ecdsa.oid, key->key.ecdsa.len, region, stream) || + !limread_mpi(&key->key.ecdsa.p, region, stream)) { + return 0; + } + break; + case PGP_PKA_RSA: case PGP_PKA_RSA_ENCRYPT_ONLY: case PGP_PKA_RSA_SIGN_ONLY: @@ -1496,6 +1513,13 @@ parse_v3_sig(pgp_region_t *region, } break; + case PGP_PKA_ECDSA: + if (!limread_mpi(&pkt.u.sig.info.sig.ecdsa.r, region, stream) || + !limread_mpi(&pkt.u.sig.info.sig.ecdsa.s, region, stream)) { + return 0; + } + break; + case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region, stream) || @@ -2035,6 +2059,13 @@ parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream) } break; + case PGP_PKA_ECDSA: + if (!limread_mpi(&pkt.u.sig.info.sig.ecdsa.r, region, stream) || + !limread_mpi(&pkt.u.sig.info.sig.ecdsa.s, region, stream)) { + return 0; + } + break; + case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region, stream) || @@ -2322,6 +2353,10 @@ pgp_seckey_free(pgp_seckey_t *key) free_BN(&key->key.dsa.x); break; + case PGP_PKA_ECDSA: + free_BN(&key->key.ecdsa.x); + break; + default: (void) fprintf(stderr, "pgp_seckey_free: Unknown algorithm: %d (%s)\n", @@ -2632,6 +2667,12 @@ parse_seckey(pgp_region_t *region, pgp_stream_t *stream) } break; + case PGP_PKA_ECDSA: + if (!limread_mpi(&pkt.u.seckey.key.ecdsa.x, region, stream)) { + ret = 0; + } + break; + case PGP_PKA_ELGAMAL: if (!limread_mpi(&pkt.u.seckey.key.elgamal.x, region, stream)) { ret = 0; diff --git a/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c b/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c index 702b90ccd2fc..90d114230093 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c +++ b/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c @@ -58,7 +58,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: packet-print.c,v 1.43 2021/07/28 22:31:45 jhigh Exp $"); +__RCSID("$NetBSD: packet-print.c,v 1.44 2022/08/26 19:18:38 jhigh Exp $"); #endif #include @@ -325,6 +325,8 @@ numkeybits(const pgp_pubkey_t *pubkey) default: return 0; } + case PGP_PKA_ECDSA: + return ecdsa_numbits(&pubkey->key.ecdsa); case PGP_PKA_ELGAMAL: return BN_num_bytes(pubkey->key.elgamal.y) * 8; default: @@ -659,7 +661,9 @@ pgp_print_pubkey(const pgp_pubkey_t *pubkey) print_bn(0, "g", pubkey->key.dsa.g); print_bn(0, "y", pubkey->key.dsa.y); break; - + case PGP_PKA_ECDSA: + print_bn(0, "p", pubkey->key.ecdsa.p); + break; case PGP_PKA_RSA: case PGP_PKA_RSA_ENCRYPT_ONLY: case PGP_PKA_RSA_SIGN_ONLY: @@ -974,6 +978,11 @@ pgp_print_packet(pgp_printstate_t *print, const pgp_packet_t *pkt) print_bn(print->indent, "s", content->sig.info.sig.dsa.s); break; + case PGP_PKA_ECDSA: + print_bn(print->indent, "r", content->sig.info.sig.ecdsa.r); + print_bn(print->indent, "s", content->sig.info.sig.ecdsa.s); + break; + case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: print_bn(print->indent, "r", content->sig.info.sig.elgamal.r); print_bn(print->indent, "s", content->sig.info.sig.elgamal.s); diff --git a/crypto/external/bsd/netpgp/dist/src/lib/packet-show.c b/crypto/external/bsd/netpgp/dist/src/lib/packet-show.c index d21043a7f9e6..d285420b4dfd 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/packet-show.c +++ b/crypto/external/bsd/netpgp/dist/src/lib/packet-show.c @@ -60,7 +60,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: packet-show.c,v 1.22 2021/07/28 22:31:45 jhigh Exp $"); +__RCSID("$NetBSD: packet-show.c,v 1.23 2022/08/26 19:18:38 jhigh Exp $"); #endif #include @@ -218,7 +218,7 @@ static pgp_map_t pubkey_alg_map[] = {PGP_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"}, {PGP_PKA_DSA, "DSA"}, {PGP_PKA_RESERVED_ELLIPTIC_CURVE, "Reserved for Elliptic Curve"}, - {PGP_PKA_RESERVED_ECDSA, "Reserved for ECDSA"}, + {PGP_PKA_ECDSA, "ECDSA"}, {PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign"}, {PGP_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)"}, {PGP_PKA_PRIVATE00, "Private/Experimental"}, diff --git a/crypto/external/bsd/netpgp/dist/src/lib/packet.h b/crypto/external/bsd/netpgp/dist/src/lib/packet.h index aa65be6891aa..e5c83f21cc4d 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/packet.h +++ b/crypto/external/bsd/netpgp/dist/src/lib/packet.h @@ -348,7 +348,7 @@ typedef enum { PGP_PKA_DSA = 17, /* DSA (Digital Signature Algorithm) */ PGP_PKA_RESERVED_ELLIPTIC_CURVE = 18, /* Reserved for Elliptic * Curve */ - PGP_PKA_RESERVED_ECDSA = 19, /* Reserved for ECDSA */ + PGP_PKA_ECDSA = 19, /* ECDSA */ PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN = 20, /* Deprecated. */ PGP_PKA_RESERVED_DH = 21, /* Reserved for Diffie-Hellman * (X9.42, as defined for @@ -378,6 +378,16 @@ typedef struct { * with x being the secret) */ } pgp_dsa_pubkey_t; +/** Structure to hold one ECDSA public key params. + * + * \see RFC6637 9 + */ +typedef struct { + uint8_t len; + uint8_t oid[8]; + BIGNUM *p; +} pgp_ecdsa_pubkey_t; + /** Structure to hold an RSA public key. * * \see RFC4880 5.5.2 @@ -422,6 +432,7 @@ typedef struct { pgp_pubkey_alg_t alg; /* Public Key Algorithm type */ union { pgp_dsa_pubkey_t dsa; /* A DSA public key */ + pgp_ecdsa_pubkey_t ecdsa; /* An ECDSA public key */ pgp_rsa_pubkey_t rsa; /* An RSA public key */ pgp_elgamal_pubkey_t elgamal; /* An ElGamal public key */ } key; /* Public Key Parameters */ @@ -441,6 +452,11 @@ typedef struct { BIGNUM *x; } pgp_dsa_seckey_t; +/** pgp_ecdsa_seckey_t */ +typedef struct { + BIGNUM *x; +} pgp_ecdsa_seckey_t; + /** pgp_elgamal_seckey_t */ typedef struct { BIGNUM *x; @@ -542,6 +558,7 @@ typedef struct pgp_seckey_t { union { pgp_rsa_seckey_t rsa; pgp_dsa_seckey_t dsa; + pgp_ecdsa_seckey_t ecdsa; pgp_elgamal_seckey_t elgamal; } key; unsigned checksum; @@ -599,6 +616,12 @@ typedef struct pgp_dsa_sig_t { BIGNUM *s; /* DSA value s */ } pgp_dsa_sig_t; +/** Struct to hold params of an ECDSA signature */ +typedef struct pgp_ecdsa_sig_t { + BIGNUM *r; /* ECDSA value r */ + BIGNUM *s; /* ECDSA value s */ +} pgp_ecdsa_sig_t; + /** pgp_elgamal_signature_t */ typedef struct pgp_elgamal_sig_t { BIGNUM *r; @@ -625,6 +648,7 @@ typedef struct pgp_sig_info_t { union { pgp_rsa_sig_t rsa; /* An RSA Signature */ pgp_dsa_sig_t dsa; /* A DSA Signature */ + pgp_ecdsa_sig_t ecdsa; /* An ECDSA Signature */ pgp_elgamal_sig_t elgamal; /* deprecated */ pgp_data_t unknown; /* private or experimental */ } sig; /* signature params */ diff --git a/crypto/external/bsd/netpgp/dist/src/lib/signature.c b/crypto/external/bsd/netpgp/dist/src/lib/signature.c index d23ff80494a9..467e52497fdd 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/signature.c +++ b/crypto/external/bsd/netpgp/dist/src/lib/signature.c @@ -57,7 +57,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: signature.c,v 1.38 2018/02/05 23:56:01 christos Exp $"); +__RCSID("$NetBSD: signature.c,v 1.39 2022/08/26 19:18:38 jhigh Exp $"); #endif #include @@ -265,6 +265,56 @@ dsa_sign(pgp_hash_t *hash, return 1; } +static int +ecdsa_sign(pgp_hash_t *hash, + const pgp_ecdsa_pubkey_t *ecdsa, + const pgp_ecdsa_seckey_t *secdsa, + pgp_output_t *output) +{ + unsigned hashsize; + unsigned t; + uint8_t hashbuf[NETPGP_BUFSIZ]; + ECDSA_SIG *ecdsasig; + const BIGNUM *r, *s; + + hashsize = ecdsa_hashsize(ecdsa); + + if (hashsize == -1) { + return 0; + } + + t = hash->finish(hash, &hashbuf[0]); + + if (t != hashsize) { + (void) fprintf(stderr, "ecdsa_sign: hashfinish %d not %d\n", t, hashsize); + return 0; + } + + pgp_write(output, &hashbuf[0], 2); + + /* write signature to buf */ + ecdsasig = pgp_ecdsa_sign(hashbuf, hashsize, secdsa, ecdsa); + + if (ecdsasig == NULL) { + (void) fprintf(stderr, "ecdsa_sign: invalid ecdsa sig\n"); + return 0; + } + + /* convert and write the sig out to memory */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + ECDSA_SIG_get0(ecdsasig, &r, &s); +#else + r = ecdsasig->r; + s = ecdsasig->s; +#endif + pgp_write_mpi(output, r); + pgp_write_mpi(output, s); + + ECDSA_SIG_free(ecdsasig); + + return 1; +} + static unsigned rsa_verify(pgp_hash_alg_t type, const uint8_t *hash, @@ -430,6 +480,12 @@ pgp_check_sig(const uint8_t *hash, unsigned length, &signer->key.dsa); break; + case PGP_PKA_ECDSA: + ret = pgp_ecdsa_verify(hash, length, + &sig->info.sig.ecdsa, + &signer->key.ecdsa); + break; + case PGP_PKA_RSA: ret = rsa_verify(sig->info.hash_alg, hash, length, &sig->info.sig.rsa, @@ -764,6 +820,14 @@ pgp_write_sig(pgp_output_t *output, } break; + case PGP_PKA_ECDSA: + if (seckey->key.ecdsa.x == NULL) { + (void) fprintf(stderr, "pgp_write_sig: null ecdsa.x\n"); + return 0; + } + + break; + default: (void) fprintf(stderr, "Unsupported algorithm %d\n", seckey->pubkey.alg); @@ -817,6 +881,15 @@ pgp_write_sig(pgp_output_t *output, } break; + case PGP_PKA_ECDSA: + if (!ecdsa_sign(&sig->hash, &key->key.ecdsa, &seckey->key.ecdsa, + sig->output)) { + (void) fprintf(stderr, + "pgp_write_sig: ecdsa_sign failure\n"); + return 0; + } + break; + default: (void) fprintf(stderr, "Unsupported algorithm %d\n", seckey->pubkey.alg); @@ -972,7 +1045,14 @@ pgp_sign_file(pgp_io_t *io, fd_out = 0; /* find the hash algorithm */ - hash_alg = pgp_str_to_hash_alg(hashname); + switch (seckey->pubkey.alg) { + case PGP_PKA_ECDSA: + hash_alg = ecdsa_hashalg(&seckey->pubkey.key.ecdsa); + break; + default: + hash_alg = pgp_str_to_hash_alg(hashname); + } + if (hash_alg == PGP_HASH_UNKNOWN) { (void) fprintf(io->errs, "pgp_sign_file: unknown hash algorithm: \"%s\"\n", diff --git a/crypto/external/bsd/netpgp/dist/src/lib/version.h b/crypto/external/bsd/netpgp/dist/src/lib/version.h index 984a9e95027f..b95553163ee1 100644 --- a/crypto/external/bsd/netpgp/dist/src/lib/version.h +++ b/crypto/external/bsd/netpgp/dist/src/lib/version.h @@ -58,7 +58,7 @@ #endif /* development versions have .99 suffix */ -#define NETPGP_BASE_VERSION "3.99.17" +#define NETPGP_BASE_VERSION "3.99.18" #define NETPGP_VERSION_CAT(a, b) "NetPGP portable " a "/[" b "]" #define NETPGP_VERSION_STRING \