aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-04-09 13:49:00 +0000
committerWerner Koch <[email protected]>2024-04-09 13:49:00 +0000
commit8d552b279d8963dfaff910a55bcca55ac5e2f258 (patch)
treeaf442611109b88e6d1476300207b8575c3f771c5
parentagent: Changes to the new KEM code in pkdecrypt.c (diff)
downloadgnupg-wk/kyber-test.tar.gz
gnupg-wk/kyber-test.zip
gpg: Make Kyber creation more flexible.wk/kyber-test
* common/openpgp-oid.c (openpgp_is_curve_supported): Allow the abbreviated curve name. * g10/pkglue.c (pk_encrypt): Add debug output. * g10/seskey.c (encode_session_key): Handle Kyber session key like ECDH. This is just a stub. * g10/keygen.c (ecckey_from_sexp): Use the modern OID for cv25519. (parse_key_parameter_part): Allow more Kyber variants. -- Test by creating an ed25519 key and using gpg --quick-add-key --batch --passphrase "" <fingerprint> <algo> to create several subkeys. Tested with ALGOs: kyber768 kyber1024 ky768_cv25519 ky768_bp256 kyber768_nistp256 ky1024_cv448 All curves capable of encryption should work. GnuPG-bug-id: 6815
-rw-r--r--common/openpgp-oid.c4
-rw-r--r--g10/encrypt.c2
-rw-r--r--g10/keygen.c51
-rw-r--r--g10/pkglue.c5
-rw-r--r--g10/seskey.c4
5 files changed, 55 insertions, 11 deletions
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c
index bc82cc6b0..4b59c1aeb 100644
--- a/common/openpgp-oid.c
+++ b/common/openpgp-oid.c
@@ -599,7 +599,9 @@ openpgp_is_curve_supported (const char *name, int *r_algo,
{
if ((!ascii_strcasecmp (name, oidtable[idx].name)
|| (oidtable[idx].alias
- && !ascii_strcasecmp (name, (oidtable[idx].alias))))
+ && !ascii_strcasecmp (name, (oidtable[idx].alias)))
+ || (oidtable[idx].abbr
+ && !ascii_strcasecmp (name, (oidtable[idx].abbr))))
&& curve_supported_p (oidtable[idx].name))
{
if (r_algo)
diff --git a/g10/encrypt.c b/g10/encrypt.c
index 62483fa16..aa0c3c6dd 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -758,7 +758,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, aead_algo_t aead_algo,
* Encrypt the file with the given userids (or ask if none is
* supplied). Either FILENAME or FILEFD must be given, but not both.
* The caller may provide a checked list of public keys in
- * PROVIDED_PKS; if not the function builds a list of keys on its own.
+ * PROVIDED_KEYS; if not the function builds a list of keys on its own.
*
* Note that FILEFD is currently only used by cmd_encrypt in the
* not yet finished server.c.
diff --git a/g10/keygen.c b/g10/keygen.c
index 763d23ee4..119f7ca5d 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1319,7 +1319,7 @@ curve_is_448 (gcry_sexp_t sexp)
* parameters for dual algorithm (e.g. Kyber). */
static gpg_error_t
ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
- gcry_sexp_t sexp2, int algo)
+ gcry_sexp_t sexp2, int algo, int pkversion)
{
gpg_error_t err;
gcry_sexp_t list, l2;
@@ -1362,6 +1362,10 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
err = gpg_error (GPG_ERR_INV_OBJ);
goto leave;
}
+ /* For v5 keys we prefer the modern OID for cv25519. */
+ if (pkversion > 4 && !strcmp (oidstr, "1.3.6.1.4.1.3029.1.5.1"))
+ oidstr = "1.3.101.110";
+
err = openpgp_oid_from_str (oidstr, &array[0]);
if (err)
goto leave;
@@ -1605,11 +1609,11 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
pk->pubkey_algo = algo;
if (algo == PUBKEY_ALGO_KYBER)
- err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo);
+ err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo, pk->version);
else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH )
- err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
+ err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo, pk->version);
else
err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
if (err)
@@ -1716,11 +1720,11 @@ common_gen (const char *keyparms, const char *keyparms2,
pk->pubkey_algo = algo;
if (algo == PUBKEY_ALGO_KYBER)
- err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo);
+ err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo, pk->version);
else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH )
- err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
+ err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo, pk->version);
else
err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
if (err)
@@ -3682,7 +3686,8 @@ parse_key_parameter_part (ctrl_t ctrl,
return gpg_error (GPG_ERR_INV_VALUE);
}
}
- else if (!ascii_strcasecmp (string, "kyber"))
+ else if (!ascii_strcasecmp (string, "kyber")
+ || !ascii_strcasecmp (string, "kyber768"))
{
/* Get the curve and check that it can technically be used
* (i.e. everything except the EdXXXX curves. */
@@ -3693,6 +3698,35 @@ parse_key_parameter_part (ctrl_t ctrl,
size = 768;
is_pqc = 1;
}
+ else if (!ascii_strcasecmp (string, "kyber1024"))
+ {
+ /* Get the curve and check that it can technically be used
+ * (i.e. everything except the EdXXXX curves. */
+ curve = openpgp_is_curve_supported ("brainpoolP512r1", &algo, NULL);
+ if (!curve || algo == PUBKEY_ALGO_EDDSA)
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ algo = PUBKEY_ALGO_KYBER;
+ size = 1024;
+ is_pqc = 1;
+ }
+ else if (!ascii_strncasecmp (string, "ky768_", 6)
+ || !ascii_strncasecmp (string, "ky1024_", 7)
+ || !ascii_strncasecmp (string, "kyber768_", 9)
+ || !ascii_strncasecmp (string, "kyber1024_", 10)
+ )
+ {
+ /* Get the curve and check that it can technically be used
+ * (i.e. everything except the EdXXXX curves. */
+ s = strchr (string, '_');
+ log_assert (s);
+ s++;
+ curve = openpgp_is_curve_supported (s, &algo, NULL);
+ if (!curve || algo == PUBKEY_ALGO_EDDSA)
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ algo = PUBKEY_ALGO_KYBER;
+ size = strstr (string, "768_")? 768 : 1024;
+ is_pqc = 1;
+ }
else if (!ascii_strcasecmp (string, "dil3"))
{
algo = PUBKEY_ALGO_DIL3_25519;
@@ -6734,12 +6768,14 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root,
if (curve_is_448 (s_key))
*keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
+ pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4;
+
if (algo == PUBKEY_ALGO_RSA)
err = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH )
- err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
+ err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo, pk->version);
else
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
gcry_sexp_release (s_key);
@@ -6752,7 +6788,6 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root,
}
pk->timestamp = *timestamp;
- pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4;
if (expireval)
pk->expiredate = pk->timestamp + expireval;
pk->pubkey_algo = algo;
diff --git a/g10/pkglue.c b/g10/pkglue.c
index f18313913..037e97a14 100644
--- a/g10/pkglue.c
+++ b/g10/pkglue.c
@@ -480,6 +480,11 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
gcry_mpi_release (k);
}
}
+ else if (algo == PUBKEY_ALGO_KYBER)
+ {
+ log_debug ("Implement Kyber encryption\n");
+ rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ }
else
rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
diff --git a/g10/seskey.c b/g10/seskey.c
index 15c210b78..e5397080d 100644
--- a/g10/seskey.c
+++ b/g10/seskey.c
@@ -92,7 +92,9 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits)
/* Shortcut for ECDH. It's padding is minimal to simply make the
output be a multiple of 8 bytes. */
- if (openpgp_pk_algo == PUBKEY_ALGO_ECDH)
+ /* FIXME: We use the ECDH also for Kyber for now. */
+ if (openpgp_pk_algo == PUBKEY_ALGO_ECDH
+ || openpgp_pk_algo == PUBKEY_ALGO_KYBER)
{
/* Pad to 8 byte granularity; the padding byte is the number of
* padded bytes.