mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-01-17 09:28:05 +00:00
parent
4d6f6e4635
commit
629f14ab0d
8 changed files with 103 additions and 11 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 09ec0767b6a3bd79b2a176fb468e97d9fde28449
|
Subproject commit d0dea3d0c5427549ad56c284a2011d5b3eea42e0
|
||||||
|
|
@ -79,6 +79,14 @@ int cmd_keypair_gen() {
|
||||||
if (asn1_find_tag(&ctxo, 0x83, &g) != true) {
|
if (asn1_find_tag(&ctxo, 0x83, &g) != true) {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
}
|
}
|
||||||
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
if (ec_id == MBEDTLS_ECP_DP_CURVE25519 && (g.data[0] != 9)) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED25519;
|
||||||
|
}
|
||||||
|
else if (ec_id == MBEDTLS_ECP_DP_CURVE448 && (g.len != 56 || g.data[0] != 5)) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED448;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
mbedtls_ecdsa_context ecdsa;
|
mbedtls_ecdsa_context ecdsa;
|
||||||
mbedtls_ecdsa_init(&ecdsa);
|
mbedtls_ecdsa_init(&ecdsa);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
#include "mbedtls/oid.h"
|
#include "mbedtls/oid.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
#include "mbedtls/eddsa.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern mbedtls_ecp_keypair hd_context;
|
extern mbedtls_ecp_keypair hd_context;
|
||||||
extern uint8_t hd_keytype;
|
extern uint8_t hd_keytype;
|
||||||
|
|
@ -273,7 +276,16 @@ int cmd_signature() {
|
||||||
}
|
}
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
|
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
|
||||||
r = mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN, &olen, random_gen, NULL);
|
#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, apdu.data, apdu.nc, buf, sizeof(buf), &olen, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
r = mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN,
|
||||||
|
&olen, random_gen, NULL);
|
||||||
|
}
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
mbedtls_ecp_keypair_free(&ctx);
|
mbedtls_ecp_keypair_free(&ctx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@
|
||||||
#include "oid.h"
|
#include "oid.h"
|
||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
#include "mbedtls/eddsa.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern const uint8_t *dev_name;
|
extern const uint8_t *dev_name;
|
||||||
extern uint16_t dev_name_len;
|
extern uint16_t dev_name_len;
|
||||||
|
|
@ -88,7 +91,11 @@ uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecp_keypair *ecdsa, uint8_t *buf, uin
|
||||||
uint16_t ctot_size = asn1_len_tag(0x87, (uint16_t)c_size);
|
uint16_t ctot_size = asn1_len_tag(0x87, (uint16_t)c_size);
|
||||||
uint16_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa));
|
uint16_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa));
|
||||||
uint16_t tot_len = 0, tot_data_len = 0;
|
uint16_t tot_len = 0, tot_data_len = 0;
|
||||||
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
|
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY
|
||||||
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
|| mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
tot_data_len = oid_len + ptot_size + otot_size + gtot_size + ytot_size;
|
tot_data_len = oid_len + ptot_size + otot_size + gtot_size + ytot_size;
|
||||||
oid = oid_ri;
|
oid = oid_ri;
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +116,11 @@ uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecp_keypair *ecdsa, uint8_t *buf, uin
|
||||||
//oid
|
//oid
|
||||||
*p++ = 0x6; p += format_tlv_len(sizeof(oid_ecdsa), p); memcpy(p, oid, sizeof(oid_ecdsa));
|
*p++ = 0x6; p += format_tlv_len(sizeof(oid_ecdsa), p); memcpy(p, oid, sizeof(oid_ecdsa));
|
||||||
p += sizeof(oid_ecdsa);
|
p += sizeof(oid_ecdsa);
|
||||||
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
|
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY
|
||||||
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
|| mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
//p
|
//p
|
||||||
*p++ = 0x81; p += format_tlv_len((uint16_t)p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size);
|
*p++ = 0x81; p += format_tlv_len((uint16_t)p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size);
|
||||||
p += p_size;
|
p += p_size;
|
||||||
|
|
@ -296,7 +307,15 @@ uint16_t asn1_cvc_cert(void *rsa_ecdsa,
|
||||||
mbedtls_ecp_keypair *ecdsa = (mbedtls_ecp_keypair *) rsa_ecdsa;
|
mbedtls_ecp_keypair *ecdsa = (mbedtls_ecp_keypair *) rsa_ecdsa;
|
||||||
mbedtls_mpi_init(&r);
|
mbedtls_mpi_init(&r);
|
||||||
mbedtls_mpi_init(&s);
|
mbedtls_mpi_init(&s);
|
||||||
ret = mbedtls_ecdsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, hsh, sizeof(hsh), random_gen, NULL);
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
if (ecdsa->grp.id == MBEDTLS_ECP_DP_ED25519 || ecdsa->grp.id == MBEDTLS_ECP_DP_ED448) {
|
||||||
|
ret = mbedtls_eddsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, body, body_size, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ret = mbedtls_ecdsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, hsh, sizeof(hsh), random_gen, NULL);
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
mbedtls_mpi_write_binary(&r, p, key_size / 2); p += key_size / 2;
|
mbedtls_mpi_write_binary(&r, p, key_size / 2); p += key_size / 2;
|
||||||
mbedtls_mpi_write_binary(&s, p, key_size / 2); p += key_size / 2;
|
mbedtls_mpi_write_binary(&s, p, key_size / 2); p += key_size / 2;
|
||||||
|
|
@ -353,9 +372,17 @@ uint16_t asn1_cvc_aut(void *rsa_ecdsa,
|
||||||
mbedtls_mpi r, s;
|
mbedtls_mpi r, s;
|
||||||
mbedtls_mpi_init(&r);
|
mbedtls_mpi_init(&r);
|
||||||
mbedtls_mpi_init(&s);
|
mbedtls_mpi_init(&s);
|
||||||
uint8_t hsh[32];
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
hash256(body, cvcert_size + outcar_size, hsh);
|
if (ectx.grp.id == MBEDTLS_ECP_DP_ED25519 || ectx.grp.id == MBEDTLS_ECP_DP_ED448) {
|
||||||
ret = mbedtls_ecdsa_sign(&ectx.grp, &r, &s, &ectx.d, hsh, sizeof(hsh), random_gen, NULL);
|
ret = mbedtls_eddsa_sign(&ectx.grp, &r, &s, &ectx.d, body, cvcert_size + outcar_size, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
uint8_t hsh[32];
|
||||||
|
hash256(body, cvcert_size + outcar_size, hsh);
|
||||||
|
ret = mbedtls_ecdsa_sign(&ectx.grp, &r, &s, &ectx.d, hsh, sizeof(hsh), random_gen, NULL);
|
||||||
|
}
|
||||||
mbedtls_ecp_keypair_free(&ectx);
|
mbedtls_ecp_keypair_free(&ectx);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
mbedtls_mpi_free(&r);
|
mbedtls_mpi_free(&r);
|
||||||
|
|
|
||||||
|
|
@ -664,6 +664,14 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
|
||||||
|
|
||||||
//G
|
//G
|
||||||
len = get_uint16_t_be(kb + ofs);
|
len = get_uint16_t_be(kb + ofs);
|
||||||
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
if (ec_id == MBEDTLS_ECP_DP_CURVE25519 && kb[ofs + 2] != 0x09) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED25519;
|
||||||
|
}
|
||||||
|
else if (ec_id == MBEDTLS_ECP_DP_CURVE448 && (len != 56 || kb[ofs + 2] != 0x05)) {
|
||||||
|
ec_id = MBEDTLS_ECP_DP_ED448;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ofs += len + 2;
|
ofs += len + 2;
|
||||||
|
|
||||||
//d
|
//d
|
||||||
|
|
@ -679,7 +687,15 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
|
||||||
len = get_uint16_t_be(kb + ofs); ofs += 2;
|
len = get_uint16_t_be(kb + ofs); ofs += 2;
|
||||||
r = mbedtls_ecp_point_read_binary(&ecdsa->grp, &ecdsa->Q, kb + ofs, len);
|
r = mbedtls_ecp_point_read_binary(&ecdsa->grp, &ecdsa->Q, kb + ofs, len);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
r = mbedtls_ecp_mul(&ecdsa->grp, &ecdsa->Q, &ecdsa->d, &ecdsa->grp.G, random_gen, NULL);
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
|
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS) {
|
||||||
|
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) {
|
if (r != 0) {
|
||||||
mbedtls_ecdsa_free(ecdsa);
|
mbedtls_ecdsa_free(ecdsa);
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEY_EXEC_ERROR;
|
||||||
|
|
|
||||||
|
|
@ -683,7 +683,15 @@ int load_private_key_ec(mbedtls_ecp_keypair *ctx, file_t *fkey) {
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEY_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
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 (gid == MBEDTLS_ECP_DP_ED25519 || gid == 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) {
|
if (r != 0) {
|
||||||
mbedtls_ecp_keypair_free(ctx);
|
mbedtls_ecp_keypair_free(ctx);
|
||||||
return PICOKEY_EXEC_ERROR;
|
return PICOKEY_EXEC_ERROR;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import pytest
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
from picohsm import DOPrefixes
|
from picohsm import DOPrefixes
|
||||||
from cryptography.hazmat.primitives.asymmetric import rsa, ec, x25519, x448
|
from cryptography.hazmat.primitives.asymmetric import rsa, ec, x25519, x448, ed25519, ed448
|
||||||
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
||||||
from picohsm.const import DEFAULT_RETRIES, DEFAULT_DKEK_SHARES
|
from picohsm.const import DEFAULT_RETRIES, DEFAULT_DKEK_SHARES
|
||||||
from const import DEFAULT_DKEK
|
from const import DEFAULT_DKEK
|
||||||
|
|
@ -70,6 +70,17 @@ def test_import_montgomery(device, curve):
|
||||||
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
device.delete_file(DOPrefixes.EE_CERTIFICATE_PREFIX, keyid)
|
device.delete_file(DOPrefixes.EE_CERTIFICATE_PREFIX, keyid)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"curve", [ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey]
|
||||||
|
)
|
||||||
|
def test_import_edwards(device, curve):
|
||||||
|
pkey = curve.generate()
|
||||||
|
keyid = device.import_key(pkey)
|
||||||
|
pubkey = device.public_key(keyid, param=curve)
|
||||||
|
assert(pubkey.public_bytes(Encoding.Raw, PublicFormat.Raw) == pkey.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw))
|
||||||
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
|
device.delete_file(DOPrefixes.EE_CERTIFICATE_PREFIX, keyid)
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"size", [128, 192, 256]
|
"size", [128, 192, 256]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -54,3 +54,13 @@ def test_signature_rsa(device, modulus, scheme):
|
||||||
signature = device.sign(keyid=keyid, scheme=scheme, data=data)
|
signature = device.sign(keyid=keyid, scheme=scheme, data=data)
|
||||||
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
device.verify(pubkey, data, signature, scheme)
|
device.verify(pubkey, data, signature, scheme)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"curve", ['ed25519', 'ed448']
|
||||||
|
)
|
||||||
|
def test_signature_edwards(device, curve):
|
||||||
|
keyid = device.key_generation(KeyType.ECC, curve)
|
||||||
|
pubkey = device.public_key(keyid=keyid)
|
||||||
|
signature = device.sign(keyid=keyid, scheme=Algorithm.ALGO_EC_RAW, data=data)
|
||||||
|
device.delete_file(DOPrefixes.KEY_PREFIX, keyid)
|
||||||
|
device.verify(pubkey, data, signature)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue