From a32f577dfa09f6033eb0c7db1340964736f83833 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 20 Feb 2014 10:55:20 +0900 Subject: [PATCH] add call-ec_p256k1 --- ChangeLog | 7 ++++ src/call-ec.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ src/call-ec_p256k1.c | 34 ++++++++++++++++++ src/call-ec_p256r1.c | 68 ++--------------------------------- src/gnuk.h | 10 ++++-- src/openpgp.c | 2 +- 6 files changed, 138 insertions(+), 69 deletions(-) create mode 100644 src/call-ec.c create mode 100644 src/call-ec_p256k1.c diff --git a/ChangeLog b/ChangeLog index e1a2c89..11361ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2014-02-20 Niibe Yutaka + + * src/call-ec_p256k1.c: New. Use call-ec.c. + * src/call-ec_p256r1.c: Use call-ec.c. + * src/call-ec.c: New. + (ecdsa_sign): Change the signature. + 2014-02-19 Niibe Yutaka * tool/calc_precompute_table_ecc.py: New. diff --git a/src/call-ec.c b/src/call-ec.c new file mode 100644 index 0000000..04b5bd4 --- /dev/null +++ b/src/call-ec.c @@ -0,0 +1,86 @@ +/* + * call-ec.c - interface between Gnuk and Elliptic curve over GF(prime) + * + * Copyright (C) 2013 Free Software Initiative of Japan + * Author: NIIBE Yutaka + * + * This file is a part of Gnuk, a GnuPG USB Token implementation. + * + * Gnuk is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Gnuk is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "field-group-select.h" + +/* We are little endian. */ + +#define ECDSA_BYTE_SIZE 32 + +int +FUNC(ecdsa_sign) (const uint8_t *hash, uint8_t *output, + const uint8_t *key_data) +{ + int i; + bn256 r[1], s[1], z[1], d[1]; + uint8_t *p; + + p = (uint8_t *)d; + for (i = 0; i < ECDSA_BYTE_SIZE; i++) + p[ECDSA_BYTE_SIZE - i - 1] = key_data[i]; + + p = (uint8_t *)z; + for (i = 0; i < ECDSA_BYTE_SIZE; i++) + p[ECDSA_BYTE_SIZE - i - 1] = hash[i]; + + FUNC(ecdsa) (r, s, z, d); + p = (uint8_t *)r; + for (i = 0; i < ECDSA_BYTE_SIZE; i++) + *output++ = p[ECDSA_BYTE_SIZE - i - 1]; + p = (uint8_t *)s; + for (i = 0; i < ECDSA_BYTE_SIZE; i++) + *output++ = p[ECDSA_BYTE_SIZE - i - 1]; + return 0; +} + +uint8_t * +FUNC(ecdsa_compute_public) (const uint8_t *key_data) +{ + uint8_t *p0, *p, *p1; + ac q[1]; + bn256 k[1]; + int i; + + p0 = (uint8_t *)malloc (ECDSA_BYTE_SIZE * 2); + if (p0 == NULL) + return NULL; + + p = (uint8_t *)k; + for (i = 0; i < ECDSA_BYTE_SIZE; i++) + p[ECDSA_BYTE_SIZE - i - 1] = key_data[i]; + if (FUNC(compute_kG) (q, k) < 0) + { + free (p0); + return NULL; + } + + p = p0; + p1 = (uint8_t *)q->x; + for (i = 0; i < ECDSA_BYTE_SIZE; i++) + *p++ = p1[ECDSA_BYTE_SIZE - i - 1]; + p1 = (uint8_t *)q->y; + for (i = 0; i < ECDSA_BYTE_SIZE; i++) + *p++ = p1[ECDSA_BYTE_SIZE - i - 1]; + + return p0; +} diff --git a/src/call-ec_p256k1.c b/src/call-ec_p256k1.c new file mode 100644 index 0000000..1a83ce5 --- /dev/null +++ b/src/call-ec_p256k1.c @@ -0,0 +1,34 @@ +/* + * call-ec_p256k1.c - interface between Gnuk and Elliptic curve over + * GF(p256k1) + * + * Copyright (C) 2014 Free Software Initiative of Japan + * Author: NIIBE Yutaka + * + * This file is a part of Gnuk, a GnuPG USB Token implementation. + * + * Gnuk is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Gnuk is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include "bn.h" +#include "jpc-ac_p256k1.h" +#include "ec_p256k1.h" + +#define FIELD p256k1 + +#include "call-ec.c" diff --git a/src/call-ec_p256r1.c b/src/call-ec_p256r1.c index c91e936..6b9a6c2 100644 --- a/src/call-ec_p256r1.c +++ b/src/call-ec_p256r1.c @@ -2,7 +2,7 @@ * call-ec_p256r1.c - interface between Gnuk and Elliptic curve over * GF(p256r1) * - * Copyright (C) 2013 Free Software Initiative of Japan + * Copyright (C) 2014 Free Software Initiative of Japan * Author: NIIBE Yutaka * * This file is a part of Gnuk, a GnuPG USB Token implementation. @@ -29,68 +29,6 @@ #include "jpc-ac_p256r1.h" #include "ec_p256r1.h" -#include "config.h" +#define FIELD p256r1 -#include "gnuk.h" - -/* We are little endian. */ - -#define ECDSA_BYTE_SIZE 32 - -int -ecdsa_sign (const uint8_t *hash, uint8_t *output, - const struct key_data *kd) -{ - int i; - bn256 r[1], s[1], z[1], d[1]; - uint8_t *p; - - p = (uint8_t *)d; - for (i = 0; i < ECDSA_BYTE_SIZE; i++) - p[ECDSA_BYTE_SIZE - i - 1] = kd->data[i]; - - p = (uint8_t *)z; - for (i = 0; i < ECDSA_BYTE_SIZE; i++) - p[ECDSA_BYTE_SIZE - i - 1] = hash[i]; - - ecdsa_p256r1 (r, s, z, d); - p = (uint8_t *)r; - for (i = 0; i < ECDSA_BYTE_SIZE; i++) - *output++ = p[ECDSA_BYTE_SIZE - i - 1]; - p = (uint8_t *)s; - for (i = 0; i < ECDSA_BYTE_SIZE; i++) - *output++ = p[ECDSA_BYTE_SIZE - i - 1]; - return 0; -} - -uint8_t * -ecdsa_compute_public (const uint8_t *key_data) -{ - uint8_t *p0, *p, *p1; - ac q[1]; - bn256 k[1]; - int i; - - p0 = (uint8_t *)malloc (ECDSA_BYTE_SIZE * 2); - if (p0 == NULL) - return NULL; - - p = (uint8_t *)k; - for (i = 0; i < ECDSA_BYTE_SIZE; i++) - p[ECDSA_BYTE_SIZE - i - 1] = key_data[i]; - if (compute_kG (q, k) < 0) - { - free (p0); - return NULL; - } - - p = p0; - p1 = (uint8_t *)q->x; - for (i = 0; i < ECDSA_BYTE_SIZE; i++) - *p++ = p1[ECDSA_BYTE_SIZE - i - 1]; - p1 = (uint8_t *)q->y; - for (i = 0; i < ECDSA_BYTE_SIZE; i++) - *p++ = p1[ECDSA_BYTE_SIZE - i - 1]; - - return p0; -} +#include "call-ec.c" diff --git a/src/gnuk.h b/src/gnuk.h index f3399b6..1e293c0 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -246,9 +246,13 @@ 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 (const uint8_t *hash, uint8_t *output, - const struct key_data *kd); -extern uint8_t *ecdsa_compute_public (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 uint8_t *ecdsa_compute_public_p256k1 (const uint8_t *key_data); 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.c b/src/openpgp.c index 9543643..dd26a16 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -966,7 +966,7 @@ cmd_internal_authenticate (void) res_APDU_size = ECDSA_SIGNATURE_LENGTH; r = ecdsa_sign (apdu.cmd_apdu_data, res_APDU, - &kd[GPG_KEY_FOR_AUTHENTICATION]); + kd[GPG_KEY_FOR_AUTHENTICATION]->data); if (r < 0) GPG_ERROR (); }