mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Initial support for generating Kyber subkeys.
* common/openpgpdefs.h (PUBKEY_ALGO_KY768_25519): Remove. (PUBKEY_ALGO_KY1024_448): Remove. (PUBKEY_ALGO_KYBER): New. Use them everywhere instead of the removed. * g10/build-packet.c (gpg_mpi_write_nohdr): Rename to (gpg_mpi_write_opaque_nohdr): this. Change callers. (gpg_mpi_write_opaque_32): New. (do_key): Support Kyber keys using the revised format. * g10/gpg.h (MAX_EXTERN_KEYPARM_BITS): New. * g10/parse-packet.c (read_octet_string): Add arg nbytes so support reading with a length prefix. Adjust callers. (parse_key): Parse Kyber public keys. * g10/misc.c (pubkey_get_npkey): Support Kyber. (pubkey_get_nskey): Ditto. * g10/keyid.c (pubkey_string): Support dual algorithms. (do_hash_public_key): Support Kyber. (nbits_from_pk): Ditto. (keygrip_from_pk): Return the Kyber part for the ECC+Kyber dual algo. * g10/keygen.c (struct common_gen_cb_parm_s): Add genkey_result2. Note that this callback is not yet used. (ecckey_from_sexp): Add optional arg sexp2 and use it for Kyber. Change callers. (ecckey_from_sexp): Do not leak LIST in case of an error. (common_gen): Add arg keyparms2, change callers, and support Kyber. (gen_kyber): New. (get_keysize_range): Support Kyber. (fixup_keysize): Simplify and support Kyber. (do_create): Handle Kyber. (parse_key_parameter_part): Remove algo strings "ky768" and "ky1024" and add a generic "kyber" with default parameters. -- This uses a revised format which is more aligned with the usual OpenPGP structure. A lot of things are still missing. For example support for handling two keygrips and checking both of them in a -K listing. There is also only ky768_bp384 as fixed algorithm for now. No passphrase for the Kyber part of the dual algorithm is on purpose. A test was done using gpg --quick-gen-key pqc1 nistp256 and then running gpg -v --quick-add-key <fingerprint> kyber which creates a v5 subkey on a v4 primary key. A second test using gpg --quick-gen-key pqc2 Ed448 followed by a --quick-add-key created a v5 key with a v5 subkey. GnuPG-bug-id: 6815
This commit is contained in:
parent
6c1dd3afd1
commit
97f5159495
@ -172,8 +172,7 @@ typedef enum
|
||||
PUBKEY_ALGO_ELGAMAL = 20, /* Elgamal encrypt+sign (legacy). */
|
||||
/* 21 reserved by OpenPGP. */
|
||||
PUBKEY_ALGO_EDDSA = 22, /* EdDSA. */
|
||||
PUBKEY_ALGO_KY768_25519 = 29, /* Kyber768 + X25519 (aka ML-KEM-768) */
|
||||
PUBKEY_ALGO_KY1024_448 = 30, /* Kyber1024 + X448 (aka ML-KEM-1024) */
|
||||
PUBKEY_ALGO_KYBER = 29, /* Kyber */
|
||||
PUBKEY_ALGO_DIL3_25519 = 35, /* Dilithium3 + Ed25519 (aka ML-DSA-65) */
|
||||
PUBKEY_ALGO_DIL5_448 = 36, /* Dilithium5 + Ed448 (aka ML-DSA-87) */
|
||||
PUBKEY_ALGO_SPHINX_SHA2 = 41, /* SPHINX+-simple-SHA2 (aka SLH-DSA-SHA2) */
|
||||
|
@ -433,7 +433,7 @@ sos_write (iobuf_t out, gcry_mpi_t a, unsigned int *r_nwritten)
|
||||
* Write an opaque string to the output stream without length info.
|
||||
*/
|
||||
gpg_error_t
|
||||
gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a)
|
||||
gpg_mpi_write_opaque_nohdr (iobuf_t out, gcry_mpi_t a)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@ -452,6 +452,45 @@ gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write an opaque MPI string with a four-byte octet count to the
|
||||
* output stream. If R_NWRITTEN is not NULL the number of written
|
||||
* bytes is stored there. OUT may be NULL in which case only
|
||||
* R_NWRITTEN is updated and error checking is done.
|
||||
*/
|
||||
gpg_error_t
|
||||
gpg_mpi_write_opaque_32 (iobuf_t out, gcry_mpi_t a, unsigned int *r_nwritten)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
|
||||
{
|
||||
unsigned int nbits, nbytes;
|
||||
const void *p;
|
||||
|
||||
p = gcry_mpi_get_opaque (a, &nbits);
|
||||
nbytes = (nbits + 7)/8;
|
||||
if (out)
|
||||
{
|
||||
write_32 (out, nbytes);
|
||||
err = p ? iobuf_write (out, p, nbytes) : 0;
|
||||
}
|
||||
else
|
||||
err = 0;
|
||||
if (r_nwritten)
|
||||
*r_nwritten = 4 + (p? nbytes : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = gpg_error (GPG_ERR_BAD_MPI);
|
||||
if (r_nwritten)
|
||||
*r_nwritten = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Calculate the length of a packet described by PKT. */
|
||||
u32
|
||||
calc_packet_length( PACKET *pkt )
|
||||
@ -639,8 +678,14 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
|
||||
{
|
||||
if ( (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0))
|
||||
|| (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0))
|
||||
|| (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)))
|
||||
err = gpg_mpi_write_nohdr (a, pk->pkey[i]);
|
||||
|| (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2))
|
||||
|| (pk->pubkey_algo == PUBKEY_ALGO_KYBER && (i == 0)))
|
||||
err = gpg_mpi_write_opaque_nohdr (a, pk->pkey[i]);
|
||||
else if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2)
|
||||
{
|
||||
/* Write a four-octet count prefixed Kyber public key. */
|
||||
err = gpg_mpi_write_opaque_32 (a, pk->pkey[2], NULL);
|
||||
}
|
||||
else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||
@ -779,9 +824,15 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
|
||||
|
||||
for (j=i; j < nskey; j++ )
|
||||
{
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && j == 4)
|
||||
{
|
||||
if ((err=gpg_mpi_write_opaque_32 (NULL,pk->pkey[j], &n)))
|
||||
goto leave;
|
||||
}
|
||||
else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_KYBER)
|
||||
{
|
||||
if ((err = sos_write (NULL, pk->pkey[j], &n)))
|
||||
goto leave;
|
||||
@ -798,7 +849,14 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
|
||||
}
|
||||
|
||||
for ( ; i < nskey; i++ )
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
{
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 4)
|
||||
{
|
||||
err = gpg_mpi_write_opaque_32 (a, pk->pkey[i], NULL);
|
||||
if (err)
|
||||
goto leave;
|
||||
}
|
||||
else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||
{
|
||||
@ -806,8 +864,11 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((err = gpg_mpi_write (a, pk->pkey[i], NULL)))
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
write_16 (a, ski->csum );
|
||||
}
|
||||
@ -922,7 +983,7 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
|
||||
for (i=0; i < n && !rc ; i++ )
|
||||
{
|
||||
if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
|
||||
rc = gpg_mpi_write_nohdr (a, enc->data[i]);
|
||||
rc = gpg_mpi_write_opaque_nohdr (a, enc->data[i]);
|
||||
else if (enc->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||
rc = sos_write (a, enc->data[i], NULL);
|
||||
else
|
||||
|
@ -156,11 +156,11 @@ build_kdf_params (unsigned char kdf_params[256], size_t *r_size,
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
/* variable-length field 1, curve name OID */
|
||||
err = gpg_mpi_write_nohdr (obuf, pkey[0]);
|
||||
err = gpg_mpi_write_opaque_nohdr (obuf, pkey[0]);
|
||||
/* fixed-length field 2 */
|
||||
iobuf_put (obuf, PUBKEY_ALGO_ECDH);
|
||||
/* variable-length field 3, KDF params */
|
||||
err = (err ? err : gpg_mpi_write_nohdr (obuf, pkey[2]));
|
||||
err = (err ? err : gpg_mpi_write_opaque_nohdr (obuf, pkey[2]));
|
||||
/* fixed-length field 4 */
|
||||
iobuf_write (obuf, "Anonymous Sender ", 20);
|
||||
/* fixed-length field 5, recipient fp (or first 20 octets of fp) */
|
||||
|
@ -41,6 +41,10 @@
|
||||
/* Number of bits we accept when reading or writing MPIs. */
|
||||
#define MAX_EXTERN_MPI_BITS 16384
|
||||
|
||||
/* Number of bytes we accept when reading four-octet count prefixed
|
||||
* key parameters. Needs to fit as a positive number into an int. */
|
||||
#define MAX_EXTERN_KEYPARM_BITS (32768*8)
|
||||
|
||||
/* The maximum length of a binary fingerprints. This is used to
|
||||
* provide a static buffer and will be increased if we need to support
|
||||
* longer fingerprints. Warning: At some places we have some
|
||||
|
223
g10/keygen.c
223
g10/keygen.c
@ -139,6 +139,9 @@ struct common_gen_cb_parm_s
|
||||
* may take a copy of this so that the result can be used after we
|
||||
* are back from the deep key generation call stack. */
|
||||
gcry_sexp_t genkey_result;
|
||||
/* For a dual algorithms the result of the second algorithm
|
||||
* (e.g. Kyber). */
|
||||
gcry_sexp_t genkey_result2;
|
||||
};
|
||||
typedef struct common_gen_cb_parm_s *common_gen_cb_parm_t;
|
||||
|
||||
@ -1311,8 +1314,12 @@ curve_is_448 (gcry_sexp_t sexp)
|
||||
}
|
||||
|
||||
|
||||
/* Extract the parameters in OpenPGP format from SEXP and put them
|
||||
* into the caller provided ARRAY. SEXP2 is used to provide the
|
||||
* parameters for dual algorithm (e.g. Kyber). */
|
||||
static gpg_error_t
|
||||
ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
|
||||
ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
|
||||
gcry_sexp_t sexp2, int algo)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gcry_sexp_t list, l2;
|
||||
@ -1364,8 +1371,46 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
|
||||
goto leave;
|
||||
|
||||
gcry_sexp_release (list);
|
||||
list = NULL;
|
||||
|
||||
if (algo == PUBKEY_ALGO_ECDH)
|
||||
if (algo == PUBKEY_ALGO_KYBER)
|
||||
{
|
||||
if (!sexp2)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_MISSING_VALUE);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
list = gcry_sexp_find_token (sexp2, "public-key", 0);
|
||||
if (!list)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||
goto leave;
|
||||
}
|
||||
l2 = gcry_sexp_cadr (list);
|
||||
gcry_sexp_release (list);
|
||||
list = l2;
|
||||
if (!list)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_NO_OBJ);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
l2 = gcry_sexp_find_token (list, "p", 1);
|
||||
if (!l2)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_NO_OBJ); /* required parameter not found */
|
||||
goto leave;
|
||||
}
|
||||
array[2] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_OPAQUE);
|
||||
gcry_sexp_release (l2);
|
||||
if (!array[2])
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_OBJ); /* required parameter invalid */
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
else if (algo == PUBKEY_ALGO_ECDH)
|
||||
{
|
||||
array[2] = pk_ecdh_default_params (nbits);
|
||||
if (!array[2])
|
||||
@ -1377,6 +1422,7 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
|
||||
|
||||
leave:
|
||||
xfree (curve);
|
||||
gcry_sexp_release (list);
|
||||
if (err)
|
||||
{
|
||||
for (i=0; i < 3; i++)
|
||||
@ -1515,7 +1561,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
||||
if (algo == PUBKEY_ALGO_ECDSA
|
||||
|| algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_ECDH )
|
||||
err = ecckey_from_sexp (pk->pkey, s_key, algo);
|
||||
err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
|
||||
else
|
||||
err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
|
||||
if (err)
|
||||
@ -1543,12 +1589,13 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
||||
}
|
||||
|
||||
|
||||
/* Common code for the key generation function gen_xxx. The optinal
|
||||
/* Common code for the key generation function gen_xxx. The optional
|
||||
* (COMMON_GEN_CB,COMMON_GEN_CB_PARM) can be used as communication
|
||||
* object.
|
||||
* object. A KEYPARMS2 forces the use of a dual key (e.g. Kyber+ECC).
|
||||
*/
|
||||
static int
|
||||
common_gen (const char *keyparms, int algo, const char *algoelem,
|
||||
common_gen (const char *keyparms, const char *keyparms2,
|
||||
int algo, const char *algoelem,
|
||||
kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey,
|
||||
int keygen_flags, const char *passphrase,
|
||||
char **cache_nonce_addr, char **passwd_nonce_addr,
|
||||
@ -1559,6 +1606,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
|
||||
PACKET *pkt;
|
||||
PKT_public_key *pk;
|
||||
gcry_sexp_t s_key;
|
||||
gcry_sexp_t s_key2 = NULL;
|
||||
|
||||
err = agent_genkey (NULL, cache_nonce_addr, passwd_nonce_addr, keyparms,
|
||||
!!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION),
|
||||
@ -1570,14 +1618,32 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keyparms2)
|
||||
{
|
||||
err = agent_genkey (NULL, NULL, NULL, keyparms2,
|
||||
1 /* No protection */,
|
||||
NULL, timestamp,
|
||||
&s_key2);
|
||||
if (err)
|
||||
{
|
||||
log_error ("agent_genkey failed for second algo: %s\n",
|
||||
gpg_strerror (err) );
|
||||
gcry_sexp_release (s_key);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (common_gen_cb && common_gen_cb_parm)
|
||||
{
|
||||
common_gen_cb_parm->genkey_result = s_key;
|
||||
common_gen_cb_parm->genkey_result2 = s_key2;
|
||||
err = common_gen_cb (common_gen_cb_parm);
|
||||
common_gen_cb_parm->genkey_result = NULL;
|
||||
common_gen_cb_parm->genkey_result2 = NULL;
|
||||
if (err)
|
||||
{
|
||||
gcry_sexp_release (s_key);
|
||||
gcry_sexp_release (s_key2);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@ -1596,10 +1662,12 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
|
||||
pk->expiredate = pk->timestamp + expireval;
|
||||
pk->pubkey_algo = algo;
|
||||
|
||||
if (algo == PUBKEY_ALGO_ECDSA
|
||||
if (algo == PUBKEY_ALGO_KYBER)
|
||||
err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo);
|
||||
else if (algo == PUBKEY_ALGO_ECDSA
|
||||
|| algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_ECDH )
|
||||
err = ecckey_from_sexp (pk->pkey, s_key, algo);
|
||||
err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
|
||||
else
|
||||
err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
|
||||
if (err)
|
||||
@ -1610,6 +1678,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
|
||||
return err;
|
||||
}
|
||||
gcry_sexp_release (s_key);
|
||||
gcry_sexp_release (s_key2);
|
||||
|
||||
pkt = xtrycalloc (1, sizeof *pkt);
|
||||
if (!pkt)
|
||||
@ -1675,7 +1744,7 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
err = common_gen (keyparms, algo, "pgy",
|
||||
err = common_gen (keyparms, NULL, algo, "pgy",
|
||||
pub_root, timestamp, expireval, is_subkey,
|
||||
keygen_flags, passphrase,
|
||||
cache_nonce_addr, passwd_nonce_addr,
|
||||
@ -1767,7 +1836,7 @@ gen_dsa (unsigned int nbits, KBNODE pub_root,
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy",
|
||||
err = common_gen (keyparms, NULL, PUBKEY_ALGO_DSA, "pqgy",
|
||||
pub_root, timestamp, expireval, is_subkey,
|
||||
keygen_flags, passphrase,
|
||||
cache_nonce_addr, passwd_nonce_addr,
|
||||
@ -1868,7 +1937,7 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
err = common_gen (keyparms, algo, "",
|
||||
err = common_gen (keyparms, NULL, algo, "",
|
||||
pub_root, timestamp, expireval, is_subkey,
|
||||
*keygen_flags, passphrase,
|
||||
cache_nonce_addr, passwd_nonce_addr,
|
||||
@ -1880,6 +1949,79 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
|
||||
}
|
||||
|
||||
|
||||
/* Generate a dual ECC+Kyber key. Note that KEYGEN_FLAGS will be
|
||||
* updated by this function to indicate the forced creation of a v5
|
||||
* key. */
|
||||
static gpg_error_t
|
||||
gen_kyber (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root,
|
||||
u32 timestamp, u32 expireval, int is_subkey,
|
||||
int *keygen_flags, const char *passphrase,
|
||||
char **cache_nonce_addr, char **passwd_nonce_addr,
|
||||
gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t),
|
||||
common_gen_cb_parm_t common_gen_cb_parm)
|
||||
{
|
||||
gpg_error_t err;
|
||||
char *keyparms1;
|
||||
const char *keyparms2;
|
||||
|
||||
log_assert (algo == PUBKEY_ALGO_KYBER);
|
||||
|
||||
if (nbits == 768)
|
||||
keyparms2 = "(genkey(kyber768))";
|
||||
else if (nbits == 1024)
|
||||
keyparms2 = "(genkey(kyber1024))";
|
||||
else
|
||||
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
||||
|
||||
if (!curve || !*curve)
|
||||
return gpg_error (GPG_ERR_UNKNOWN_CURVE);
|
||||
|
||||
*keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
||||
|
||||
if (!strcmp (curve, "Curve25519"))
|
||||
{
|
||||
keyparms1 = xtryasprintf
|
||||
("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))",
|
||||
strlen (curve), curve,
|
||||
(((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
|
||||
&& (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
|
||||
" transient-key" : ""));
|
||||
}
|
||||
else if (!strcmp (curve, "X448"))
|
||||
{
|
||||
keyparms1 = xtryasprintf
|
||||
("(genkey(ecc(curve %zu:%s)(flags comp%s)))",
|
||||
strlen (curve), curve,
|
||||
(((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
|
||||
&& (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
|
||||
" transient-key" : ""));
|
||||
}
|
||||
else /* Should we use the compressed format? Check smartcard support. */
|
||||
{
|
||||
keyparms1 = xtryasprintf
|
||||
("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))",
|
||||
strlen (curve), curve,
|
||||
(((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
|
||||
&& (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
|
||||
" transient-key" : ""));
|
||||
}
|
||||
|
||||
if (!keyparms1)
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
err = common_gen (keyparms1, keyparms2, algo, "",
|
||||
pub_root, timestamp, expireval, is_subkey,
|
||||
*keygen_flags, passphrase,
|
||||
cache_nonce_addr, passwd_nonce_addr,
|
||||
common_gen_cb, common_gen_cb_parm);
|
||||
xfree (keyparms1);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generate an RSA key.
|
||||
*/
|
||||
@ -1928,7 +2070,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
err = common_gen (keyparms, algo, "ne",
|
||||
err = common_gen (keyparms, NULL, algo, "ne",
|
||||
pub_root, timestamp, expireval, is_subkey,
|
||||
keygen_flags, passphrase,
|
||||
cache_nonce_addr, passwd_nonce_addr,
|
||||
@ -2547,6 +2689,12 @@ get_keysize_range (int algo, unsigned int *min, unsigned int *max)
|
||||
def=255;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_KYBER:
|
||||
*min = 768;
|
||||
*max = 1024;
|
||||
def = 768;
|
||||
break;
|
||||
|
||||
default:
|
||||
*min = opt.compliance == CO_DE_VS ? 2048: 1024;
|
||||
*max = 4096;
|
||||
@ -2562,27 +2710,20 @@ get_keysize_range (int algo, unsigned int *min, unsigned int *max)
|
||||
static unsigned int
|
||||
fixup_keysize (unsigned int nbits, int algo, int silent)
|
||||
{
|
||||
unsigned int orig_nbits = nbits;
|
||||
|
||||
if (algo == PUBKEY_ALGO_DSA && (nbits % 64))
|
||||
{
|
||||
nbits = ((nbits + 63) / 64) * 64;
|
||||
if (!silent)
|
||||
tty_printf (_("rounded up to %u bits\n"), nbits);
|
||||
}
|
||||
else if (algo == PUBKEY_ALGO_EDDSA)
|
||||
{
|
||||
if (nbits != 255 && nbits != 441)
|
||||
{
|
||||
if (nbits < 256)
|
||||
nbits = 255;
|
||||
else
|
||||
nbits = 441;
|
||||
if (!silent)
|
||||
tty_printf (_("rounded to %u bits\n"), nbits);
|
||||
}
|
||||
}
|
||||
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
|
||||
{
|
||||
if (nbits != 256 && nbits != 384 && nbits != 521)
|
||||
{
|
||||
if (nbits < 256)
|
||||
nbits = 256;
|
||||
@ -2590,17 +2731,23 @@ fixup_keysize (unsigned int nbits, int algo, int silent)
|
||||
nbits = 384;
|
||||
else
|
||||
nbits = 521;
|
||||
if (!silent)
|
||||
tty_printf (_("rounded to %u bits\n"), nbits);
|
||||
}
|
||||
else if (algo == PUBKEY_ALGO_KYBER)
|
||||
{
|
||||
/* (in reality the numbers are not bits) */
|
||||
if (nbits < 768)
|
||||
nbits = 768;
|
||||
else if (nbits > 1024)
|
||||
nbits = 1024;
|
||||
}
|
||||
else if ((nbits % 32))
|
||||
{
|
||||
nbits = ((nbits + 31) / 32) * 32;
|
||||
if (!silent)
|
||||
tty_printf (_("rounded up to %u bits\n"), nbits );
|
||||
}
|
||||
|
||||
if (!silent && orig_nbits != nbits)
|
||||
tty_printf (_("rounded to %u bits\n"), nbits);
|
||||
|
||||
return nbits;
|
||||
}
|
||||
|
||||
@ -3330,6 +3477,12 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root,
|
||||
keygen_flags, passphrase,
|
||||
cache_nonce_addr, passwd_nonce_addr,
|
||||
common_gen_cb, common_gen_cb_parm);
|
||||
else if (algo == PUBKEY_ALGO_KYBER)
|
||||
err = gen_kyber (algo, nbits, curve,
|
||||
pub_root, timestamp, expiredate, is_subkey,
|
||||
keygen_flags, passphrase,
|
||||
cache_nonce_addr, passwd_nonce_addr,
|
||||
common_gen_cb, common_gen_cb_parm);
|
||||
else if (algo == PUBKEY_ALGO_RSA)
|
||||
err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey,
|
||||
*keygen_flags, passphrase,
|
||||
@ -3434,6 +3587,7 @@ parse_key_parameter_part (ctrl_t ctrl,
|
||||
; /* We need the flags before we can figure out the key to use. */
|
||||
else if (algo)
|
||||
{
|
||||
/* This is one of the algos parsed above (rsa, dsa, or elg). */
|
||||
if (!string[3])
|
||||
size = get_keysize_range (algo, NULL, NULL);
|
||||
else
|
||||
@ -3443,14 +3597,15 @@ parse_key_parameter_part (ctrl_t ctrl,
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
}
|
||||
}
|
||||
else if (!ascii_strcasecmp (string, "ky768"))
|
||||
else if (!ascii_strcasecmp (string, "kyber"))
|
||||
{
|
||||
algo = PUBKEY_ALGO_KY768_25519;
|
||||
is_pqc = 1;
|
||||
}
|
||||
else if (!ascii_strcasecmp (string, "ky1024"))
|
||||
{
|
||||
algo = PUBKEY_ALGO_KY1024_448;
|
||||
/* Get the curve and check that it can technically be used
|
||||
* (i.e. everything except the EdXXXX curves. */
|
||||
curve = openpgp_is_curve_supported ("brainpoolP384r1", &algo, NULL);
|
||||
if (!curve || algo == PUBKEY_ALGO_EDDSA)
|
||||
return gpg_error (GPG_ERR_UNKNOWN_CURVE);
|
||||
algo = PUBKEY_ALGO_KYBER;
|
||||
size = 768;
|
||||
is_pqc = 1;
|
||||
}
|
||||
else if (!ascii_strcasecmp (string, "dil3"))
|
||||
@ -3782,6 +3937,8 @@ parse_key_parameter_part (ctrl_t ctrl,
|
||||
* cv25519 := ECDH using curve Curve25519.
|
||||
* cv448 := ECDH using curve X448.
|
||||
* nistp256:= ECDSA or ECDH using curve NIST P-256
|
||||
* kyber := Kyber with the default parameters
|
||||
* ky768_bp384 := Kyber-768 with BrainpoolP256r1 as second algo
|
||||
*
|
||||
* All strings with an unknown prefix are considered an elliptic
|
||||
* curve. Curves which have no implicit algorithm require that FLAGS
|
||||
@ -6495,7 +6652,7 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root,
|
||||
else if (algo == PUBKEY_ALGO_ECDSA
|
||||
|| algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_ECDH )
|
||||
err = ecckey_from_sexp (pk->pkey, s_key, algo);
|
||||
err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
|
||||
else
|
||||
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||
gcry_sexp_release (s_key);
|
||||
|
83
g10/keyid.c
83
g10/keyid.c
@ -76,10 +76,16 @@ pubkey_letter( int algo )
|
||||
|
||||
"rsa3072" - RSA with 3072 bit
|
||||
"elg1024" - Elgamal with 1024 bit
|
||||
"ed25519" - ECC using the curve Ed25519.
|
||||
"ed25519" - EdDSA using the curve Ed25519.
|
||||
"cv25519" - ECDH using the curve X25519.
|
||||
"ky768_cv448 - Kyber-768 with X448 as second algo.
|
||||
"ky1025_bp512 - Kyber-1024 with BrainpoolP256r1 as second algo.
|
||||
"E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4".
|
||||
"E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID.
|
||||
"unknown_N" - Unknown OpenPGP algorithm N.
|
||||
"E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID.
|
||||
|
||||
Note that with Kyber we use "bp" as abbreviation for BrainpoolP and
|
||||
ignore the final r1 part.
|
||||
|
||||
If the option --legacy-list-mode is active, the output use the
|
||||
legacy format:
|
||||
@ -97,6 +103,9 @@ char *
|
||||
pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
|
||||
{
|
||||
const char *prefix = NULL;
|
||||
int dual = 0;
|
||||
char *curve;
|
||||
const char *name;
|
||||
|
||||
if (opt.legacy_list_mode)
|
||||
{
|
||||
@ -116,19 +125,34 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
|
||||
case PUBKEY_ALGO_ECDH:
|
||||
case PUBKEY_ALGO_ECDSA:
|
||||
case PUBKEY_ALGO_EDDSA: prefix = ""; break;
|
||||
case PUBKEY_ALGO_KY768_25519: prefix = "ky768"; break;
|
||||
case PUBKEY_ALGO_KY1024_448: prefix = "ky1024"; break;
|
||||
case PUBKEY_ALGO_KYBER: prefix = "ky"; dual = 1; break;
|
||||
case PUBKEY_ALGO_DIL3_25519: prefix = "dil3"; break;
|
||||
case PUBKEY_ALGO_DIL5_448: prefix = "dil5"; break;
|
||||
case PUBKEY_ALGO_SPHINX_SHA2: prefix = "sphinx_sha2"; break;
|
||||
}
|
||||
|
||||
|
||||
if (prefix && *prefix)
|
||||
{
|
||||
if (dual)
|
||||
{
|
||||
curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
/* Note that we prefer the abbreviated name of the curve. */
|
||||
name = openpgp_oid_to_curve (curve, 2);
|
||||
if (!name)
|
||||
name = "unknown";
|
||||
|
||||
snprintf (buffer, bufsize, "%s%u_%s",
|
||||
prefix, nbits_from_pk (pk), name);
|
||||
xfree (curve);
|
||||
}
|
||||
else
|
||||
snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
|
||||
}
|
||||
else if (prefix)
|
||||
{
|
||||
char *curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
const char *name = openpgp_oid_to_curve (curve, 0);
|
||||
curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
name = openpgp_oid_to_curve (curve, 0);
|
||||
|
||||
if (name)
|
||||
snprintf (buffer, bufsize, "%s", name);
|
||||
@ -308,6 +332,23 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5)
|
||||
pp[i] = NULL;
|
||||
nn[i] = 0;
|
||||
}
|
||||
else if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2)
|
||||
{
|
||||
/* Ugly: We need to re-construct the wire format of the
|
||||
* key parameter. It would be easier to use a second
|
||||
* second index for pp and nn which could bump
|
||||
* independet of i. */
|
||||
const char *p;
|
||||
|
||||
p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
|
||||
pp[i] = xmalloc ((nbits+7)/8 + 1);
|
||||
if (p)
|
||||
memcpy (pp[i], p, (nbits+7)/8);
|
||||
else
|
||||
pp[i] = NULL;
|
||||
nn[i] = (nbits+7)/8;
|
||||
n += nn[i];
|
||||
}
|
||||
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
||||
{
|
||||
const char *p;
|
||||
@ -805,11 +846,28 @@ namehash_from_uid (PKT_user_id *uid)
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of bits used in PK.
|
||||
* Return the number of bits used in PK. For Kyber we return the
|
||||
* octet count of the Kyber part and not of the ECC (thus likely
|
||||
* values are 768 or 1024).
|
||||
*/
|
||||
unsigned int
|
||||
nbits_from_pk (PKT_public_key *pk)
|
||||
{
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_KYBER)
|
||||
{
|
||||
unsigned int nbits;
|
||||
if (!gcry_mpi_get_opaque (pk->pkey[2], &nbits))
|
||||
return 0;
|
||||
switch (nbits/8)
|
||||
{
|
||||
case 800: nbits = 512; break;
|
||||
case 1184: nbits = 768; break;
|
||||
case 1568: nbits = 1024; break;
|
||||
default: nbits = 0; break; /* Unkown version. */
|
||||
}
|
||||
return nbits;
|
||||
}
|
||||
else
|
||||
return pubkey_nbits (pk->pubkey_algo, pk->pkey);
|
||||
}
|
||||
|
||||
@ -1292,6 +1350,17 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
|
||||
}
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_KYBER:
|
||||
{
|
||||
char tmpname[15];
|
||||
|
||||
snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk));
|
||||
err = gcry_sexp_build (&s_pkey, NULL,
|
||||
"(public-key(%s(p%m)))",
|
||||
tmpname, pk->pkey[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||
break;
|
||||
|
@ -801,8 +801,7 @@ openpgp_pk_algo_usage ( int algo )
|
||||
use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_KY768_25519:
|
||||
case PUBKEY_ALGO_KY1024_448:
|
||||
case PUBKEY_ALGO_KYBER:
|
||||
use = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC;
|
||||
break;
|
||||
|
||||
@ -1724,6 +1723,7 @@ pubkey_get_npkey (pubkey_algo_t algo)
|
||||
case PUBKEY_ALGO_ECDSA: return 2;
|
||||
case PUBKEY_ALGO_ELGAMAL: return 3;
|
||||
case PUBKEY_ALGO_EDDSA: return 2;
|
||||
case PUBKEY_ALGO_KYBER: return 3;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@ -1744,6 +1744,7 @@ pubkey_get_nskey (pubkey_algo_t algo)
|
||||
case PUBKEY_ALGO_ECDSA: return 3;
|
||||
case PUBKEY_ALGO_ELGAMAL: return 4;
|
||||
case PUBKEY_ALGO_EDDSA: return 3;
|
||||
case PUBKEY_ALGO_KYBER: return 5;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@ -1783,8 +1784,7 @@ pubkey_get_nenc (pubkey_algo_t algo)
|
||||
case PUBKEY_ALGO_ECDSA: return 0;
|
||||
case PUBKEY_ALGO_ELGAMAL: return 2;
|
||||
case PUBKEY_ALGO_EDDSA: return 0;
|
||||
case PUBKEY_ALGO_KY768_25519: return 4;
|
||||
case PUBKEY_ALGO_KY1024_448: return 4;
|
||||
case PUBKEY_ALGO_KYBER: return 4;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
@ -863,7 +863,9 @@ gpg_error_t build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf);
|
||||
int build_packet (iobuf_t out, PACKET *pkt);
|
||||
gpg_error_t build_packet_and_meta (iobuf_t out, PACKET *pkt);
|
||||
gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a, unsigned int *t_nwritten);
|
||||
gpg_error_t gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a);
|
||||
gpg_error_t gpg_mpi_write_opaque_nohdr (iobuf_t out, gcry_mpi_t a);
|
||||
gpg_error_t gpg_mpi_write_opaque_32 (iobuf_t out, gcry_mpi_t a,
|
||||
unsigned int *r_nwritten);
|
||||
u32 calc_packet_length( PACKET *pkt );
|
||||
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
||||
const byte *buffer, size_t buflen );
|
||||
|
@ -188,13 +188,21 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure)
|
||||
}
|
||||
|
||||
|
||||
/* Read an octet string of length NBYTES from INP and return it at
|
||||
* R_DATA. On error return an error code and store NULL at R_DATA.
|
||||
* PKTLEN shall give the current lenhgth of the packt and is updated
|
||||
* with each read. If SECURE is true, the integer is stored in secure
|
||||
* memory (allocated using gcry_xmalloc_secure). */
|
||||
/* If NLENGTH is zero read an octet string of length NBYTES from INP
|
||||
* and return it at R_DATA.
|
||||
*
|
||||
* If NLENGTH is either 1, 2, or 4 and NLENGTH is zero read an
|
||||
* NLENGTH-octet count and use this count number octets from INP and
|
||||
* return it at R_DATA.
|
||||
*
|
||||
* On error return an error code and store NULL at R_DATA. PKTLEN
|
||||
* shall give the current length of the packet and is updated with
|
||||
* each read. If SECURE is true, the integer is stored in secure
|
||||
* memory (allocated using gcry_xmalloc_secure).
|
||||
*/
|
||||
static gpg_error_t
|
||||
read_octet_string (iobuf_t inp, unsigned long *pktlen, unsigned int nbytes,
|
||||
read_octet_string (iobuf_t inp, unsigned long *pktlen,
|
||||
unsigned int nlength, unsigned int nbytes,
|
||||
int secure, gcry_mpi_t *r_data)
|
||||
{
|
||||
gpg_error_t err;
|
||||
@ -204,12 +212,48 @@ read_octet_string (iobuf_t inp, unsigned long *pktlen, unsigned int nbytes,
|
||||
|
||||
*r_data = NULL;
|
||||
|
||||
if (nbytes*8 > MAX_EXTERN_MPI_BITS)
|
||||
if ((nbytes && nlength)
|
||||
|| (!nbytes && !(nlength == 1 || nlength == 2 || nlength == 4)))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_ARG);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (nlength)
|
||||
{
|
||||
for (i = 0; i < nlength; i++)
|
||||
{
|
||||
if (!*pktlen)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_PACKET);
|
||||
goto leave;
|
||||
}
|
||||
c = iobuf_readbyte (inp);
|
||||
if (c < 0)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_PACKET);
|
||||
goto leave;
|
||||
}
|
||||
--*pktlen;
|
||||
nbytes <<= 8;
|
||||
nbytes |= c;
|
||||
}
|
||||
|
||||
if (!nbytes)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_PACKET);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if (nbytes*8 > (nbytes==4? MAX_EXTERN_KEYPARM_BITS:MAX_EXTERN_MPI_BITS)
|
||||
|| (nbytes*8 < nbytes))
|
||||
{
|
||||
log_error ("octet string too large (%u octets)\n", nbytes);
|
||||
err = gpg_error (GPG_ERR_TOO_LARGE);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (nbytes > *pktlen)
|
||||
{
|
||||
log_error ("octet string larger than packet (%u octets)\n", nbytes);
|
||||
@ -1408,7 +1452,6 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
int i, ndata;
|
||||
unsigned int n;
|
||||
PKT_pubkey_enc *k;
|
||||
int is_ky1024 = 0;
|
||||
|
||||
k = packet->pkt.pubkey_enc = xmalloc_clear (sizeof *packet->pkt.pubkey_enc);
|
||||
if (pktlen < 12)
|
||||
@ -1467,23 +1510,19 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
if (rc)
|
||||
goto leave;
|
||||
}
|
||||
else if (k->pubkey_algo == PUBKEY_ALGO_KY768_25519
|
||||
|| (is_ky1024 = (k->pubkey_algo == PUBKEY_ALGO_KY1024_448)))
|
||||
else if (k->pubkey_algo == PUBKEY_ALGO_KYBER)
|
||||
{
|
||||
log_assert (ndata == 4);
|
||||
/* Get the ephemeral public key. */
|
||||
n = is_ky1024? 56 : 32;
|
||||
rc = read_octet_string (inp, &pktlen, n, 0, k->data + 0);
|
||||
rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 0);
|
||||
if (rc)
|
||||
goto leave;
|
||||
/* Get the Kyber ciphertext. */
|
||||
n = is_ky1024? 1568 : 1088;
|
||||
rc = read_octet_string (inp, &pktlen, n, 0, k->data + 1);
|
||||
rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 1);
|
||||
if (rc)
|
||||
goto leave;
|
||||
/* Get the algorithm id. */
|
||||
n = 1;
|
||||
rc = read_octet_string (inp, &pktlen, n, 0, k->data + 2);
|
||||
rc = read_octet_string (inp, &pktlen, 0, 1, 0, k->data + 2);
|
||||
if (rc)
|
||||
goto leave;
|
||||
/* Get the wrapped symmetric key. */
|
||||
@ -2681,17 +2720,25 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
{
|
||||
if ( (algorithm == PUBKEY_ALGO_ECDSA && (i == 0))
|
||||
|| (algorithm == PUBKEY_ALGO_EDDSA && (i == 0))
|
||||
|| (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)))
|
||||
|| (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2))
|
||||
|| (algorithm == PUBKEY_ALGO_KYBER && (i == 0)))
|
||||
{
|
||||
/* Read the OID (i==0) or the KDF params (i==2). */
|
||||
err = read_sized_octet_string (inp, &pktlen, pk->pkey+i);
|
||||
}
|
||||
else if (algorithm == PUBKEY_ALGO_KYBER && i == 2)
|
||||
{
|
||||
/* Read the four-octet count prefixed Kyber public key. */
|
||||
err = read_octet_string (inp, &pktlen, 4, 0, 0, pk->pkey+i);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read MPI or SOS. */
|
||||
unsigned int n = pktlen;
|
||||
if (algorithm == PUBKEY_ALGO_ECDSA
|
||||
|| algorithm == PUBKEY_ALGO_EDDSA
|
||||
|| algorithm == PUBKEY_ALGO_ECDH)
|
||||
|| algorithm == PUBKEY_ALGO_ECDH
|
||||
|| algorithm == PUBKEY_ALGO_KYBER)
|
||||
pk->pkey[i] = sos_read (inp, &n, 0);
|
||||
else
|
||||
pk->pkey[i] = mpi_read (inp, &n, 0);
|
||||
@ -2707,7 +2754,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
mpi_print (listfp, pk->pkey[i], mpi_print_mode);
|
||||
if ((algorithm == PUBKEY_ALGO_ECDSA
|
||||
|| algorithm == PUBKEY_ALGO_EDDSA
|
||||
|| algorithm == PUBKEY_ALGO_ECDH) && i==0)
|
||||
|| algorithm == PUBKEY_ALGO_ECDH
|
||||
|| algorithm == PUBKEY_ALGO_KYBER) && i==0)
|
||||
{
|
||||
char *curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
const char *name = openpgp_oid_to_curve (curve, 0);
|
||||
@ -3044,21 +3092,32 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
/* Not encrypted. */
|
||||
for (i = npkey; i < nskey; i++)
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
if (pktlen < 2) /* At least two bytes for the length. */
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_PACKET);
|
||||
goto leave;
|
||||
}
|
||||
n = pktlen;
|
||||
if (algorithm == PUBKEY_ALGO_KYBER && i == npkey+1)
|
||||
{
|
||||
err = read_octet_string (inp, &pktlen, 4, 0, 1, pk->pkey+i);
|
||||
if (err)
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int n = pktlen;
|
||||
|
||||
if (algorithm == PUBKEY_ALGO_ECDSA
|
||||
|| algorithm == PUBKEY_ALGO_EDDSA
|
||||
|| algorithm == PUBKEY_ALGO_ECDH)
|
||||
|| algorithm == PUBKEY_ALGO_ECDH
|
||||
|| algorithm == PUBKEY_ALGO_KYBER)
|
||||
pk->pkey[i] = sos_read (inp, &n, 0);
|
||||
else
|
||||
pk->pkey[i] = mpi_read (inp, &n, 0);
|
||||
pktlen -= n;
|
||||
}
|
||||
|
||||
if (list_mode)
|
||||
{
|
||||
es_fprintf (listfp, "\tskey[%d]: ", i);
|
||||
|
Loading…
x
Reference in New Issue
Block a user