Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP4
rpm
ed25519.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ed25519.diff of Package rpm
--- rpmio/digest.h.orig 2017-10-05 10:04:57.554602041 +0000 +++ rpmio/digest.h 2022-07-12 08:54:37.514921377 +0000 @@ -14,6 +14,7 @@ struct pgpDigAlg_s { setmpifunc setmpi; verifyfunc verify; freefunc free; + int curve; int mpis; void *data; /*!< algorithm specific private data */ }; @@ -42,7 +43,7 @@ struct pgpDigParams_s { pgpDigAlg alg; }; -pgpDigAlg pgpPubkeyNew(int algo); +pgpDigAlg pgpPubkeyNew(int algo, int curve); pgpDigAlg pgpSignatureNew(int algo); --- rpmio/digest_beecrypt.c.orig 2017-08-10 08:08:07.145108694 +0000 +++ rpmio/digest_beecrypt.c 2022-07-12 08:54:37.514921377 +0000 @@ -461,7 +461,7 @@ static int pgpVerifyNULL(pgpDigAlg pgpke return 1; } -pgpDigAlg pgpPubkeyNew(int algo) +pgpDigAlg pgpPubkeyNew(int algo, int curve) { pgpDigAlg ka = xcalloc(1, sizeof(*ka));; --- rpmio/digest_libgcrypt.c.orig 2022-07-12 08:42:10.384358864 +0000 +++ rpmio/digest_libgcrypt.c 2022-07-12 08:56:07.498742115 +0000 @@ -346,6 +346,115 @@ static void pgpFreeKeyDSA(pgpDigAlg pgpk } +/****************************** EDDSA **************************************/ + +struct pgpDigSigEDDSA_s { + gcry_mpi_t r; + gcry_mpi_t s; +}; + +struct pgpDigKeyEDDSA_s { + gcry_mpi_t q; +}; + +static int pgpSetSigMpiEDDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) +{ + struct pgpDigSigEDDSA_s *sig = pgpsig->data; + int mlen = pgpMpiLen(p); + int rc = 1; + + if (!sig) + sig = pgpsig->data = xcalloc(1, sizeof(*sig)); + + switch (num) { + case 0: + if (!gcry_mpi_scan(&sig->r, GCRYMPI_FMT_PGP, p, mlen, NULL)) + rc = 0; + break; + case 1: + if (!gcry_mpi_scan(&sig->s, GCRYMPI_FMT_PGP, p, mlen, NULL)) + rc = 0; + break; + } + return rc; +} + +static int pgpSetKeyMpiEDDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) +{ + struct pgpDigKeyEDDSA_s *key = pgpkey->data; + int mlen = pgpMpiLen(p); + int rc = 1; + + if (!key) + key = pgpkey->data = xcalloc(1, sizeof(*key)); + + switch (num) { + case 0: + if (!gcry_mpi_scan(&key->q, GCRYMPI_FMT_PGP, p, mlen, NULL)) + rc = 0; + break; + } + return rc; +} + +static int +ed25519_zero_extend(gcry_mpi_t x, unsigned char *buf, int bufl) +{ + int n = (gcry_mpi_get_nbits(x) + 7) / 8; + if (n == 0 || n > bufl) + return 1; + n = bufl - n; + if (n) + memset(buf, 0, n); + gcry_mpi_print(GCRYMPI_FMT_USG, buf + n, bufl - n, NULL, x); + return 0; +} + +static int pgpVerifySigEDDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo) +{ + struct pgpDigKeyEDDSA_s *key = pgpkey->data; + struct pgpDigSigEDDSA_s *sig = pgpsig->data; + gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL; + int rc = 1; + unsigned char buf_r[32], buf_s[32]; + + if (!sig || !key) + return rc; + if (pgpkey->curve != PGPCURVE_ED25519) + return rc; + if (ed25519_zero_extend(sig->r, buf_r, 32) || ed25519_zero_extend(sig->s, buf_s, 32)) + return rc; + gcry_sexp_build(&sexp_sig, NULL, "(sig-val (eddsa (r %b) (s %b)))", 32, (const char *)buf_r, 32, (const char *)buf_s, 32); + gcry_sexp_build(&sexp_data, NULL, "(data (flags eddsa) (hash-algo sha512) (value %b))", (int)hashlen, (const char *)hash); + gcry_sexp_build(&sexp_pkey, NULL, "(public-key (ecc (curve \"Ed25519\") (flags eddsa) (q %M)))", key->q); + if (sexp_sig && sexp_data && sexp_pkey) + rc = gcry_pk_verify(sexp_sig, sexp_data, sexp_pkey) == 0 ? 0 : 1; + gcry_sexp_release(sexp_sig); + gcry_sexp_release(sexp_data); + gcry_sexp_release(sexp_pkey); + return rc; +} + +static void pgpFreeSigEDDSA(pgpDigAlg pgpsig) +{ + struct pgpDigSigEDDSA_s *sig = pgpsig->data; + if (sig) { + gcry_mpi_release(sig->r); + gcry_mpi_release(sig->s); + pgpsig->data = _free(sig); + } +} + +static void pgpFreeKeyEDDSA(pgpDigAlg pgpkey) +{ + struct pgpDigKeyEDDSA_s *key = pgpkey->data; + if (key) { + gcry_mpi_release(key->q); + pgpkey->data = _free(key); + } +} + + /****************************** NULL **************************************/ static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p) @@ -359,7 +468,24 @@ static int pgpVerifyNULL(pgpDigAlg pgpke return 1; } -pgpDigAlg pgpPubkeyNew(int algo) +static int pgpSupportedCurve(int curve) +{ + if (curve == PGPCURVE_ED25519) { + static int supported_ed25519; + if (!supported_ed25519) { + gcry_sexp_t sexp = NULL; + unsigned int nbits; + gcry_sexp_build(&sexp, NULL, "(public-key (ecc (curve \"Ed25519\")))"); + nbits = gcry_pk_get_nbits(sexp); + gcry_sexp_release(sexp); + supported_ed25519 = nbits > 0 ? 1 : -1; + } + return supported_ed25519 > 0; + } + return 0; +} + +pgpDigAlg pgpPubkeyNew(int algo, int curve) { pgpDigAlg ka = xcalloc(1, sizeof(*ka));; @@ -374,6 +500,17 @@ pgpDigAlg pgpPubkeyNew(int algo) ka->free = pgpFreeKeyDSA; ka->mpis = 4; break; + case PGPPUBKEYALGO_EDDSA: + if (!pgpSupportedCurve(curve)) { + ka->setmpi = pgpSetMpiNULL; + ka->mpis = -1; + break; + } + ka->setmpi = pgpSetKeyMpiEDDSA; + ka->free = pgpFreeKeyEDDSA; + ka->mpis = 1; + ka->curve = curve; + break; default: ka->setmpi = pgpSetMpiNULL; ka->mpis = -1; @@ -402,6 +539,12 @@ pgpDigAlg pgpSignatureNew(int algo) sa->verify = pgpVerifySigDSA; sa->mpis = 2; break; + case PGPPUBKEYALGO_EDDSA: + sa->setmpi = pgpSetSigMpiEDDSA; + sa->free = pgpFreeSigEDDSA; + sa->verify = pgpVerifySigEDDSA; + sa->mpis = 2; + break; default: sa->setmpi = pgpSetMpiNULL; sa->verify = pgpVerifyNULL; --- rpmio/digest_nss.c.orig 2017-10-05 10:04:57.554602041 +0000 +++ rpmio/digest_nss.c 2022-07-12 08:54:37.514921377 +0000 @@ -479,7 +479,7 @@ static int pgpVerifyNULL(pgpDigAlg pgpke return 1; } -pgpDigAlg pgpPubkeyNew(int algo) +pgpDigAlg pgpPubkeyNew(int algo, int curve) { pgpDigAlg ka = xcalloc(1, sizeof(*ka));; --- rpmio/digest_openssl.c.orig 2017-10-05 10:04:57.554602041 +0000 +++ rpmio/digest_openssl.c 2022-07-12 08:54:37.514921377 +0000 @@ -786,7 +786,7 @@ static int pgpVerifyNULL(pgpDigAlg pgpke } /****************************** PGP **************************************/ -pgpDigAlg pgpPubkeyNew(int algo) +pgpDigAlg pgpPubkeyNew(int algo, int curve) { pgpDigAlg ka = xcalloc(1, sizeof(*ka));; --- rpmio/rpmpgp.c.orig 2017-10-05 10:04:57.569602038 +0000 +++ rpmio/rpmpgp.c 2022-07-12 08:54:37.514921377 +0000 @@ -58,6 +58,7 @@ static struct pgpValTbl_s const pgpPubke { PGPPUBKEYALGO_ECDSA, "ECDSA" }, { PGPPUBKEYALGO_ELGAMAL, "Elgamal" }, { PGPPUBKEYALGO_DH, "Diffie-Hellman (X9.42)" }, + { PGPPUBKEYALGO_EDDSA, "EdDSA" }, { -1, "Unknown public key algorithm" }, }; @@ -683,15 +684,42 @@ char * pgpHexStr(const uint8_t *p, size_ return str; } +static uint8_t curve_oids[] = { + PGPCURVE_NIST_P_256, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, + PGPCURVE_NIST_P_384, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, + PGPCURVE_NIST_P_521, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, + PGPCURVE_BRAINPOOL_P256R1, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07, + PGPCURVE_BRAINPOOL_P512R1, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d, + PGPCURVE_ED25519, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01, + PGPCURVE_CURVE25519, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01, + 0, +}; + +static int pgpCurveByOid(const uint8_t *p, int l) +{ + uint8_t *curve; + for (curve = curve_oids; *curve; curve += 2 + curve[1]) + if (l == (int)curve[1] && !memcmp(p, curve + 2, l)) + return (int)curve[0]; + return 0; +} + static int pgpPrtPubkeyParams(uint8_t pubkey_algo, const uint8_t *p, const uint8_t *h, size_t hlen, pgpDigParams keyp) { int rc = 1; const uint8_t *pend = h + hlen; - int i; - pgpDigAlg keyalg = pgpPubkeyNew(pubkey_algo); - + int i, curve = 0; + pgpDigAlg keyalg; + if (pubkey_algo == PGPPUBKEYALGO_EDDSA) { + int len = p + 1 < pend ? p[0] : 0; + if (len == 0 || len == 0xff || p + 1 + len > pend) + goto exit; + curve = pgpCurveByOid(p + 1, len); + p += len + 1; + } + keyalg = pgpPubkeyNew(pubkey_algo, curve); for (i = 0; i < keyalg->mpis && p + 2 <= pend; i++) { int mpil = pgpMpiLen(p); if (p + mpil > pend) @@ -713,6 +741,7 @@ static int pgpPrtPubkeyParams(uint8_t pu else pgpDigAlgFree(keyalg); +exit: return rc; } @@ -793,10 +822,20 @@ int pgpPubkeyFingerprint(const uint8_t * case PGPPUBKEYALGO_DSA: mpis = 4; break; + case PGPPUBKEYALGO_EDDSA: + mpis = 1; + break; } } se = (uint8_t *)(v + 1); + /* EdDSA has a curve id before the MPIs */ + if (v->pubkey_algo == PGPPUBKEYALGO_EDDSA) { + if (se < pend && se[0] != 0x00 && se[0] != 0xff) + se += 1 + se[0]; + else + se = pend; /* error out when reading the MPI */ + } while (se < pend && mpis-- > 0) se += pgpMpiLen(se); --- rpmio/rpmpgp.h.orig 2017-10-05 10:04:57.569602038 +0000 +++ rpmio/rpmpgp.h 2022-07-12 08:54:37.514921377 +0000 @@ -8,6 +8,10 @@ * * Text from RFC-2440 in comments is * Copyright (C) The Internet Society (1998). All Rights Reserved. + * + * EdDSA algorithm identifier value taken from + * https://datatracker.ietf.org/doc/draft-ietf-openpgp-rfc4880bis/ + * This value is used in gnupg since version 2.1.0 */ #include <string.h> @@ -152,6 +156,7 @@ typedef enum pgpSigType_e { 20 - Elgamal (Encrypt or Sign) 21 - Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME) + 22 - EdDSA 100 to 110 - Private/Experimental algorithm. \endverbatim * @@ -168,7 +173,8 @@ typedef enum pgpPubkeyAlgo_e { PGPPUBKEYALGO_EC = 18, /*!< Elliptic Curve */ PGPPUBKEYALGO_ECDSA = 19, /*!< ECDSA */ PGPPUBKEYALGO_ELGAMAL = 20, /*!< Elgamal */ - PGPPUBKEYALGO_DH = 21 /*!< Diffie-Hellman (X9.42) */ + PGPPUBKEYALGO_DH = 21, /*!< Diffie-Hellman (X9.42) */ + PGPPUBKEYALGO_EDDSA = 22 /*!< EdDSA */ } pgpPubkeyAlgo; /** \ingroup rpmpgp @@ -269,6 +275,22 @@ typedef enum pgpHashAlgo_e { } pgpHashAlgo; /** \ingroup rpmpgp + * ECC Curves + * + * The following curve ids are private to rpm. PGP uses + * oids to identify a curve. + */ +typedef enum pgpCurveId_e { + PGPCURVE_NIST_P_256 = 1, /*!< NIST P-256 */ + PGPCURVE_NIST_P_384 = 2, /*!< NIST P-384 */ + PGPCURVE_NIST_P_521 = 3, /*!< NIST P-521 */ + PGPCURVE_BRAINPOOL_P256R1 = 4, /*!< brainpoolP256r1 */ + PGPCURVE_BRAINPOOL_P512R1 = 5, /*!< brainpoolP512r1 */ + PGPCURVE_ED25519 = 6, /*!< Ed25519 */ + PGPCURVE_CURVE25519 = 7, /*!< Curve25519 */ +} pgpCurveId; + +/** \ingroup rpmpgp * 5.2.2. Version 3 Signature Packet Format * * The body of a version 3 Signature Packet contains: @@ -285,7 +307,7 @@ typedef enum pgpHashAlgo_e { * Algorithm Specific Fields for RSA signatures: * - multiprecision integer (MPI) of RSA signature value m**d. * - * Algorithm Specific Fields for DSA signatures: + * Algorithm Specific Fields for DSA and EdDSA signatures: * - MPI of DSA value r. * - MPI of DSA value s. */ @@ -642,6 +664,11 @@ typedef struct pgpPktKeyV3_s { * - MPI of Elgamal public key value y (= g**x where x is * secret). * + * Algorithm Specific Fields for EdDSA public keys: + * - variable length field containing a curve OID + * - MPI of an EC point representing a public key Q + * (a compressed point prefixed with the octet 0x40) + * */ typedef struct pgpPktKeyV4_s { uint8_t version; /*!< version number (4). */ --- sign/rpmgensig.c.orig 2017-10-05 10:04:57.588602034 +0000 +++ sign/rpmgensig.c 2022-07-12 08:56:37.398682115 +0000 @@ -212,6 +212,7 @@ static rpmtd makeSigTag(Header sigh, int pubkey_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO); switch (pubkey_algo) { case PGPPUBKEYALGO_DSA: + case PGPPUBKEYALGO_EDDSA: sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG; break; case PGPPUBKEYALGO_RSA:
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor