mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Some support to allow Kyber decryption.
* g10/call-agent.c (agent_pkdecrypt): Support dual keygrips and switch to KEM mode. * g10/ecdh.c (pk_ecdh_decrypt): Add an extra length check. * g10/keyid.c (do_hash_public_key): Fix Kyber fingerprint computation. * g10/mainproc.c (release_list): Free all 4 data elements. (proc_pubkey_enc): Copy all 4 data elements. * g10/misc.c (openpgp_pk_test_algo2): Map Kyber to KEM. * g10/parse-packet.c (parse_pubkeyenc): Fix Kyber parser. * g10/pubkey-enc.c (get_session_key): Allow Kyber. (get_it): Support Kyber. -- GnuPG-bug-id: 6815
This commit is contained in:
parent
1a37f0080b
commit
52c4b09080
@ -2878,6 +2878,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||||||
membuf_t data;
|
membuf_t data;
|
||||||
size_t n, len;
|
size_t n, len;
|
||||||
char *p, *buf, *endp;
|
char *p, *buf, *endp;
|
||||||
|
const char *keygrip2 = NULL;
|
||||||
struct default_inq_parm_s dfltparm;
|
struct default_inq_parm_s dfltparm;
|
||||||
|
|
||||||
memset (&dfltparm, 0, sizeof dfltparm);
|
memset (&dfltparm, 0, sizeof dfltparm);
|
||||||
@ -2886,13 +2887,26 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||||||
dfltparm.keyinfo.mainkeyid = mainkeyid;
|
dfltparm.keyinfo.mainkeyid = mainkeyid;
|
||||||
dfltparm.keyinfo.pubkey_algo = pubkey_algo;
|
dfltparm.keyinfo.pubkey_algo = pubkey_algo;
|
||||||
|
|
||||||
if (!keygrip || strlen(keygrip) != 40
|
if (!keygrip || !s_ciphertext || !r_buf || !r_buflen || !r_padding)
|
||||||
|| !s_ciphertext || !r_buf || !r_buflen || !r_padding)
|
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
*r_buf = NULL;
|
*r_buf = NULL;
|
||||||
*r_padding = -1;
|
*r_padding = -1;
|
||||||
|
|
||||||
|
/* Parse the keygrip in case of a dual algo. */
|
||||||
|
keygrip2 = strchr (keygrip, ',');
|
||||||
|
if (!keygrip2)
|
||||||
|
keygrip2 = keygrip + strlen (keygrip);
|
||||||
|
if (keygrip2 - keygrip != 40)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
if (*keygrip2)
|
||||||
|
{
|
||||||
|
keygrip2++;
|
||||||
|
if (strlen (keygrip2) != 40)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
err = start_agent (ctrl, 0);
|
err = start_agent (ctrl, 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -2903,11 +2917,19 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
snprintf (line, sizeof line, "SETKEY %s", keygrip);
|
snprintf (line, sizeof line, "SETKEY %.40s", keygrip);
|
||||||
err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (*keygrip2)
|
||||||
|
{
|
||||||
|
snprintf (line, sizeof line, "SETKEY --another %.40s", keygrip2);
|
||||||
|
err = assuan_transact (agent_ctx, line, NULL, NULL,NULL,NULL,NULL,NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (desc)
|
if (desc)
|
||||||
{
|
{
|
||||||
snprintf (line, DIM(line), "SETKEYDESC %s", desc);
|
snprintf (line, DIM(line), "SETKEYDESC %s", desc);
|
||||||
@ -2926,7 +2948,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||||||
err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen);
|
err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
err = assuan_transact (agent_ctx, "PKDECRYPT",
|
err = assuan_transact (agent_ctx,
|
||||||
|
*keygrip2? "PKDECRYPT --kem=PQC-PGP":"PKDECRYPT",
|
||||||
put_membuf_cb, &data,
|
put_membuf_cb, &data,
|
||||||
inq_ciphertext_cb, &parm,
|
inq_ciphertext_cb, &parm,
|
||||||
padding_info_cb, r_padding);
|
padding_info_cb, r_padding);
|
||||||
|
@ -537,7 +537,7 @@ pk_ecdh_decrypt (gcry_mpi_t *r_result, const byte sk_fp[MAX_FINGERPRINT_LEN],
|
|||||||
nbytes = (nbits+7)/8;
|
nbytes = (nbits+7)/8;
|
||||||
|
|
||||||
data_buf_size = nbytes;
|
data_buf_size = nbytes;
|
||||||
if ((data_buf_size & 7) != 1)
|
if ((data_buf_size & 7) != 1 || data_buf_size <= 1 + 8)
|
||||||
{
|
{
|
||||||
log_error ("can't use a shared secret of %d bytes for ecdh\n",
|
log_error ("can't use a shared secret of %d bytes for ecdh\n",
|
||||||
data_buf_size);
|
data_buf_size);
|
||||||
|
17
g10/keyid.c
17
g10/keyid.c
@ -336,17 +336,24 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5)
|
|||||||
{
|
{
|
||||||
/* Ugly: We need to re-construct the wire format of the
|
/* Ugly: We need to re-construct the wire format of the
|
||||||
* key parameter. It would be easier to use a second
|
* key parameter. It would be easier to use a second
|
||||||
* second index for pp and nn which could bump
|
* index for pp and nn which we could bump independet of
|
||||||
* independet of i. */
|
* i. */
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
|
p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
|
||||||
pp[i] = xmalloc ((nbits+7)/8 + 1);
|
nn[i] = (nbits+7)/8;
|
||||||
|
pp[i] = xmalloc (4 + nn[i] + 1);
|
||||||
if (p)
|
if (p)
|
||||||
memcpy (pp[i], p, (nbits+7)/8);
|
{
|
||||||
|
pp[i][0] = nn[i] >> 24;
|
||||||
|
pp[i][1] = nn[i] >> 16;
|
||||||
|
pp[i][2] = nn[i] >> 8;
|
||||||
|
pp[i][3] = nn[i];
|
||||||
|
memcpy (pp[i] + 4 , p, nn[i]);
|
||||||
|
nn[i] += 4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
pp[i] = NULL;
|
pp[i] = NULL;
|
||||||
nn[i] = (nbits+7)/8;
|
|
||||||
n += nn[i];
|
n += nn[i];
|
||||||
}
|
}
|
||||||
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
||||||
|
@ -143,6 +143,8 @@ release_list( CTX c )
|
|||||||
|
|
||||||
mpi_release (c->pkenc_list->data[0]);
|
mpi_release (c->pkenc_list->data[0]);
|
||||||
mpi_release (c->pkenc_list->data[1]);
|
mpi_release (c->pkenc_list->data[1]);
|
||||||
|
mpi_release (c->pkenc_list->data[2]);
|
||||||
|
mpi_release (c->pkenc_list->data[3]);
|
||||||
xfree (c->pkenc_list);
|
xfree (c->pkenc_list);
|
||||||
c->pkenc_list = tmp;
|
c->pkenc_list = tmp;
|
||||||
}
|
}
|
||||||
@ -527,11 +529,13 @@ proc_pubkey_enc (CTX c, PACKET *pkt)
|
|||||||
x->keyid[1] = enc->keyid[1];
|
x->keyid[1] = enc->keyid[1];
|
||||||
x->pubkey_algo = enc->pubkey_algo;
|
x->pubkey_algo = enc->pubkey_algo;
|
||||||
x->result = -1;
|
x->result = -1;
|
||||||
x->data[0] = x->data[1] = NULL;
|
x->data[0] = x->data[1] = x->data[2] = x->data[3] = NULL;
|
||||||
if (enc->data[0])
|
if (enc->data[0])
|
||||||
{
|
{
|
||||||
x->data[0] = mpi_copy (enc->data[0]);
|
x->data[0] = mpi_copy (enc->data[0]);
|
||||||
x->data[1] = mpi_copy (enc->data[1]);
|
x->data[1] = mpi_copy (enc->data[1]);
|
||||||
|
x->data[2] = mpi_copy (enc->data[2]);
|
||||||
|
x->data[3] = mpi_copy (enc->data[3]);
|
||||||
}
|
}
|
||||||
x->next = c->pkenc_list;
|
x->next = c->pkenc_list;
|
||||||
c->pkenc_list = x;
|
c->pkenc_list = x;
|
||||||
|
@ -750,6 +750,8 @@ openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
|
|||||||
ga = GCRY_PK_ELG;
|
ga = GCRY_PK_ELG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PUBKEY_ALGO_KYBER: ga = GCRY_PK_KEM; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1444,6 +1444,7 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse a public key encrypted packet (Tag 1). */
|
||||||
static int
|
static int
|
||||||
parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
|
parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
|
||||||
PACKET * packet)
|
PACKET * packet)
|
||||||
@ -1514,9 +1515,14 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
{
|
{
|
||||||
log_assert (ndata == 4);
|
log_assert (ndata == 4);
|
||||||
/* Get the ephemeral public key. */
|
/* Get the ephemeral public key. */
|
||||||
rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 0);
|
n = pktlen;
|
||||||
if (rc)
|
k->data[0] = sos_read (inp, &n, 0);
|
||||||
goto leave;
|
pktlen -= n;
|
||||||
|
if (!k->data[0])
|
||||||
|
{
|
||||||
|
rc = gpg_error (GPG_ERR_INV_PACKET);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
/* Get the Kyber ciphertext. */
|
/* Get the Kyber ciphertext. */
|
||||||
rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 1);
|
rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 1);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -117,6 +117,7 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
|
|||||||
{
|
{
|
||||||
if (!(k->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E
|
if (!(k->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E
|
||||||
|| k->pubkey_algo == PUBKEY_ALGO_ECDH
|
|| k->pubkey_algo == PUBKEY_ALGO_ECDH
|
||||||
|
|| k->pubkey_algo == PUBKEY_ALGO_KYBER
|
||||||
|| k->pubkey_algo == PUBKEY_ALGO_RSA
|
|| k->pubkey_algo == PUBKEY_ALGO_RSA
|
||||||
|| k->pubkey_algo == PUBKEY_ALGO_RSA_E
|
|| k->pubkey_algo == PUBKEY_ALGO_RSA_E
|
||||||
|| k->pubkey_algo == PUBKEY_ALGO_ELGAMAL))
|
|| k->pubkey_algo == PUBKEY_ALGO_ELGAMAL))
|
||||||
@ -237,6 +238,16 @@ get_it (ctrl_t ctrl,
|
|||||||
err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
|
err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
|
||||||
enc->data[1], enc->data[0]);
|
enc->data[1], enc->data[0]);
|
||||||
}
|
}
|
||||||
|
else if (sk->pubkey_algo == PUBKEY_ALGO_KYBER)
|
||||||
|
{
|
||||||
|
if (!enc->data[0] || !enc->data[1] || !enc->data[2] || !enc->data[3])
|
||||||
|
err = gpg_error (GPG_ERR_BAD_MPI);
|
||||||
|
else
|
||||||
|
err = gcry_sexp_build (&s_data, NULL,
|
||||||
|
"(enc-val(pqc(e%m)(k%m)(s%m)(fixed-info%s)))",
|
||||||
|
enc->data[0], enc->data[1], enc->data[3],
|
||||||
|
"\x1d" /*PUBKEY_ALGO_KYBER*/);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
err = gpg_error (GPG_ERR_BUG);
|
err = gpg_error (GPG_ERR_BUG);
|
||||||
|
|
||||||
@ -249,7 +260,6 @@ get_it (ctrl_t ctrl,
|
|||||||
/* Decrypt. */
|
/* Decrypt. */
|
||||||
desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1);
|
desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1);
|
||||||
|
|
||||||
/*FIXME: Support dual keys. */
|
|
||||||
err = agent_pkdecrypt (NULL, keygrip,
|
err = agent_pkdecrypt (NULL, keygrip,
|
||||||
desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
|
desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
|
||||||
s_data, &frame, &nframe, &padding);
|
s_data, &frame, &nframe, &padding);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user