diff --git a/ChangeLog b/ChangeLog index 44a5d17..b1dfc3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2014-04-01 Niibe Yutaka + + * src/ecc-edwards.c (eddsa_compute_public_25519): New. + + * src/openpgp-do.c (algorithm_attr_ed25519): New. + (gpg_do_write_prvkey, proc_key_import, gpg_do_public_key): Add + EdDSA handling. + 2014-03-31 Niibe Yutaka * src/ecc-edwards.c (eddsa_sign_25519): Rename and API change. diff --git a/src/ecc-edwards.c b/src/ecc-edwards.c index 9f0091e..9a79fd5 100644 --- a/src/ecc-edwards.c +++ b/src/ecc-edwards.c @@ -23,6 +23,7 @@ */ #include +#include #include #include "bn.h" @@ -815,6 +816,22 @@ eddsa_public_key_25519 (bn256 *pk, const bn256 *a) pk->word[7] ^= mod25519_is_neg (R->x) * 0x80000000; } + +uint8_t * +eddsa_compute_public_25519 (const uint8_t *kd) +{ + uint8_t *p0; + const bn256 *a = (const bn256 *)kd; + + p0 = (uint8_t *)malloc (sizeof (bn256)); + if (p0 == NULL) + return NULL; + + eddsa_public_key_25519 ((bn256 *)p0, a); + return p0; +} + + #if 0 /** * check if P is on the curve. diff --git a/src/gnuk.h b/src/gnuk.h index a745383..b7043bb 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -248,19 +248,19 @@ extern int rsa_verify (const uint8_t *pubkey, const uint8_t *hash, const uint8_t *signature); extern uint8_t *rsa_genkey (void); -extern int ecdsa_sign_p256r1 (const uint8_t *hash, uint8_t *output, - const uint8_t *key_data); +extern int ecdsa_sign_p256r1 (const uint8_t *hash, uint8_t *output, + const uint8_t *key_data); extern uint8_t *ecdsa_compute_public_p256r1 (const uint8_t *key_data); -extern int ecdsa_sign_p256k1 (const uint8_t *hash, uint8_t *output, - const uint8_t *key_data); +extern int ecdsa_sign_p256k1 (const uint8_t *hash, uint8_t *output, + const uint8_t *key_data); extern uint8_t *ecdsa_compute_public_p256k1 (const uint8_t *key_data); - -extern int eddsa_sign_25519 (const uint8_t *input, size_t ilen, - uint8_t *output, - const uint8_t *sk_a, const uint8_t *seed, - const uint8_t *pk); +extern int eddsa_sign_25519 (const uint8_t *input, size_t ilen, + uint8_t *output, + const uint8_t *sk_a, const uint8_t *seed, + const uint8_t *pk); +extern uint8_t *eddsa_compute_public_25519 (const uint8_t *a); extern const uint8_t *gpg_do_read_simple (uint8_t); extern void gpg_do_write_simple (uint8_t, const uint8_t *, int); diff --git a/src/openpgp-do.c b/src/openpgp-do.c index 9fb312b..0293f61 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -826,6 +826,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, return -1; } #elif !defined(RSA_AUTH) && defined(RSA_SIG) +#if defined(ECDSA_AUTH) /* ECDSA with p256r1 for authentication */ if (kk != GPG_KEY_FOR_AUTHENTICATION && key_len != KEY_CONTENT_LEN) return -1; @@ -835,6 +836,17 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, if (key_len != 32) return -1; } +#else + /* EdDSA with Ed25519 for authentication */ + if (kk != GPG_KEY_FOR_AUTHENTICATION && key_len != KEY_CONTENT_LEN) + return -1; + if (kk == GPG_KEY_FOR_AUTHENTICATION) + { + pubkey_len = key_len / 2; + if (key_len != 64) + return -1; + } +#endif #else #error "not supported." #endif @@ -854,11 +866,19 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, else pubkey_allocated_here = modulus_calc (key_data, key_len); #elif !defined(RSA_AUTH) && defined(RSA_SIG) +#if defined(ECDSA_AUTH) /* ECDSA with p256r1 for authentication */ if (kk == GPG_KEY_FOR_AUTHENTICATION) pubkey_allocated_here = ecdsa_compute_public_p256r1 (key_data); else pubkey_allocated_here = modulus_calc (key_data, key_len); +#else + /* EdDSA with Ed25519 for authentication */ + if (kk == GPG_KEY_FOR_AUTHENTICATION) + pubkey_allocated_here = eddsa_compute_public_25519 (key_data); + else + pubkey_allocated_here = modulus_calc (key_data, key_len); +#endif #else #error "not supported." #endif @@ -900,7 +920,8 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, else memcpy (kdi.data, key_data, KEY_CONTENT_LEN); #elif !defined(RSA_AUTH) && defined(RSA_SIG) - /* ECDSA with p256r1 for authentication */ + /* ECDSA with p256r1 for authentication */ + /* EdDSA with Ed25519 for authentication */ if (kk == GPG_KEY_FOR_AUTHENTICATION) { memcpy (kdi.data, key_data, key_len); @@ -1083,14 +1104,21 @@ kkb_to_kk (uint8_t kk_byte) * 5f48, xx xx xx: cardholder private key * , , * - * ECDSA / EdDSA: + * ECDSA: * 4d, xx: Extended Header List * a4 00 (AUT) * 7f48, xx: cardholder private key template * 9x LEN: 9x=tag of private key d, LEN=length of d * 5f48, xx : cardholder private key * - * EdDSA 64-byte??? (a + seed, 32-byte each) + * + * EdDSA: + * 4d, xx: Extended Header List + * a4 00 (AUT) + * 7f48, xx: cardholder private key template + * 9x LEN: 9x=tag of private key d, LEN=length of d + * 5f48, xx : cardholder private key + * : (a + seed, 32-byte each) */ static int proc_key_import (const uint8_t *data, int len)