mirror of
https://github.com/polhenarejos/pico-openpgp.git
synced 2025-12-20 12:03:31 +08:00
Merge branch 'eddsa'
This commit is contained in:
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
language: [ 'cpp', 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
mode: [ 'pico', 'esp32', 'local' ]
|
||||
mode: [ 'pico', 'local' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -14,10 +14,10 @@ name: "Emulation and test"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ "main", "piv" ]
|
||||
branches: [ "main", "piv", "eddsa" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "main", "piv" ]
|
||||
branches: [ "main", "piv", "eddsa" ]
|
||||
schedule:
|
||||
- cron: '23 5 * * 4'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION_MAJOR="3"
|
||||
VERSION_MINOR="4"
|
||||
VERSION_MINOR="4-eddsa1"
|
||||
SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}"
|
||||
#if ! [[ -z "${GITHUB_SHA}" ]]; then
|
||||
# SUFFIX="${SUFFIX}.${GITHUB_SHA}"
|
||||
|
||||
Submodule pico-keys-sdk updated: 07415e6e8b...6ec374a6ac
@@ -1,6 +1,6 @@
|
||||
idf_component_register(
|
||||
SRCS ${SOURCES}
|
||||
INCLUDE_DIRS . ../../pico-keys-sdk/src ../../pico-keys-sdk/src/fs ../../pico-keys-sdk/src/rng ../../pico-keys-sdk/src/usb
|
||||
INCLUDE_DIRS . ../../pico-keys-sdk/src ../../pico-keys-sdk/src/fs ../../pico-keys-sdk/src/rng ../../pico-keys-sdk/src/usb ../../pico-keys-sdk/tinycbor/src
|
||||
REQUIRES bootloader_support esp_partition esp_tinyusb zorxx__neopixel mbedtls efuse
|
||||
)
|
||||
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)
|
||||
|
||||
@@ -156,8 +156,8 @@ int cmd_import_data() {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
else if (algo[0] == ALGO_ECDSA || algo[0] == ALGO_ECDH) {
|
||||
mbedtls_ecdsa_context ecdsa;
|
||||
else if (algo[0] == ALGO_ECDSA || algo[0] == ALGO_ECDH || algo[0] == ALGO_EDDSA) {
|
||||
mbedtls_ecp_keypair ecdsa;
|
||||
if (p[1] == NULL || len[1] == 0) {
|
||||
return SW_WRONG_DATA();
|
||||
}
|
||||
@@ -165,7 +165,7 @@ int cmd_import_data() {
|
||||
if (gid == MBEDTLS_ECP_DP_NONE) {
|
||||
return SW_FUNC_NOT_SUPPORTED();
|
||||
}
|
||||
mbedtls_ecdsa_init(&ecdsa);
|
||||
mbedtls_ecp_keypair_init(&ecdsa);
|
||||
if (gid == MBEDTLS_ECP_DP_CURVE25519) {
|
||||
mbedtls_ecp_group_load(&ecdsa.grp, gid);
|
||||
r = mbedtls_mpi_read_binary(&ecdsa.d, p[1], len[1]);
|
||||
@@ -174,17 +174,22 @@ int cmd_import_data() {
|
||||
r = mbedtls_ecp_read_key(gid, &ecdsa, p[1], len[1]);
|
||||
}
|
||||
if (r != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
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);
|
||||
if (ecdsa.grp.id == MBEDTLS_ECP_DP_ED25519) {
|
||||
r = mbedtls_ecp_point_edwards(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, random_gen, NULL);
|
||||
}
|
||||
else {
|
||||
r = mbedtls_ecp_mul(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, &ecdsa.grp.G, random_gen, NULL);
|
||||
}
|
||||
if (r != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_ecp_keypair_free(&ecdsa);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
r = store_keys(&ecdsa, ALGO_ECDSA, fid, true);
|
||||
make_ecdsa_response(&ecdsa);
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_ecp_keypair_free(&ecdsa);
|
||||
if (r != PICOKEY_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
|
||||
@@ -57,17 +57,17 @@ int cmd_internal_aut() {
|
||||
}
|
||||
res_APDU_size = olen;
|
||||
}
|
||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
|
||||
mbedtls_ecdsa_context ctx;
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) {
|
||||
mbedtls_ecp_keypair ctx;
|
||||
mbedtls_ecp_keypair_init(&ctx);
|
||||
r = load_private_key_ecdsa(&ctx, ef, true);
|
||||
if (r != PICOKEY_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
mbedtls_ecp_keypair_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
size_t olen = 0;
|
||||
r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
mbedtls_ecp_keypair_free(&ctx);
|
||||
if (r != 0) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
|
||||
@@ -76,23 +76,23 @@ int cmd_keypair_gen() {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
|
||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) {
|
||||
printf("KEYPAIR ECDSA\r\n");
|
||||
mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo + 1, algo_len - 1);
|
||||
if (gid == MBEDTLS_ECP_DP_NONE) {
|
||||
return SW_FUNC_NOT_SUPPORTED();
|
||||
}
|
||||
mbedtls_ecdsa_context ecdsa;
|
||||
mbedtls_ecdsa_init(&ecdsa);
|
||||
mbedtls_ecp_keypair ecdsa;
|
||||
mbedtls_ecp_keypair_init(&ecdsa);
|
||||
uint8_t index = 0;
|
||||
r = mbedtls_ecdsa_genkey(&ecdsa, gid, random_gen, &index);
|
||||
if (r != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_ecp_keypair_free(&ecdsa);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
r = store_keys(&ecdsa, algo[0], fid, true);
|
||||
make_ecdsa_response(&ecdsa);
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_ecp_keypair_free(&ecdsa);
|
||||
if (r != PICOKEY_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
|
||||
@@ -137,18 +137,18 @@ int cmd_pso() {
|
||||
res_APDU_size = olen;
|
||||
}
|
||||
}
|
||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
|
||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) {
|
||||
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
||||
mbedtls_ecdsa_context ctx;
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
mbedtls_ecp_keypair ctx;
|
||||
mbedtls_ecp_keypair_init(&ctx);
|
||||
r = load_private_key_ecdsa(&ctx, ef, true);
|
||||
if (r != PICOKEY_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
mbedtls_ecp_keypair_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
size_t olen = 0;
|
||||
r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
mbedtls_ecp_keypair_free(&ctx);
|
||||
if (r != 0) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
|
||||
@@ -275,6 +275,12 @@ const uint8_t algorithm_attr_cv25519[] = {
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01
|
||||
};
|
||||
|
||||
const uint8_t algorithm_attr_ed25519[] = {
|
||||
10,
|
||||
ALGO_EDDSA,
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01
|
||||
};
|
||||
|
||||
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);
|
||||
@@ -300,6 +306,7 @@ 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);
|
||||
datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_SIG);
|
||||
|
||||
datalen += parse_algo(algorithm_attr_rsa1k, EF_ALGO_DEC);
|
||||
datalen += parse_algo(algorithm_attr_rsa2k, EF_ALGO_DEC);
|
||||
@@ -326,6 +333,7 @@ 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);
|
||||
datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_AUT);
|
||||
uint16_t lpdif = res_APDU + res_APDU_size - lp - 2;
|
||||
*lp++ = lpdif >> 8;
|
||||
*lp++ = lpdif & 0xff;
|
||||
|
||||
@@ -26,3 +26,4 @@ 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[];
|
||||
extern const uint8_t algorithm_attr_ed25519[];
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "ccid/ccid.h"
|
||||
#include "otp.h"
|
||||
#include "do.h"
|
||||
#include "mbedtls/eddsa.h"
|
||||
|
||||
uint8_t PICO_PRODUCT = 3;
|
||||
|
||||
@@ -488,8 +489,8 @@ int store_keys(void *key_ctx, int type, uint16_t key_id, bool use_kek) {
|
||||
mbedtls_mpi_write_binary(&rsa->P, kdata, key_size / 2);
|
||||
mbedtls_mpi_write_binary(&rsa->Q, kdata + key_size / 2, key_size / 2);
|
||||
}
|
||||
else if (type == ALGO_ECDSA || type == ALGO_ECDH) {
|
||||
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
|
||||
else if (type == ALGO_ECDSA || type == ALGO_ECDH || type == ALGO_EDDSA) {
|
||||
mbedtls_ecp_keypair *ecdsa = (mbedtls_ecp_keypair *) key_ctx;
|
||||
size_t olen = 0;
|
||||
kdata[0] = ecdsa->grp.id & 0xff;
|
||||
mbedtls_ecp_write_key_ext(ecdsa, &olen, kdata + 1, sizeof(kdata) - 1);
|
||||
@@ -558,7 +559,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey, bool use_dek) {
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey, bool use_dek) {
|
||||
int load_private_key_ecdsa(mbedtls_ecp_keypair *ctx, file_t *fkey, bool use_dek) {
|
||||
int key_size = file_get_size(fkey);
|
||||
uint8_t kdata[67]; //Worst case, 521 bit + 1byte
|
||||
memcpy(kdata, file_get_data(fkey), key_size);
|
||||
@@ -568,11 +569,16 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey, bool use_de
|
||||
mbedtls_ecp_group_id gid = kdata[0];
|
||||
int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1);
|
||||
if (r != 0) {
|
||||
mbedtls_ecdsa_free(ctx);
|
||||
mbedtls_ecp_keypair_free(ctx);
|
||||
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);
|
||||
if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519) {
|
||||
r = mbedtls_ecp_point_edwards(&ctx->grp, &ctx->Q, &ctx->d, random_gen, NULL);
|
||||
}
|
||||
else {
|
||||
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;
|
||||
@@ -617,6 +623,9 @@ 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;
|
||||
}
|
||||
else if (memcmp(algorithm_attr_ed25519 + 2, algo, algo_len) == 0) {
|
||||
return MBEDTLS_ECP_DP_ED25519;
|
||||
}
|
||||
return MBEDTLS_ECP_DP_NONE;
|
||||
}
|
||||
|
||||
@@ -635,7 +644,7 @@ void make_rsa_response(mbedtls_rsa_context *rsa) {
|
||||
put_uint16_t_be(res_APDU_size - 5, res_APDU + 3);
|
||||
}
|
||||
|
||||
void make_ecdsa_response(mbedtls_ecdsa_context *ecdsa) {
|
||||
void make_ecdsa_response(mbedtls_ecp_keypair *ecdsa) {
|
||||
uint8_t pt[MBEDTLS_ECP_MAX_PT_LEN];
|
||||
size_t plen = 0;
|
||||
mbedtls_ecp_point_write_binary(&ecdsa->grp,
|
||||
@@ -728,23 +737,30 @@ int rsa_sign(mbedtls_rsa_context *ctx,
|
||||
return r;
|
||||
}
|
||||
|
||||
int ecdsa_sign(mbedtls_ecdsa_context *ctx,
|
||||
int ecdsa_sign(mbedtls_ecp_keypair *ctx,
|
||||
const uint8_t *data,
|
||||
size_t data_len,
|
||||
uint8_t *out,
|
||||
size_t *out_len) {
|
||||
mbedtls_mpi ri, si;
|
||||
mbedtls_mpi_init(&ri);
|
||||
mbedtls_mpi_init(&si);
|
||||
int 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;
|
||||
|
||||
int r = 0;
|
||||
if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519) {
|
||||
r = mbedtls_eddsa_write_signature(ctx, data, data_len, out, 64, out_len, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||
}
|
||||
else {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ extern int pin_reset_retries(const file_t *pin, bool force);
|
||||
#define ALGO_RSA 0x01
|
||||
#define ALGO_ECDH 0x12
|
||||
#define ALGO_ECDSA 0x13
|
||||
#define ALGO_EDDSA 0x16
|
||||
#define ALGO_AES 0x70
|
||||
#define ALGO_AES_128 0x71
|
||||
#define ALGO_AES_192 0x72
|
||||
|
||||
Reference in New Issue
Block a user