diff --git a/pico-keys-sdk b/pico-keys-sdk index 09ec076..d0dea3d 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 09ec0767b6a3bd79b2a176fb468e97d9fde28449 +Subproject commit d0dea3d0c5427549ad56c284a2011d5b3eea42e0 diff --git a/src/openpgp/cmd_import_data.c b/src/openpgp/cmd_import_data.c index 697be3f..2be1363 100644 --- a/src/openpgp/cmd_import_data.c +++ b/src/openpgp/cmd_import_data.c @@ -177,7 +177,15 @@ int cmd_import_data() { mbedtls_ecp_keypair_free(&ecdsa); return SW_EXEC_ERROR(); } - r = mbedtls_ecp_mul(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, &ecdsa.grp.G, random_gen, NULL); +#ifdef MBEDTLS_EDDSA_C + if (ecdsa.grp.id == MBEDTLS_ECP_DP_ED25519) { + r = mbedtls_ecp_point_edwards(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, random_gen, NULL); + } + else +#endif + { + r = mbedtls_ecp_mul(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, &ecdsa.grp.G, random_gen, NULL); + } if (r != 0) { mbedtls_ecp_keypair_free(&ecdsa); return SW_EXEC_ERROR(); diff --git a/src/openpgp/do.c b/src/openpgp/do.c index 6b25482..fba8580 100644 --- a/src/openpgp/do.c +++ b/src/openpgp/do.c @@ -256,6 +256,20 @@ const uint8_t algorithm_attr_cv25519[] = { 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 }; +#ifdef MBEDTLS_EDDSA_C +const uint8_t algorithm_attr_ed25519[] = { + 10, + ALGO_EDDSA, + 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01 +}; + +const uint8_t algorithm_attr_ed448[] = { + 4, + ALGO_EDDSA, + 0x2b, 0x65, 0x71 +}; +#endif + int parse_algo(const uint8_t *algo, uint16_t tag) { res_APDU[res_APDU_size++] = tag & 0xff; memcpy(res_APDU + res_APDU_size, algo, algo[0] + 1); @@ -281,6 +295,10 @@ int parse_algoinfo(const file_t *f, int mode) { datalen += parse_algo(algorithm_attr_bp256r1, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_bp384r1, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_bp512r1, EF_ALGO_SIG); +#ifdef MBEDTLS_EDDSA_C + datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_SIG); + datalen += parse_algo(algorithm_attr_ed448, EF_ALGO_SIG); +#endif datalen += parse_algo(algorithm_attr_rsa1k, EF_ALGO_DEC); datalen += parse_algo(algorithm_attr_rsa2k, EF_ALGO_DEC); @@ -307,7 +325,10 @@ int parse_algoinfo(const file_t *f, int mode) { datalen += parse_algo(algorithm_attr_bp256r1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_bp384r1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_bp512r1, EF_ALGO_AUT); - +#ifdef MBEDTLS_EDDSA_C + datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_AUT); + datalen += parse_algo(algorithm_attr_ed448, EF_ALGO_AUT); +#endif uint16_t lpdif = res_APDU + res_APDU_size - lp - 2; *lp++ = lpdif >> 8; *lp++ = lpdif & 0xff; diff --git a/src/openpgp/do.h b/src/openpgp/do.h index fc10d50..3ed727d 100644 --- a/src/openpgp/do.h +++ b/src/openpgp/do.h @@ -26,3 +26,7 @@ extern const uint8_t algorithm_attr_cv25519[]; extern const uint8_t algorithm_attr_x448[]; extern const uint8_t algorithm_attr_rsa2k[]; extern const uint8_t algorithm_attr_rsa4096[]; +#ifdef MBEDTLS_EDDSA_C +extern const uint8_t algorithm_attr_ed25519[]; +extern const uint8_t algorithm_attr_ed448[]; +#endif diff --git a/src/openpgp/openpgp.c b/src/openpgp/openpgp.c index 1b16e8f..e4bc2f9 100644 --- a/src/openpgp/openpgp.c +++ b/src/openpgp/openpgp.c @@ -30,6 +30,9 @@ #include "ccid/ccid.h" #include "otp.h" #include "do.h" +#ifdef MBEDTLS_EDDSA_C +#include "mbedtls/eddsa.h" +#endif bool has_pw1 = false; bool has_pw2 = false; @@ -570,7 +573,15 @@ int load_private_key_ecdsa(mbedtls_ecp_keypair *ctx, file_t *fkey, bool use_dek) return PICOKEY_EXEC_ERROR; } mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_gen, NULL); +#ifdef MBEDTLS_EDDSA_C + if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519 || ctx->grp.id == MBEDTLS_ECP_DP_ED448) { + r = mbedtls_ecp_point_edwards(&ctx->grp, &ctx->Q, &ctx->d, random_gen, NULL); + } + else +#endif + { + r = mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_gen, NULL); + } if (r != 0) { mbedtls_ecdsa_free(ctx); return PICOKEY_EXEC_ERROR; @@ -615,6 +626,14 @@ mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_ else if (memcmp(algorithm_attr_x448 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_CURVE448; } +#ifdef MBEDTLS_EDDSA_C + else if (memcmp(algorithm_attr_ed25519 + 2, algo, algo_len) == 0) { + return MBEDTLS_ECP_DP_ED25519; + } + else if (memcmp(algorithm_attr_ed448 + 2, algo, algo_len) == 0) { + return MBEDTLS_ECP_DP_ED448; + } +#endif return MBEDTLS_ECP_DP_NONE; } @@ -733,18 +752,26 @@ int ecdsa_sign(mbedtls_ecp_keypair *ctx, size_t *out_len) { int r = 0; - mbedtls_mpi ri, si; - mbedtls_mpi_init(&ri); - mbedtls_mpi_init(&si); - r = mbedtls_ecdsa_sign(&ctx->grp, &ri, &si, &ctx->d, data, data_len, random_gen, NULL); - if (r == 0) { - size_t plen = (ctx->grp.nbits + 7) / 8; - mbedtls_mpi_write_binary(&ri, out, plen); - mbedtls_mpi_write_binary(&si, out + plen, plen); - *out_len = 2 * plen; +#ifdef MBEDTLS_EDDSA_C + if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519 || ctx->grp.id == MBEDTLS_ECP_DP_ED448) { + r = mbedtls_eddsa_write_signature(ctx, data, data_len, out, 114, out_len, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL); + } + else +#endif + { + mbedtls_mpi ri, si; + mbedtls_mpi_init(&ri); + mbedtls_mpi_init(&si); + r = mbedtls_ecdsa_sign(&ctx->grp, &ri, &si, &ctx->d, data, data_len, random_gen, NULL); + if (r == 0) { + size_t plen = (ctx->grp.nbits + 7) / 8; + mbedtls_mpi_write_binary(&ri, out, plen); + mbedtls_mpi_write_binary(&si, out + plen, plen); + *out_len = 2 * plen; + } + mbedtls_mpi_free(&ri); + mbedtls_mpi_free(&si); } - mbedtls_mpi_free(&ri); - mbedtls_mpi_free(&si); return r; }