Merge branch 'eac'

This commit is contained in:
Pol Henarejos 2022-03-28 14:04:05 +02:00
commit 3112200eb6
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
5 changed files with 195 additions and 411 deletions

View file

@ -78,51 +78,15 @@ void process_fci(const file_t *pe) {
res_APDU[1] = res_APDU_size-2;
}
const uint8_t cvca[] = {
0x6A, 0x01,
0x7f, 0x21, 0x82, 0x01, 0x65, 0x7f, 0x4e, 0x82, 0x01, 0x2d, 0x5f,
0x29, 0x01, 0x00, 0x42, 0x0e, 0x45, 0x53, 0x48, 0x53, 0x4d, 0x43,
0x56, 0x43, 0x41, 0x32, 0x30, 0x34, 0x30, 0x31, 0x7f, 0x49, 0x81,
0xdd, 0x06, 0x0a, 0x04, 0x00, 0x7f, 0x00, 0x07, 0x02, 0x02, 0x02,
0x02, 0x03, 0x81, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x82, 0x18, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x83,
0x18, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c, 0x80, 0xe7, 0x0f, 0xa7,
0xe9, 0xab, 0x72, 0x24, 0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1,
0x46, 0xb9, 0xb1, 0x84, 0x31, 0x04, 0x18, 0x8d, 0xa8, 0x0e, 0xb0,
0x30, 0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb, 0x43, 0xa1, 0x88, 0x00,
0xf4, 0xff, 0x0a, 0xfd, 0x82, 0xff, 0x10, 0x12, 0x07, 0x19, 0x2b,
0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed, 0x6b, 0x24,
0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11, 0x85,
0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14, 0x6b, 0xc9, 0xb1, 0xb4,
0xd2, 0x28, 0x31, 0x86, 0x31, 0x04, 0x4d, 0x28, 0x34, 0x67, 0xb5,
0x43, 0xfd, 0x84, 0x22, 0x09, 0xbd, 0xd2, 0xd6, 0x26, 0x27, 0x2d,
0x53, 0xa7, 0xdf, 0x52, 0x8f, 0xc2, 0xde, 0x7c, 0x9a, 0xcd, 0x1f,
0xf2, 0x10, 0x42, 0x7c, 0x13, 0x44, 0x03, 0xb0, 0xa5, 0xdf, 0x8a,
0xd4, 0x59, 0xd1, 0x86, 0x4b, 0xde, 0x33, 0xb1, 0x60, 0x17, 0x87,
0x01, 0x01, 0x5f, 0x20, 0x0e, 0x45, 0x53, 0x48, 0x53, 0x4d, 0x43,
0x56, 0x43, 0x41, 0x32, 0x30, 0x34, 0x30, 0x31, 0x7f, 0x4c, 0x12,
0x06, 0x09, 0x04, 0x00, 0x7f, 0x00, 0x07, 0x03, 0x01, 0x02, 0x02,
0x53, 0x05, 0xc0, 0x00, 0x00, 0x00, 0x04, 0x5f, 0x25, 0x06, 0x02,
0x02, 0x00, 0x02, 0x01, 0x09, 0x5f, 0x24, 0x06, 0x03, 0x00, 0x01,
0x02, 0x03, 0x01, 0x5f, 0x37, 0x30, 0x26, 0x2d, 0x6f, 0xa6, 0xd0,
0x52, 0x01, 0xf1, 0x41, 0x1e, 0xe9, 0x33, 0x29, 0x19, 0x42, 0x42,
0x9b, 0xb0, 0xeb, 0xf7, 0x46, 0x20, 0xcb, 0x81, 0xfe, 0xda, 0xd7,
0xab, 0x2b, 0xdc, 0xa7, 0x38, 0xf4, 0xc8, 0xec, 0x4c, 0x66, 0xb4,
0x0a, 0x2d, 0x16, 0xfb, 0xf3, 0x79, 0xe9, 0x93, 0xc8, 0x25
};
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,.data = (uint8_t *)cvca, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.GDO
/* 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
/* 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

41
src/hsm/cvcerts.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef CVCERTS_H_
#define CVCERTS_H_
static const unsigned char termca[] = {
0xfa, 0x00,
0x7f,0x21,0x81,0xf6,0x7f,0x4e,0x81,0xbf,0x5f,0x29,0x01,0x00,0x42,0x0e,0x45,0x53,
0x44,0x56,0x43,0x41,0x48,0x53,0x4d,0x30,0x30,0x30,0x30,0x31,0x7f,0x49,0x3f,0x06,
0x0a,0x04,0x00,0x7f,0x00,0x07,0x02,0x02,0x02,0x02,0x03,0x86,0x31,0x04,0x0f,0x89,
0xb4,0x00,0x97,0x5e,0xdd,0x2d,0x42,0x5a,0xbf,0x85,0xf2,0xfb,0xd3,0x18,0x77,0x9b,
0x3d,0x85,0x47,0x5e,0x65,0xd4,0xd8,0x58,0x69,0xd3,0x04,0x14,0xb7,0x1f,0x16,0x1e,
0xb0,0x40,0xd9,0xf7,0xa7,0xe3,0x73,0xa3,0x15,0xc7,0xd9,0x9a,0x51,0xf5,0x5f,0x20,
0x0e,0x45,0x53,0x54,0x45,0x52,0x4d,0x48,0x53,0x4d,0x30,0x30,0x30,0x30,0x31,0x7f,
0x4c,0x12,0x06,0x09,0x04,0x00,0x7f,0x00,0x07,0x03,0x01,0x02,0x02,0x53,0x05,0x00,
0x00,0x00,0x00,0x04,0x5f,0x25,0x06,0x02,0x02,0x00,0x03,0x02,0x07,0x5f,0x24,0x06,
0x02,0x03,0x01,0x02,0x03,0x01,0x65,0x2f,0x73,0x2d,0x06,0x09,0x04,0x00,0x7f,0x00,
0x07,0x03,0x01,0x03,0x01,0x80,0x20,0x68,0x53,0x30,0xc7,0x9a,0x47,0xad,0xfd,0x37,
0xaa,0xe8,0x53,0xf4,0xbd,0x77,0x3a,0x40,0x89,0x3a,0x79,0x7e,0x3c,0x27,0x18,0x3b,
0x39,0x67,0xdf,0x8d,0x4f,0xe5,0x99,0x5f,0x37,0x30,0x10,0xff,0x17,0x96,0x0d,0x93,
0x07,0xc0,0x69,0x8e,0x3a,0xa0,0x44,0x69,0x70,0x88,0xe6,0x9c,0xb4,0xd3,0x16,0x9a,
0x22,0x4e,0x5c,0x77,0xa9,0xe7,0x83,0x75,0x9a,0xd2,0x7e,0x92,0xf2,0x04,0x93,0xb1,
0xe9,0xc9,0xe5,0x10,0xc9,0x94,0xff,0x9d,0xe2,0x00
};
static const unsigned char dica[] = {
0xc9, 0x00,
0x7f,0x21,0x81,0xc5,0x7f,0x4e,0x81,0x8e,0x5f,0x29,0x01,0x00,0x42,0x0e,0x45,0x53,
0x43,0x56,0x43,0x41,0x48,0x53,0x4d,0x30,0x30,0x30,0x30,0x31,0x7f,0x49,0x3f,0x06,
0x0a,0x04,0x00,0x7f,0x00,0x07,0x02,0x02,0x02,0x02,0x03,0x86,0x31,0x04,0x93,0x7e,
0xdf,0xf1,0xa6,0xd2,0x40,0x7e,0xb4,0x71,0xb2,0x97,0x50,0xdb,0x7e,0xe1,0x70,0xfb,
0x6c,0xcd,0x06,0x47,0x2a,0x3e,0x9c,0x8d,0x59,0x56,0x57,0xbe,0x11,0x11,0x0a,0x08,
0x81,0x54,0xed,0x22,0xc0,0x83,0xac,0xa1,0x2e,0x39,0x7b,0xd4,0x65,0x1f,0x5f,0x20,
0x0e,0x45,0x53,0x44,0x56,0x43,0x41,0x48,0x53,0x4d,0x30,0x30,0x30,0x30,0x31,0x7f,
0x4c,0x12,0x06,0x09,0x04,0x00,0x7f,0x00,0x07,0x03,0x01,0x02,0x02,0x53,0x05,0x80,
0x00,0x00,0x00,0x04,0x5f,0x25,0x06,0x02,0x02,0x00,0x03,0x02,0x07,0x5f,0x24,0x06,
0x02,0x05,0x01,0x02,0x03,0x01,0x5f,0x37,0x30,0x8b,0xb2,0x01,0xb6,0x24,0xfe,0xe5,
0x4e,0x65,0x3a,0x02,0xa2,0xb2,0x27,0x2d,0x3d,0xb4,0xb0,0xc9,0xdd,0xbf,0x10,0x6d,
0x99,0x49,0x46,0xd6,0xd0,0x72,0xc1,0xf3,0x4c,0xab,0x4f,0x32,0x14,0x7c,0xb0,0x99,
0xb7,0x33,0x70,0xd6,0x00,0xff,0x73,0x0c,0x5d
};
#endif

View file

@ -29,6 +29,7 @@
#include "mbedtls/cmac.h"
#include "mbedtls/hkdf.h"
#include "version.h"
#include "cvcerts.h"
const uint8_t sc_hsm_aid[] = {
11,
@ -146,6 +147,9 @@ static int cmd_select() {
if (apdu.cmd_apdu_data_len >= 2)
fid = get_uint16_t(apdu.cmd_apdu_data, 0);
//if ((fid & 0xff00) == (KEY_PREFIX << 8))
// fid = (PRKD_PREFIX << 8) | (fid & 0xff);
if ((fid & 0xff00) == (PRKD_PREFIX << 8)) {
if (!(pe = search_dynamic_file(fid)))
@ -222,6 +226,53 @@ static int cmd_select() {
return SW_OK ();
}
sc_context_t *create_context() {
sc_context_t *ctx;
sc_context_param_t ctx_opts;
memset(&ctx_opts, 0, sizeof(sc_context_param_t));
ctx_opts.ver = 0;
ctx_opts.app_name = "hsm2040";
sc_context_create(&ctx, &ctx_opts);
ctx->debug = 0;
sc_ctx_log_to_file(ctx, "stdout");
return ctx;
}
void cvc_init_common(sc_cvc_t *cvc, sc_context_t *ctx) {
memset(cvc, 0, sizeof(sc_cvc_t));
size_t lencar = 0, lenchr = 0;
const unsigned char *car = sc_asn1_find_tag(ctx, (const uint8_t *)apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, 0x42, &lencar);
const unsigned char *chr = sc_asn1_find_tag(ctx, (const uint8_t *)apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, 0x5f20, &lenchr);
if (car && lencar > 0)
strlcpy(cvc->car, car, MIN(lencar,sizeof(cvc->car)));
else
strlcpy(cvc->car, "UTSRCACC100001", sizeof(cvc->car));
if (chr && lenchr > 0)
strlcpy(cvc->chr, chr, MIN(lenchr, sizeof(cvc->chr)));
else
strlcpy(cvc->chr, "ESHSMCVCA00001", sizeof(cvc->chr));
strlcpy(cvc->outer_car, "ESHSM00001", sizeof(cvc->outer_car));
}
int cvc_prepare_signatures(sc_pkcs15_card_t *p15card, sc_cvc_t *cvc, size_t sig_len, uint8_t *hsh) {
uint8_t *cvcbin;
size_t cvclen;
cvc->signatureLen = sig_len;
cvc->signature = (uint8_t *)calloc(1, sig_len);
cvc->outerSignatureLen = 4;
cvc->outerSignature = (uint8_t *)calloc(1, sig_len);
int r = sc_pkcs15emu_sc_hsm_encode_cvc(p15card, cvc, &cvcbin, &cvclen);
if (r != SC_SUCCESS) {
if (cvcbin)
free(cvcbin);
return r;
}
hash(cvcbin, cvclen, hsh);
free(cvcbin);
return HSM_OK;
}
int parse_token_info(const file_t *f, int mode) {
char *label = "Pico-HSM";
char *manu = "Pol Henarejos";
@ -247,6 +298,16 @@ int parse_token_info(const file_t *f, int mode) {
return len;
}
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;
}
static int cmd_list_keys()
{
@ -254,6 +315,8 @@ static int cmd_list_keys()
for (int i = 0; i < dynamic_files; i++) {
file_t *f = &dynamic_file[i];
if ((f->fid & 0xff00) == (PRKD_PREFIX << 8)) {
res_APDU[res_APDU_size++] = PRKD_PREFIX;
res_APDU[res_APDU_size++] = f->fid & 0xff;
res_APDU[res_APDU_size++] = KEY_PREFIX;
res_APDU[res_APDU_size++] = f->fid & 0xff;
}
@ -421,6 +484,12 @@ static int cmd_verify() {
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_pin1->data+2));
}
else if (p2 == 0x88) { //SOPin
if (apdu.cmd_apdu_data_len > 0) {
return check_pin(file_sopin, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
}
if (file_read_uint8(file_retries_sopin->data+2) == 0)
return SW_PIN_BLOCKED();
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_sopin->data+2));
}
return SW_REFERENCE_NOT_FOUND();
}
@ -458,62 +527,82 @@ static int cmd_challenge() {
return SW_OK();
}
extern char __StackLimit;
int heapLeft() {
char *p = malloc(256); // try to avoid undue fragmentation
int left = &__StackLimit - p;
free(p);
return left;
}
static int cmd_initialize() {
initialize_flash(true);
scan_flash();
dkeks = 0;
const uint8_t *p = apdu.cmd_apdu_data;
while (p-apdu.cmd_apdu_data < apdu.cmd_apdu_data_len) {
uint8_t tag = *p++;
uint8_t tag_len = *p++;
if (tag == 0x80) { //options
}
else if (tag == 0x81) { //user pin
if (file_pin1 && file_pin1->data) {
uint8_t dhash[33];
dhash[0] = tag_len;
double_hash_pin(p, tag_len, dhash+1);
flash_write_data_to_file(file_pin1, dhash, sizeof(dhash));
hash_multi(p, tag_len, session_pin);
has_session_pin = true;
}
}
else if (tag == 0x82) { //user pin
if (file_sopin && file_sopin->data) {
uint8_t dhash[33];
dhash[0] = tag_len;
double_hash_pin(p, tag_len, dhash+1);
flash_write_data_to_file(file_sopin, dhash, sizeof(dhash));
hash_multi(p, tag_len, session_sopin);
has_session_sopin = true;
}
}
else if (tag == 0x91) { //user pin
file_t *tf = search_by_fid(0x1082, NULL, SPECIFY_EF);
if (tf && tf->data) {
flash_write_data_to_file(tf, p, tag_len);
if (apdu.cmd_apdu_data_len > 0) {
initialize_flash(true);
scan_flash();
dkeks = current_dkeks = 0;
const uint8_t *p = apdu.cmd_apdu_data;
while (p-apdu.cmd_apdu_data < apdu.cmd_apdu_data_len) {
uint8_t tag = *p++;
uint8_t tag_len = *p++;
if (tag == 0x80) { //options
}
if (file_retries_pin1 && file_retries_pin1->data) {
flash_write_data_to_file(file_retries_pin1, p, tag_len);
else if (tag == 0x81) { //user pin
if (file_pin1 && file_pin1->data) {
uint8_t dhash[33];
dhash[0] = tag_len;
double_hash_pin(p, tag_len, dhash+1);
flash_write_data_to_file(file_pin1, dhash, sizeof(dhash));
hash_multi(p, tag_len, session_pin);
has_session_pin = true;
}
}
else if (tag == 0x82) { //sopin pin
if (file_sopin && file_sopin->data) {
uint8_t dhash[33];
dhash[0] = tag_len;
double_hash_pin(p, tag_len, dhash+1);
flash_write_data_to_file(file_sopin, dhash, sizeof(dhash));
hash_multi(p, tag_len, session_sopin);
has_session_sopin = true;
}
}
else if (tag == 0x91) { //retries user pin
file_t *tf = search_by_fid(0x1082, NULL, SPECIFY_EF);
if (tf && tf->data) {
flash_write_data_to_file(tf, p, tag_len);
}
if (file_retries_pin1 && file_retries_pin1->data) {
flash_write_data_to_file(file_retries_pin1, p, tag_len);
}
}
else if (tag == 0x92) {
dkeks = *p;
}
p += tag_len;
}
else if (tag == 0x92) {
dkeks = *p;
current_dkeks = 0;
}
p += tag_len;
}
p = random_bytes_get(32);
memset(tmp_dkek, 0, sizeof(tmp_dkek));
memcpy(tmp_dkek, p, IV_SIZE);
if (dkeks == 0) {
p = random_bytes_get(32);
memcpy(tmp_dkek+IV_SIZE, p, 32);
encrypt(session_pin, tmp_dkek, tmp_dkek+IV_SIZE, 32);
file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, tmp_dkek, sizeof(tmp_dkek));
memset(tmp_dkek, 0, sizeof(tmp_dkek));
memcpy(tmp_dkek, p, IV_SIZE);
if (dkeks == 0) {
p = random_bytes_get(32);
memcpy(tmp_dkek+IV_SIZE, p, 32);
encrypt(session_pin, tmp_dkek, tmp_dkek+IV_SIZE, 32);
file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, tmp_dkek, sizeof(tmp_dkek));
}
low_flash_available();
}
else { //free memory bytes request
int heap_left = heapLeft();
res_APDU[0] = ((heap_left >> 24) & 0xff);
res_APDU[1] = ((heap_left >> 16) & 0xff);
res_APDU[2] = ((heap_left >> 8) & 0xff);
res_APDU[3] = ((heap_left >> 0) & 0xff);
res_APDU[4] = 0;
res_APDU[5] = HSM_VERSION_MAJOR;
res_APDU[6] = HSM_VERSION_MINOR;
res_APDU_size = 7;
}
low_flash_available();
return SW_OK();
}
@ -571,9 +660,11 @@ void generic_hash(mbedtls_md_type_t md, const uint8_t *input, size_t len, uint8_
}
static int cmd_import_dkek() {
if (dkeks == 0)
return SW_COMMAND_NOT_ALLOWED();
if (has_session_pin == false)
//if (dkeks == 0)
// return SW_COMMAND_NOT_ALLOWED();
if (P1(apdu) != 0x0 || P2(apdu) != 0x0)
return SW_INCORRECT_P1P2();
if (has_session_pin == false && apdu.cmd_apdu_data_len > 0)
return SW_CONDITIONS_NOT_SATISFIED();
file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF);
if (!authenticate_action(get_parent(tf), ACL_OP_CREATE_EF)) {
@ -720,53 +811,6 @@ int store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx) {
return HSM_OK;
}
sc_context_t *create_context() {
sc_context_t *ctx;
sc_context_param_t ctx_opts;
memset(&ctx_opts, 0, sizeof(sc_context_param_t));
ctx_opts.ver = 0;
ctx_opts.app_name = "hsm2040";
sc_context_create(&ctx, &ctx_opts);
ctx->debug = 0;
sc_ctx_log_to_file(ctx, "stdout");
return ctx;
}
void cvc_init_common(sc_cvc_t *cvc, sc_context_t *ctx) {
memset(cvc, 0, sizeof(sc_cvc_t));
size_t lencar = 0, lenchr = 0;
const unsigned char *car = sc_asn1_find_tag(ctx, (const uint8_t *)apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, 0x42, &lencar);
const unsigned char *chr = sc_asn1_find_tag(ctx, (const uint8_t *)apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, 0x5f20, &lenchr);
if (car && lencar > 0)
strlcpy(cvc->car, car, MIN(lencar,sizeof(cvc->car)));
else
strlcpy(cvc->car, "UTCA00001", sizeof(cvc->car));
if (chr && lenchr > 0)
strlcpy(cvc->chr, chr, MIN(lenchr, sizeof(cvc->chr)));
else
strlcpy(cvc->chr, "ESHSMCVCA00001", sizeof(cvc->chr));
strlcpy(cvc->outer_car, "ESHSM00001", sizeof(cvc->outer_car));
}
int cvc_prepare_signatures(sc_pkcs15_card_t *p15card, sc_cvc_t *cvc, size_t sig_len, uint8_t *hsh) {
uint8_t *cvcbin;
size_t cvclen;
cvc->signatureLen = sig_len;
cvc->signature = (uint8_t *)calloc(1, sig_len);
cvc->outerSignatureLen = 4;
cvc->outerSignature = (uint8_t *)calloc(1, sig_len);
int r = sc_pkcs15emu_sc_hsm_encode_cvc(p15card, cvc, &cvcbin, &cvclen);
if (r != SC_SUCCESS) {
if (cvcbin)
free(cvcbin);
return r;
}
hash(cvcbin, cvclen, hsh);
free(cvcbin);
return HSM_OK;
}
static int cmd_keypair_gen() {
uint8_t key_id = P1(apdu);
uint8_t auth_key_id = P2(apdu);

View file

@ -84,6 +84,14 @@ extern const uint8_t sc_hsm_aid[];
#define ALGO_AES_CMAC 0x18
#define ALGO_AES_DERIVE 0x99
#define HSM_OPT_RRC 0x1
#define HSM_OPT_TRANSPORT_PIN 0x2
#define HSM_OPT_SESSION_PIN 0x4
#define HSM_OPT_SESSION_PIN_EXPL 0xC
#define HSM_OPT_REPLACE_PKA 0x8
#define HSM_OPT_COMBINED_AUTH 0x10
#define HSM_OPT_RRC_RESET_ONLY 0x20
extern int pin_reset_retries(const file_t *pin, bool);
extern int pin_wrong_retry(const file_t *pin);

View file

@ -1,273 +0,0 @@
/*
* Copyright (C) 2009-2015 Frank Morgner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* @file
*/
#ifndef _CCID_TYPES_H
#define _CCID_TYPES_H
#include "pico/types.h"
#include "hardware/structs/usb.h"
#define USB_REQ_CCID 0xA1
#define CCID_CONTROL_ABORT 0x01
#define CCID_CONTROL_GET_CLOCK_FREQUENCIES 0x02
#define CCID_CONTROL_GET_DATA_RATES 0x03
#define CCID_OPERATION_VERIFY 0x00;
#define CCID_OPERATION_MODIFY 0x01;
#define CCID_ENTRY_VALIDATE 0x02
#define CCID_BERROR_CMD_ABORTED 0xff /** Host aborted the current activity */
#define CCID_BERROR_ICC_MUTE 0xfe /** CCID timed out while talking to the ICC */
#define CCID_BERROR_XFR_PARITY_ERROR 0xfd /** Parity error while talking to the ICC */
#define CCID_BERROR_XFR_OVERRUN 0xfc /** Overrun error while talking to the ICC */
#define CCID_BERROR_HW_ERROR 0xfb /** An all inclusive hardware error occurred */
#define CCID_BERROR_BAD_ATR_TS 0xf
#define CCID_BERROR_BAD_ATR_TCK 0xf
#define CCID_BERROR_ICC_PROTOCOL_NOT_SUPPORTED 0xf6
#define CCID_BERROR_ICC_CLASS_NOT_SUPPORTED 0xf5
#define CCID_BERROR_PROCEDURE_BYTE_CONFLICT 0xf4
#define CCID_BERROR_DEACTIVATED_PROTOCOL 0xf3
#define CCID_BERROR_BUSY_WITH_AUTO_SEQUENCE 0xf2 /** Automatic Sequence Ongoing */
#define CCID_BERROR_PIN_TIMEOUT 0xf0
#define CCID_BERROR_PIN_CANCELLED 0xef
#define CCID_BERROR_CMD_SLOT_BUSY 0xe0 /** A second command was sent to a slot which was already processing a command. */
#define CCID_BERROR_CMD_NOT_SUPPORTED 0x00
#define CCID_BERROR_OK 0x00
#define CCID_BSTATUS_OK_ACTIVE 0x00 /** No error. An ICC is present and active */
#define CCID_BSTATUS_OK_INACTIVE 0x01 /** No error. ICC is present and inactive */
#define CCID_BSTATUS_OK_NOICC 0x02 /** No error. No ICC is present */
#define CCID_BSTATUS_ERROR_ACTIVE 0x40 /** Failed. An ICC is present and active */
#define CCID_BSTATUS_ERROR_INACTIVE 0x41 /** Failed. ICC is present and inactive */
#define CCID_BSTATUS_ERROR_NOICC 0x42 /** Failed. No ICC is present */
#define CCID_WLEVEL_DIRECT __constant_cpu_to_le16(0) /** APDU begins and ends with this command */
#define CCID_WLEVEL_CHAIN_NEXT_XFRBLOCK __constant_cpu_to_le16(1) /** APDU begins with this command, and continue in the next PC_to_RDR_XfrBlock */
#define CCID_WLEVEL_CHAIN_END __constant_cpu_to_le16(2) /** abData field continues a command APDU and ends the APDU command */
#define CCID_WLEVEL_CHAIN_CONTINUE __constant_cpu_to_le16(3) /** abData field continues a command APDU and another block is to follow */
#define CCID_WLEVEL_RESPONSE_IN_DATABLOCK __constant_cpu_to_le16(0x10) /** empty abData field, continuation of response APDU is expected in the next RDR_to_PC_DataBlock */
#define CCID_PIN_ENCODING_BIN 0x00
#define CCID_PIN_ENCODING_BCD 0x01
#define CCID_PIN_ENCODING_ASCII 0x02
#define CCID_PIN_UNITS_BYTES 0x80
#define CCID_PIN_JUSTIFY_RIGHT 0x04
#define CCID_PIN_CONFIRM_NEW 0x01
#define CCID_PIN_INSERT_OLD 0x02
#define CCID_PIN_NO_MSG 0x00
#define CCID_PIN_MSG1 0x01
#define CCID_PIN_MSG2 0x02
#define CCID_PIN_MSG_REF 0x03
#define CCID_PIN_MSG_DEFAULT 0xff
#define CCID_SLOTS_UNCHANGED 0x00
#define CCID_SLOT1_CARD_PRESENT 0x01
#define CCID_SLOT1_CHANGED 0x02
#define CCID_SLOT2_CARD_PRESENT 0x04
#define CCID_SLOT2_CHANGED 0x08
#define CCID_SLOT3_CARD_PRESENT 0x10
#define CCID_SLOT3_CHANGED 0x20
#define CCID_SLOT4_CARD_PRESENT 0x40
#define CCID_SLOT4_CHANGED 0x80
#define CCID_EXT_APDU_MAX (4 + 3 + 0xffff + 3)
#define CCID_SHORT_APDU_MAX (4 + 1 + 0xff + 1)
typedef struct TU_ATTR_PACKED {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdCCID;
uint8_t bMaxSlotIndex;
uint8_t bVoltageSupport;
uint32_t dwProtocols;
uint32_t dwDefaultClock;
uint32_t dwMaximumClock;
uint8_t bNumClockSupport;
uint32_t dwDataRate;
uint32_t dwMaxDataRate;
uint8_t bNumDataRatesSupported;
uint32_t dwMaxIFSD;
uint32_t dwSynchProtocols;
uint32_t dwMechanical;
uint32_t dwFeatures;
uint32_t dwMaxCCIDMessageLength;
uint8_t bClassGetResponse;
uint8_t bclassEnvelope;
uint16_t wLcdLayout;
uint8_t bPINSupport;
uint8_t bMaxCCIDBusySlots;
} class_desc_ccid_t;
struct abProtocolDataStructure_T0 {
uint8_t bmFindexDindex;
uint8_t bmTCCKST0;
uint8_t bGuardTimeT0;
uint8_t bWaitingIntegerT0;
uint8_t bClockStop;
} __packed;
struct abProtocolDataStructure_T1 {
uint8_t bmFindexDindex;
uint8_t bmTCCKST1;
uint8_t bGuardTimeT1;
uint8_t bWaitingIntegersT1;
uint8_t bClockStop;
uint8_t bIFSC;
uint8_t bNadValue;
} __packed;
struct abPINDataStucture_Verification {
uint8_t bTimeOut;
uint8_t bmFormatString;
uint8_t bmPINBlockString;
uint8_t bmPINLengthFormat;
uint16_t wPINMaxExtraDigit;
uint8_t bEntryValidationCondition;
uint8_t bNumberMessage;
uint16_t wLangId;
uint8_t bMsgIndex;
uint8_t bTeoPrologue1;
uint16_t bTeoPrologue2;
} __packed;
struct abPINDataStucture_Modification {
uint8_t bTimeOut;
uint8_t bmFormatString;
uint8_t bmPINBlockString;
uint8_t bmPINLengthFormat;
uint8_t bInsertionOffsetOld;
uint8_t bInsertionOffsetNew;
uint16_t wPINMaxExtraDigit;
uint8_t bConfirmPIN;
uint8_t bEntryValidationCondition;
uint8_t bNumberMessage;
uint16_t wLangId;
uint8_t bMsgIndex1;
} __packed;
struct PC_to_RDR_XfrBlock {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bBWI;
uint16_t wLevelParameter;
} __packed;
struct PC_to_RDR_IccPowerOff {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t abRFU1;
uint16_t abRFU2;
} __packed;
struct PC_to_RDR_GetSlotStatus {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t abRFU1;
uint16_t abRFU2;
} __packed;
struct PC_to_RDR_GetParameters {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t abRFU1;
uint16_t abRFU2;
} __packed;
struct PC_to_RDR_ResetParameters {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t abRFU1;
uint16_t abRFU2;
} __packed;
struct PC_to_RDR_SetParameters {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bProtocolNum;
uint16_t abRFU;
} __packed;
struct PC_to_RDR_Secure {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bBWI;
uint16_t wLevelParameter;
} __packed;
struct PC_to_RDR_IccPowerOn {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bPowerSelect;
uint16_t abRFU;
} __packed;
struct RDR_to_PC_SlotStatus {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bStatus;
uint8_t bError;
uint8_t bClockStatus;
} __packed;
struct RDR_to_PC_DataBlock {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bStatus;
uint8_t bError;
uint8_t bChainParameter;
} __packed;
struct RDR_to_PC_Parameters {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bStatus;
uint8_t bError;
uint8_t bProtocolNum;
} __packed;
struct RDR_to_PC_NotifySlotChange {
uint8_t bMessageType;
uint8_t bmSlotICCState; /* we support 1 slots, so we need 2*1 bits = 1 byte */
} __packed;
#endif