[PATCH] scd: Generation of ECC keys on-board (OpenPGP card 3)
Arnaud Fontaine
arnaud.fontaine at ssi.gouv.fr
Fri Oct 14 13:46:35 CEST 2016
* scd/app-openpgp.c: Support for on-board generation of ECC keys
introduced in OpenPGP card specification 3.0.
---
scd/app-openpgp.c | 116
+++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 88 insertions(+), 28 deletions(-)
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 563a045..775640e 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -3568,9 +3568,17 @@ do_genkey (app_t app, ctrl_t ctrl, const char
*keynostr, unsigned int flags,
to put a limit on the max. allowed keysize. 2048 bit will
already lead to a 527 byte long status line and thus a 4096 bit
key would exceed the Assuan line length limit. */
- keybits = app->app_local->keyattr[keyno].rsa.n_bits;
- if (keybits > 4096)
- return gpg_error (GPG_ERR_TOO_LARGE);
+ if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
+ {
+ keybits = app->app_local->keyattr[keyno].rsa.n_bits;
+ if (keybits > 4096)
+ return gpg_error (GPG_ERR_TOO_LARGE);
+ }
+ else
+ {
+ keybits = 600; /* arbitrary value, but large enough for curves
+ supported in 3.0 */
+ }
/* Prepare for key generation by verifying the Admin PIN. */
rc = verify_chv3 (app, pincb, pincb_arg);
@@ -3625,38 +3633,90 @@ do_genkey (app_t app, ctrl_t ctrl, const char
*keynostr, unsigned int flags,
goto leave;
}
- m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
- if (!m)
+ created_at = createtime? createtime : gnupg_get_time ();
+ sprintf (numbuf, "%lu", (unsigned long)created_at);
+ send_status_info (ctrl, "KEY-CREATED-AT",
+ numbuf, (size_t)strlen(numbuf), NULL, 0);
+
+ if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
{
- rc = gpg_error (GPG_ERR_CARD);
- log_error (_("response does not contain the RSA modulus\n"));
- goto leave;
+ m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
+ if (!m)
+ {
+ rc = gpg_error (GPG_ERR_CARD);
+ log_error (_("response does not contain the RSA modulus\n"));
+ goto leave;
+ }
+ /* log_printhex ("RSA n:", m, mlen); */
+ send_key_data (ctrl, "n", m, mlen);
+
+ e = find_tlv (keydata, keydatalen, 0x0082, &elen);
+ if (!e)
+ {
+ rc = gpg_error (GPG_ERR_CARD);
+ log_error (_("response does not contain the RSA public
exponent\n"));
+ goto leave;
+ }
+ /* log_printhex ("RSA e:", e, elen); */
+ send_key_data (ctrl, "e", e, elen);
+
+ for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */
+ ;
+ for (; elen && !*e; elen--, e++) /* strip leading zeroes */
+ ;
+
+ rc = store_fpr (app, keyno, (u32)created_at, fprbuf, PUBKEY_ALGO_RSA,
+ m, mlen, e, elen);
}
- /* log_printhex ("RSA n:", m, mlen); */
- send_key_data (ctrl, "n", m, mlen);
- e = find_tlv (keydata, keydatalen, 0x0082, &elen);
- if (!e)
+ if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC)
{
- rc = gpg_error (GPG_ERR_CARD);
- log_error (_("response does not contain the RSA public exponent\n"));
- goto leave;
- }
- /* log_printhex ("RSA e:", e, elen); */
- send_key_data (ctrl, "e", e, elen);
+ gcry_mpi_t oid;
+ int n;
- created_at = createtime? createtime : gnupg_get_time ();
- sprintf (numbuf, "%lu", (unsigned long)created_at);
- send_status_info (ctrl, "KEY-CREATED-AT",
- numbuf, (size_t)strlen(numbuf), NULL, 0);
+ m = find_tlv (keydata, keydatalen, 0x0086, &mlen);
+ if (!m)
+ {
+ rc = gpg_error (GPG_ERR_CARD);
+ log_error (_("response does not contain the EC public key\n"));
+ goto leave;
+ }
- for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */
- ;
- for (; elen && !*e; elen--, e++) /* strip leading zeroes */
- ;
+ rc = openpgp_oid_from_str
(app->app_local->keyattr[keyno].ecc.oid, &oid);
+ if (rc)
+ goto leave;
+
+ e = gcry_mpi_get_opaque (oid, &n);
+ elen = (n+7)/8;
+
+ send_key_data (ctrl, "q", m, mlen);
+
+ for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */
+ ;
+
+ send_key_data(ctrl, "c", e, elen);
+
+ if (keyno == 1)
+ {
+ send_key_data(ctrl, "f", "\x03\x01\x08\x07", (size_t)4);
+
+ rc = store_fpr (app, keyno, (u32)created_at, fprbuf,
+ PUBKEY_ALGO_ECDH,
+ e, elen,
+ m, mlen,
+ "\x03\x01\x08\x07", (size_t)4); /* KDF for
ECDH : 03 01 hash_alg sym_alg */
+ /* hash_alg :
8 = SHA256, 9 = SHA384, 10 = SHA512 */
+ /* sym_alg :
7 = AES, 8 = AES192, 9 = AES256 */
+ }
+ else
+ {
+ rc = store_fpr (app, keyno, (u32)created_at, fprbuf,
+ PUBKEY_ALGO_ECDSA,
+ e, elen,
+ m, mlen);
+ }
+ }
- rc = store_fpr (app, keyno, (u32)created_at, fprbuf, PUBKEY_ALGO_RSA,
- m, mlen, e, elen);
if (rc)
goto leave;
send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf);
--
2.9.3
More information about the Gnupg-devel
mailing list