aboutsummaryrefslogtreecommitdiffstats
path: root/g10/pubkey-enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/pubkey-enc.c')
-rw-r--r--g10/pubkey-enc.c113
1 files changed, 87 insertions, 26 deletions
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index 6e1b0898e..563077803 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -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
|| k->pubkey_algo == PUBKEY_ALGO_ECDH
+ || k->pubkey_algo == PUBKEY_ALGO_KYBER
|| k->pubkey_algo == PUBKEY_ALGO_RSA
|| k->pubkey_algo == PUBKEY_ALGO_RSA_E
|| k->pubkey_algo == PUBKEY_ALGO_ELGAMAL))
@@ -193,7 +194,7 @@ get_it (ctrl_t ctrl,
{
gpg_error_t err;
byte *frame = NULL;
- unsigned int n;
+ unsigned int frameidx;
size_t nframe;
u16 csum, csum2;
int padding;
@@ -237,6 +238,32 @@ get_it (ctrl_t ctrl,
err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
enc->data[1], enc->data[0]);
}
+ else if (sk->pubkey_algo == PUBKEY_ALGO_KYBER)
+ {
+ char fixedinfo[1+MAX_FINGERPRINT_LEN];
+ int fixedlen;
+
+ if ((opt.compat_flags & COMPAT_T7014_OLD))
+ {
+ /* Temporary use for tests with original test vectors. */
+ fixedinfo[0] = 0x69;
+ fixedlen = 1;
+ }
+ else
+ {
+ fixedinfo[0] = enc->seskey_algo;
+ v5_fingerprint_from_pk (sk, fixedinfo+1, NULL);
+ fixedlen = 33;
+ }
+
+ if (!enc->data[0] || !enc->data[1] || !enc->data[2])
+ err = gpg_error (GPG_ERR_BAD_MPI);
+ else
+ err = gcry_sexp_build (&s_data, NULL,
+ "(enc-val(pqc(e%m)(k%m)(s%m)(c%d)(fixed-info%b)))",
+ enc->data[0], enc->data[1], enc->data[2],
+ enc->seskey_algo, fixedlen, fixedinfo);
+ }
else
err = gpg_error (GPG_ERR_BUG);
@@ -248,6 +275,7 @@ get_it (ctrl_t ctrl,
/* Decrypt. */
desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1);
+
err = agent_pkdecrypt (NULL, keygrip,
desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
s_data, &frame, &nframe, &padding);
@@ -275,9 +303,22 @@ get_it (ctrl_t ctrl,
*/
if (DBG_CRYPTO)
log_printhex (frame, nframe, "DEK frame:");
- n = 0;
+ frameidx = 0;
- if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
+ if (sk->pubkey_algo == PUBKEY_ALGO_KYBER)
+ {
+ /* We expect a 32 byte session key. We should not see this
+ * error here because due to the KEM mode the agent_pkdecrypt
+ * should have already failed. */
+ if (nframe != 32)
+ {
+ err = gpg_error (GPG_ERR_WRONG_SECKEY);
+ goto leave;
+ }
+ dek->keylen = nframe;
+ dek->algo = enc->seskey_algo;
+ }
+ else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
{
gcry_mpi_t decoded;
@@ -301,13 +342,21 @@ get_it (ctrl_t ctrl,
goto leave;
}
nframe -= frame[nframe-1]; /* Remove padding. */
- log_assert (!n); /* (used just below) */
+ if (4 > nframe)
+ {
+ err = gpg_error (GPG_ERR_WRONG_SECKEY);
+ goto leave;
+ }
+
+ dek->keylen = nframe - 3;
+ dek->algo = frame[0];
+ frameidx = 1;
}
else
{
if (padding)
{
- if (n + 7 > nframe)
+ if (7 > nframe)
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
@@ -319,34 +368,38 @@ get_it (ctrl_t ctrl,
* using a Smartcard we are doing it the right way and
* therefore we have to skip the zero. This should be fixed
* in gpg-agent of course. */
- if (!frame[n])
- n++;
+ frameidx = 0;
+ if (!frame[frameidx])
+ frameidx++;
- if (frame[n] == 1 && frame[nframe - 1] == 2)
+ if (frame[frameidx] == 1 && frame[nframe - 1] == 2)
{
log_info (_("old encoding of the DEK is not supported\n"));
err = gpg_error (GPG_ERR_CIPHER_ALGO);
goto leave;
}
- if (frame[n] != 2) /* Something went wrong. */
+ if (frame[frameidx] != 2) /* Something went wrong. */
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
- for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */
+ /* Skip the random bytes. */
+ for (frameidx++; frameidx < nframe && frame[frameidx]; frameidx++)
;
- n++; /* Skip the zero byte. */
+ frameidx++; /* Skip the zero byte. */
}
- }
- if (n + 4 > nframe)
- {
- err = gpg_error (GPG_ERR_WRONG_SECKEY);
- goto leave;
+ if (frameidx + 4 > nframe)
+ {
+ err = gpg_error (GPG_ERR_WRONG_SECKEY);
+ goto leave;
+ }
+
+ dek->keylen = nframe - (frameidx + 1) - 2;
+ dek->algo = frame[frameidx++];
}
- dek->keylen = nframe - (n + 1) - 2;
- dek->algo = frame[n++];
+ /* Check whether we support the ago. */
err = openpgp_cipher_test_algo (dek->algo);
if (err)
{
@@ -365,16 +418,21 @@ get_it (ctrl_t ctrl,
goto leave;
}
- /* Copy the key to DEK and compare the checksum. */
- csum = buf16_to_u16 (frame+nframe-2);
- memcpy (dek->key, frame + n, dek->keylen);
- for (csum2 = 0, n = 0; n < dek->keylen; n++)
- csum2 += dek->key[n];
- if (csum != csum2)
+ /* Copy the key to DEK and compare the checksum if needed. */
+ /* We use the frameidx as flag for the need of a checksum. */
+ memcpy (dek->key, frame + frameidx, dek->keylen);
+ if (frameidx)
{
- err = gpg_error (GPG_ERR_WRONG_SECKEY);
- goto leave;
+ csum = buf16_to_u16 (frame+nframe-2);
+ for (csum2 = 0, frameidx = 0; frameidx < dek->keylen; frameidx++)
+ csum2 += dek->key[frameidx];
+ if (csum != csum2)
+ {
+ err = gpg_error (GPG_ERR_WRONG_SECKEY);
+ goto leave;
+ }
}
+
if (DBG_CLOCK)
log_clock ("decryption ready");
if (DBG_CRYPTO)
@@ -399,6 +457,9 @@ get_it (ctrl_t ctrl,
log_info (_("WARNING: cipher algorithm %s not found in recipient"
" preferences\n"), openpgp_cipher_algo_name (dek->algo));
+ /* if (!err && 25519 && openpgp_oidbuf_is_ed25519 (curve, len)) */
+ /* log_info ("Note: legacy OID was used for cv25519\n"); */
+
if (!err)
{
kbnode_t k;