mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Add option to create Kyber with --full-gen-key.
* g10/keygen.c (PQC_STD_KEY_PARAM_PRI, PQC_STD_KEY_PARAM_SUB): New. (PQC_STD_KEY_PARAM): Construct from above. (gen_kyber): Allow short curve names. (ask_algo): Add Entry for ecc+kyber. (ask_kyber_variant): New. (generate_keypair): Generate ECC primary and Kyber sub. -- GnuPG-bug-id: 6638
This commit is contained in:
parent
d54db0ac42
commit
6b02292d31
2
NEWS
2
NEWS
@ -1,6 +1,8 @@
|
|||||||
Noteworthy changes in version 2.5.2 (unreleased)
|
Noteworthy changes in version 2.5.2 (unreleased)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
|
* gpg: Add option 16 to --full-gen-key to create ECC+Kyber. [T6638]
|
||||||
|
|
||||||
* dirmngr: A list of used URLs for loaded CRLs is printed first in
|
* dirmngr: A list of used URLs for loaded CRLs is printed first in
|
||||||
the output of the LISTCRL command. [T7337]
|
the output of the LISTCRL command. [T7337]
|
||||||
|
|
||||||
|
173
g10/keygen.c
173
g10/keygen.c
@ -54,7 +54,9 @@
|
|||||||
* keep the values set in generate_subkeypair in sync. */
|
* keep the values set in generate_subkeypair in sync. */
|
||||||
#define DEFAULT_STD_KEY_PARAM "ed25519/cert,sign+cv25519/encr"
|
#define DEFAULT_STD_KEY_PARAM "ed25519/cert,sign+cv25519/encr"
|
||||||
#define FUTURE_STD_KEY_PARAM "ed25519/cert,sign+cv25519/encr"
|
#define FUTURE_STD_KEY_PARAM "ed25519/cert,sign+cv25519/encr"
|
||||||
#define PQC_STD_KEY_PARAM "bp384/cert,sign+kyber768_bp256/encr"
|
#define PQC_STD_KEY_PARAM_PRI "bp384/cert,sign"
|
||||||
|
#define PQC_STD_KEY_PARAM_SUB "kyber768_bp256/encr"
|
||||||
|
#define PQC_STD_KEY_PARAM PQC_STD_KEY_PARAM_PRI "+" PQC_STD_KEY_PARAM_SUB
|
||||||
|
|
||||||
/* When generating keys using the streamlined key generation dialog,
|
/* When generating keys using the streamlined key generation dialog,
|
||||||
use this as a default expiration interval. */
|
use this as a default expiration interval. */
|
||||||
@ -2181,8 +2183,9 @@ gen_kyber (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root,
|
|||||||
|
|
||||||
*keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
*keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
||||||
|
|
||||||
if (!strcmp (curve, "Curve25519"))
|
if (!strcmp (curve, "Curve25519") || !ascii_strcasecmp (curve, "cv25519"))
|
||||||
{
|
{
|
||||||
|
curve = "Curve25519";
|
||||||
keyparms1 = xtryasprintf
|
keyparms1 = xtryasprintf
|
||||||
("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))",
|
("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))",
|
||||||
strlen (curve), curve,
|
strlen (curve), curve,
|
||||||
@ -2190,8 +2193,9 @@ gen_kyber (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root,
|
|||||||
&& (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
|
&& (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
|
||||||
" transient-key" : ""));
|
" transient-key" : ""));
|
||||||
}
|
}
|
||||||
else if (!strcmp (curve, "X448"))
|
else if (!strcmp (curve, "X448") || !ascii_strcasecmp (curve, "cv448"))
|
||||||
{
|
{
|
||||||
|
curve = "X448";
|
||||||
keyparms1 = xtryasprintf
|
keyparms1 = xtryasprintf
|
||||||
("(genkey(ecc(curve %zu:%s)(flags comp%s)))",
|
("(genkey(ecc(curve %zu:%s)(flags comp%s)))",
|
||||||
strlen (curve), curve,
|
strlen (curve), curve,
|
||||||
@ -2591,10 +2595,11 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
|
|||||||
if (r_keygrip)
|
if (r_keygrip)
|
||||||
tty_printf (_(" (%d) Existing key from card%s\n"), 14, "");
|
tty_printf (_(" (%d) Existing key from card%s\n"), 14, "");
|
||||||
|
|
||||||
/* Reserve 15 for ECC or Dilithium primary + Kyber subkey. */
|
/* Reserve 15 for Dilithium primary + Kyber subkey. */
|
||||||
|
tty_printf (_(" (%d) ECC and Kyber%s\n"), 16, "");
|
||||||
if (addmode)
|
if (addmode)
|
||||||
{
|
{
|
||||||
tty_printf (_(" (%d) Kyber (encrypt only)%s\n"), 16, "");
|
tty_printf (_(" (%d) Kyber (encrypt only)%s\n"), 17, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -2882,7 +2887,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
|
|||||||
free_keypair_info (keypairlist);
|
free_keypair_info (keypairlist);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ((algo == 16 || !strcmp (answer, "kyber")) && addmode)
|
else if ((algo == 16 || !strcmp (answer, "ecc+kyber")) && !addmode)
|
||||||
|
{
|
||||||
|
algo = PUBKEY_ALGO_ECDSA;
|
||||||
|
*r_subkey_algo = PUBKEY_ALGO_KYBER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((algo == 17 || !strcmp (answer, "kyber")) && addmode)
|
||||||
{
|
{
|
||||||
algo = PUBKEY_ALGO_KYBER;
|
algo = PUBKEY_ALGO_KYBER;
|
||||||
*r_usage = PUBKEY_USAGE_ENC;
|
*r_usage = PUBKEY_USAGE_ENC;
|
||||||
@ -3219,6 +3230,77 @@ ask_curve (int *algo, int *subkey_algo, const char *current)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Ask for the Kyber variant. Returns a const algo string like
|
||||||
|
* kyber768_bp256 or NULL on error. */
|
||||||
|
const char *
|
||||||
|
ask_kyber_variant (void)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
const char *desc; /* e.g. "Kyber 768" */
|
||||||
|
const char *variant; /* e.g. "kyber768_bp256" */
|
||||||
|
unsigned int de_vs : 1; /* Allowed in CO_DE_VS. */
|
||||||
|
} table[] = {
|
||||||
|
{ "Kyber 768", "kyber768_bp256", 1 },
|
||||||
|
{ "Kyber 1024", "kyber1024_bp384", 1 },
|
||||||
|
{ "Kyber 768 (X25519)", "kyber768_cv25519", 0 },
|
||||||
|
{ "Kyber 1024 (X448)", "kyber1024_cv448", 0 },
|
||||||
|
};
|
||||||
|
int idx;
|
||||||
|
char *answer;
|
||||||
|
const char *result = NULL;
|
||||||
|
|
||||||
|
tty_printf (_("Please select the %s variant you want:\n"), "Kyber");
|
||||||
|
|
||||||
|
for (idx=0; idx < DIM(table); idx++)
|
||||||
|
{
|
||||||
|
if (opt.compliance==CO_DE_VS)
|
||||||
|
{
|
||||||
|
if (!table[idx].de_vs)
|
||||||
|
continue; /* Not allowed. */
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_printf (" (%d) %s%s\n", idx + 1,
|
||||||
|
table[idx].desc,
|
||||||
|
idx == 0? _(" *default*"):"");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
answer = cpr_get ("keygen.kyber_variant", _("Your selection? "));
|
||||||
|
cpr_kill_prompt ();
|
||||||
|
idx = *answer? atoi (answer) : 1 /* default */;
|
||||||
|
if (*answer && !idx)
|
||||||
|
{
|
||||||
|
/* See whether the user entered the name of the algo. */
|
||||||
|
for (idx=0; idx < DIM(table); idx++)
|
||||||
|
{
|
||||||
|
if (!stricmp (table[idx].variant, answer))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (idx == DIM(table))
|
||||||
|
idx = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
idx--; /* Map back to 0 based index. */
|
||||||
|
xfree(answer);
|
||||||
|
answer = NULL;
|
||||||
|
if (idx < 0 || idx >= DIM (table)
|
||||||
|
|| (opt.compliance==CO_DE_VS && !table[idx].de_vs))
|
||||||
|
tty_printf (_("Invalid selection.\n"));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = table[idx].variant;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
result = table[0].variant;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Parse an expire string and return its value in seconds.
|
* Parse an expire string and return its value in seconds.
|
||||||
* Returns (u32)-1 on error.
|
* Returns (u32)-1 on error.
|
||||||
@ -5296,7 +5378,7 @@ quickgen_set_para (struct para_data_s *para, int for_subkey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Always store the size - although not required for ECC it is
|
/* Always store the size - although not required for ECC it is
|
||||||
* required for compiste algos. Should not harm anyway. */
|
* required for composite algos. Should not harm anyway. */
|
||||||
r = xmalloc_clear (sizeof *r + 20);
|
r = xmalloc_clear (sizeof *r + 20);
|
||||||
r->key = for_subkey? pSUBKEYLENGTH : pKEYLENGTH;
|
r->key = for_subkey? pSUBKEYLENGTH : pKEYLENGTH;
|
||||||
sprintf (r->u.value, "%u", nbits);
|
sprintf (r->u.value, "%u", nbits);
|
||||||
@ -5699,7 +5781,82 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||||||
{
|
{
|
||||||
const char *curve = NULL;
|
const char *curve = NULL;
|
||||||
|
|
||||||
if (subkey_algo)
|
if (algo == PUBKEY_ALGO_ECDSA && subkey_algo == PUBKEY_ALGO_KYBER)
|
||||||
|
{
|
||||||
|
/* Create primary and subkey at once. */
|
||||||
|
const char *subalgostr;
|
||||||
|
const char *s;
|
||||||
|
const char *pricurve;
|
||||||
|
int prialgo = PUBKEY_ALGO_ECDSA;
|
||||||
|
|
||||||
|
both = 1;
|
||||||
|
subalgostr = ask_kyber_variant ();
|
||||||
|
if (!subalgostr) /* Should not happen. */
|
||||||
|
subalgostr = PQC_STD_KEY_PARAM_SUB;
|
||||||
|
|
||||||
|
/* Determine the primary key algo from the subkey algo. */
|
||||||
|
if (strstr (subalgostr, "bp384"))
|
||||||
|
pricurve = "brainpoolP384r1";
|
||||||
|
else if (strstr (subalgostr, "bp256"))
|
||||||
|
pricurve = "brainpoolP256r1";
|
||||||
|
else if (strstr (subalgostr, "cv448"))
|
||||||
|
{
|
||||||
|
pricurve = "Ed448";
|
||||||
|
prialgo = PUBKEY_ALGO_EDDSA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pricurve = "Ed25519";
|
||||||
|
prialgo = PUBKEY_ALGO_EDDSA;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = xmalloc_clear (sizeof *r + 20);
|
||||||
|
r->key = pKEYTYPE;
|
||||||
|
sprintf (r->u.value, "%d", prialgo);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
r = xmalloc_clear (sizeof *r + strlen (pricurve));
|
||||||
|
r->key = pKEYCURVE;
|
||||||
|
strcpy (r->u.value, pricurve);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
r = xmalloc_clear (sizeof *r + 20);
|
||||||
|
r->key = pKEYUSAGE;
|
||||||
|
strcpy (r->u.value, "sign");
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
r = xmalloc_clear (sizeof *r + 20);
|
||||||
|
r->key = pSUBKEYTYPE;
|
||||||
|
sprintf (r->u.value, "%d", PUBKEY_ALGO_KYBER);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
r = xmalloc_clear (sizeof *r + 20);
|
||||||
|
r->key = pSUBKEYLENGTH;
|
||||||
|
sprintf (r->u.value, "%u",
|
||||||
|
strstr (subalgostr, "768_")? 768 : 1024);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
s = strchr (subalgostr, '_');
|
||||||
|
log_assert (s && s[1]);
|
||||||
|
s++;
|
||||||
|
r = xmalloc_clear (sizeof *r + strlen (s));
|
||||||
|
r->key = pSUBKEYCURVE;
|
||||||
|
strcpy (r->u.value, s);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
r = xmalloc_clear (sizeof *r + 20);
|
||||||
|
r->key = pSUBKEYUSAGE;
|
||||||
|
strcpy( r->u.value, "encrypt" );
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
else if (subkey_algo)
|
||||||
{
|
{
|
||||||
/* Create primary and subkey at once. */
|
/* Create primary and subkey at once. */
|
||||||
both = 1;
|
both = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user