mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-01-17 09:28:05 +00:00
Removing cvcerts.h dependency.
A python script gets the public key of the device (EF_EE_DEV) and requests to our PKI for a CVC. Once got, it is updated to EF_TERMCA (0x2f02). termca_pk is now on EF_KEY_DEV and termca is on EF_TERMCA (concat with DICA). Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
4e01a78286
commit
fec02ca733
8 changed files with 45 additions and 39 deletions
|
|
@ -20,9 +20,9 @@
|
|||
#include "asn1.h"
|
||||
#include "sc_hsm.h"
|
||||
#include "random.h"
|
||||
#include "cvcerts.h"
|
||||
#include "oid.h"
|
||||
#include "eac.h"
|
||||
#include "files.h"
|
||||
|
||||
int cmd_general_authenticate() {
|
||||
if (P1(apdu) == 0x0 && P2(apdu) == 0x0) {
|
||||
|
|
@ -39,16 +39,27 @@ int cmd_general_authenticate() {
|
|||
pubkey_len = tag_len+1;
|
||||
}
|
||||
}
|
||||
file_t *fkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF);
|
||||
if (!fkey)
|
||||
return SW_EXEC_ERROR();
|
||||
mbedtls_ecdsa_context ectx;
|
||||
mbedtls_ecdsa_init(&ectx);
|
||||
r = load_private_key_ecdsa(&ectx, fkey);
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ectx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
mbedtls_ecdh_context ctx;
|
||||
int key_size = file_read_uint16(termca_pk);
|
||||
mbedtls_ecdh_init(&ctx);
|
||||
mbedtls_ecp_group_id gid = MBEDTLS_ECP_DP_SECP192R1;
|
||||
r = mbedtls_ecdh_setup(&ctx, gid);
|
||||
if (r != 0) {
|
||||
mbedtls_ecdsa_free(&ectx);
|
||||
mbedtls_ecdh_free(&ctx);
|
||||
return SW_DATA_INVALID();
|
||||
}
|
||||
r = mbedtls_mpi_read_binary(&ctx.ctx.mbed_ecdh.d, termca_pk+2, key_size);
|
||||
r = mbedtls_mpi_copy(&ctx.ctx.mbed_ecdh.d, &ectx.d);
|
||||
mbedtls_ecdsa_free(&ectx);
|
||||
if (r != 0) {
|
||||
mbedtls_ecdh_free(&ctx);
|
||||
return SW_DATA_INVALID();
|
||||
|
|
|
|||
|
|
@ -160,18 +160,18 @@ int cmd_initialize() {
|
|||
mbedtls_ecdsa_free(&ecdsa);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
|
||||
size_t cvc_len = 0;
|
||||
if ((cvc_len = asn1_cvc_aut(&ecdsa, HSM_KEY_EC, res_APDU, 4096, NULL, 0)) == 0) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
|
||||
file_t *fpk = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF);
|
||||
ret = flash_write_data_to_file(fpk, res_APDU, cvc_len);
|
||||
if (ret != 0)
|
||||
return SW_EXEC_ERROR();
|
||||
|
||||
const uint8_t *keyid = (const uint8_t *)"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", *label = (const uint8_t *)"TERMCA";
|
||||
const uint8_t *keyid = (const uint8_t *)"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", *label = (const uint8_t *)"ESTERMHSM";
|
||||
size_t prkd_len = asn1_build_prkd_ecc(label, strlen((const char *)label), keyid, 20, 192, res_APDU, 4096);
|
||||
fpk = search_by_fid(EF_PRKD_DEV, NULL, SPECIFY_EF);
|
||||
ret = flash_write_data_to_file(fpk, res_APDU, prkd_len);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "cvc.h"
|
||||
#include "kek.h"
|
||||
#include "files.h"
|
||||
#include "cvcerts.h"
|
||||
|
||||
uint8_t get_key_domain(file_t *fkey) {
|
||||
size_t tag_len = 0;
|
||||
|
|
@ -110,7 +109,10 @@ int cmd_key_domain() {
|
|||
else if (p1 == 0x2) { //XKEK Key Domain creation
|
||||
if (apdu.nc > 0) {
|
||||
size_t pub_len = 0;
|
||||
const uint8_t *pub = cvc_get_pub(termca+2, (termca[1] << 8 | termca[0]), &pub_len);
|
||||
file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF);
|
||||
if (!fterm)
|
||||
return SW_EXEC_ERROR();
|
||||
const uint8_t *pub = cvc_get_pub(file_get_data(fterm), file_get_size(fterm), &pub_len);
|
||||
if (!pub)
|
||||
return SW_EXEC_ERROR();
|
||||
size_t t86_len = 0;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ int cmd_select() {
|
|||
pfx == DCOD_PREFIX ||
|
||||
pfx == DATA_PREFIX ||
|
||||
pfx == PROT_DATA_PREFIX) {
|
||||
if (!(pe = search_dynamic_file(fid)))
|
||||
if (!(pe = search_dynamic_file(fid)) && !(pe = search_by_fid(fid, NULL, SPECIFY_EF)))
|
||||
return SW_FILE_NOT_FOUND();
|
||||
}
|
||||
if (!pe) {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "cvc.h"
|
||||
#include "sc_hsm.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "cvcerts.h"
|
||||
#include <string.h>
|
||||
#include "asn1.h"
|
||||
#include "ccid2040.h"
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
#include "random.h"
|
||||
#include "oid.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "files.h"
|
||||
|
||||
extern const uint8_t *dev_name;
|
||||
extern size_t dev_name_len;
|
||||
|
|
@ -182,7 +183,6 @@ size_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf
|
|||
p += format_tlv_len(body_size+sig_size, p);
|
||||
body = p;
|
||||
p += asn1_cvc_cert_body(rsa_ecdsa, key_type, p, body_size, ext, ext_len);
|
||||
|
||||
uint8_t hsh[32];
|
||||
hash256(body, body_size, hsh);
|
||||
memcpy(p, "\x5F\x37", 2); p += 2;
|
||||
|
|
@ -214,10 +214,19 @@ size_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf
|
|||
|
||||
size_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_len, const uint8_t *ext, size_t ext_len) {
|
||||
size_t cvcert_size = asn1_cvc_cert(rsa_ecdsa, key_type, NULL, 0, ext, ext_len);
|
||||
size_t outcar_len = 0;
|
||||
const uint8_t *outcar = cvc_get_chr((uint8_t *)termca+2, (termca[1] << 8) | termca[0], &outcar_len);
|
||||
size_t outcar_len = dev_name_len;
|
||||
const uint8_t *outcar = dev_name;
|
||||
size_t outcar_size = asn1_len_tag(0x42, outcar_len);
|
||||
int key_size = 2*file_read_uint16(termca_pk), ret = 0;
|
||||
file_t *fkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF);
|
||||
if (!fkey)
|
||||
return 0;
|
||||
mbedtls_ecdsa_context ectx;
|
||||
mbedtls_ecdsa_init(&ectx);
|
||||
if (load_private_key_ecdsa(&ectx, fkey) != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ectx);
|
||||
return 0;
|
||||
}
|
||||
int ret = 0, key_size = mbedtls_mpi_size(&ectx.d);
|
||||
size_t outsig_size = asn1_len_tag(0x5f37, key_size), tot_len = asn1_len_tag(0x67, cvcert_size+outcar_size+outsig_size);
|
||||
if (buf_len == 0 || buf == NULL)
|
||||
return tot_len;
|
||||
|
|
@ -231,10 +240,6 @@ size_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_
|
|||
p += asn1_cvc_cert(rsa_ecdsa, key_type, p, cvcert_size, ext, ext_len);
|
||||
//outcar
|
||||
*p++ = 0x42; p += format_tlv_len(outcar_len, p); memcpy(p, outcar, outcar_len); p += outcar_len;
|
||||
mbedtls_ecdsa_context ctx;
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
if (mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP192R1, &ctx, termca_pk+2, file_read_uint16(termca_pk)) != 0)
|
||||
return 0;
|
||||
uint8_t hsh[32];
|
||||
memcpy(p, "\x5f\x37", 2); p += 2;
|
||||
p += format_tlv_len(key_size, p);
|
||||
|
|
@ -242,8 +247,8 @@ size_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_
|
|||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
ret = mbedtls_ecdsa_sign(&ctx.grp, &r, &s, &ctx.d, hsh, sizeof(hsh), random_gen, NULL);
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
ret = mbedtls_ecdsa_sign(&ectx.grp, &r, &s, &ectx.d, hsh, sizeof(hsh), random_gen, NULL);
|
||||
mbedtls_ecdsa_free(&ectx);
|
||||
if (ret != 0) {
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
|
|
|
|||
|
|
@ -19,13 +19,12 @@
|
|||
|
||||
extern const uint8_t sc_hsm_aid[];
|
||||
extern int parse_token_info(const file_t *f, int mode);
|
||||
extern int parse_cvca(const file_t *f, int mode);
|
||||
|
||||
file_t file_entries[] = {
|
||||
/* 0 */ { .fid = 0x3f00 , .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, // MF
|
||||
/* 1 */ { .fid = 0x2f00 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DIR
|
||||
/* 2 */ { .fid = 0x2f01 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ATR
|
||||
/* 3 */ { .fid = 0x2f02 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC,.data = (uint8_t *)parse_cvca, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.GDO
|
||||
/* 3 */ { .fid = EF_TERMCA , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.GDO
|
||||
/* 4 */ { .fid = 0x2f03 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC,.data = (uint8_t *)parse_token_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo
|
||||
/* 5 */ { .fid = 0x5015 , .parent = 0, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, //DF.PKCS15
|
||||
/* 6 */ { .fid = 0x5031 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ODF
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#define EF_PRKD_DEV 0xC400
|
||||
#define EF_EE_DEV 0xCE00
|
||||
|
||||
#define EF_TERMCA 0x2f02
|
||||
|
||||
extern file_t *file_pin1;
|
||||
extern file_t *file_retries_pin1;
|
||||
extern file_t *file_sopin;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "files.h"
|
||||
#include "common.h"
|
||||
#include "version.h"
|
||||
#include "cvcerts.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "kek.h"
|
||||
#include "eac.h"
|
||||
|
|
@ -218,16 +217,15 @@ void init_sc_hsm() {
|
|||
}
|
||||
memset(puk_store, 0, sizeof(puk_store));
|
||||
puk_store_entries = 0;
|
||||
const uint8_t *cvcerts[] = { cvca, dica, termca };
|
||||
for (int i = 0; i < sizeof(cvcerts)/sizeof(uint8_t *); i++) {
|
||||
add_cert_puk_store(cvcerts[i]+2, (cvcerts[i][1] << 8) | cvcerts[i][0], false);
|
||||
}
|
||||
file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF);
|
||||
if (fterm)
|
||||
add_cert_puk_store(file_get_data(fterm), file_get_size(fterm), false);
|
||||
for (int i = 0; i < 0xfe; i++) {
|
||||
file_t *ef = search_dynamic_file((CA_CERTIFICATE_PREFIX << 8) | i);
|
||||
if (ef && file_get_size(ef) > 0)
|
||||
add_cert_puk_store(file_get_data(ef), file_get_size(ef), false);
|
||||
}
|
||||
dev_name = cvc_get_chr(termca, (termca[1] << 8) | termca[0], &dev_name_len);
|
||||
dev_name = cvc_get_chr(file_get_data(fterm), file_get_size(fterm), &dev_name_len);
|
||||
memset(puk_status, 0, sizeof(puk_status));
|
||||
}
|
||||
|
||||
|
|
@ -278,17 +276,6 @@ int parse_token_info(const file_t *f, int mode) {
|
|||
return 2+(2+1)+(2+8)+(2+strlen(manu))+(2+strlen(label))+(2+2);
|
||||
}
|
||||
|
||||
int parse_cvca(const file_t *f, int mode) {
|
||||
size_t termca_len = file_read_uint16(termca);
|
||||
size_t dica_len = file_read_uint16(dica);
|
||||
if (mode == 1) {
|
||||
memcpy(res_APDU, termca+2, termca_len);
|
||||
memcpy(res_APDU+termca_len, dica+2, dica_len);
|
||||
res_APDU_size = termca_len+dica_len;
|
||||
}
|
||||
return termca_len+dica_len;
|
||||
}
|
||||
|
||||
int pin_reset_retries(const file_t *pin, bool force) {
|
||||
if (!pin)
|
||||
return CCID_ERR_NULL_PARAM;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue