Switching to new style.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2023-02-15 00:10:35 +01:00
parent e7495d11f2
commit cd6e280f4f
33 changed files with 1067 additions and 642 deletions

View File

@@ -78,9 +78,8 @@ extern int cmd_pso();
extern const uint8_t *ccid_atr;
app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len)
{
if (!memcmp(aid, sc_hsm_aid+1, MIN(aid_len, sc_hsm_aid[0]))) {
app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) {
if (!memcmp(aid, sc_hsm_aid + 1, MIN(aid_len, sc_hsm_aid[0]))) {
a->aid = sc_hsm_aid;
a->process_apdu = sc_hsm_process_apdu;
a->unload = sc_hsm_unload;
@@ -90,14 +89,12 @@ app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len)
return NULL;
}
void __attribute__((constructor)) sc_hsm_ctor()
{
void __attribute__((constructor)) sc_hsm_ctor() {
ccid_atr = atr_sc_hsm;
register_app(sc_hsm_select_aid);
}
void scan_files()
{
void scan_files() {
file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF);
if (file_pin1) {
if (!file_pin1->data) {
@@ -105,7 +102,8 @@ void scan_files()
const uint8_t empty[33] = { 0 };
flash_write_data_to_file(file_pin1, empty, sizeof(empty));
}
} else {
}
else {
printf("FATAL ERROR: PIN1 not found in memory!\r\n");
}
file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF);
@@ -115,7 +113,8 @@ void scan_files()
const uint8_t empty[33] = { 0 };
flash_write_data_to_file(file_sopin, empty, sizeof(empty));
}
} else {
}
else {
printf("FATAL ERROR: SOPIN not found in memory!\r\n");
}
file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF);
@@ -125,7 +124,8 @@ void scan_files()
const uint8_t retries = 3;
flash_write_data_to_file(file_retries_pin1, &retries, sizeof(uint8_t));
}
} else {
}
else {
printf("FATAL ERROR: Retries PIN1 not found in memory!\r\n");
}
file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF);
@@ -135,7 +135,8 @@ void scan_files()
const uint8_t retries = 15;
flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t));
}
} else {
}
else {
printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
}
file_t *tf = NULL;
@@ -147,7 +148,8 @@ void scan_files()
const uint8_t retries = 3;
flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
}
} else {
}
else {
printf("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n");
}
tf = search_by_fid(0x1089, NULL, SPECIFY_EF);
@@ -157,14 +159,14 @@ void scan_files()
const uint8_t retries = 15;
flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
}
} else {
}
else {
printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
}
low_flash_available();
}
void scan_all()
{
void scan_all() {
scan_flash();
scan_files();
}
@@ -174,8 +176,7 @@ int puk_store_entries = 0;
PUK *current_puk = NULL;
uint8_t puk_status[MAX_PUK];
int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy)
{
int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy) {
if (data == NULL || data_len == 0) {
return CCID_ERR_NULL_PARAM;
}
@@ -188,7 +189,8 @@ int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy)
uint8_t *tmp = (uint8_t *) calloc(data_len, sizeof(uint8_t));
memcpy(tmp, data, data_len);
puk_store[puk_store_entries].cvcert = tmp;
} else {
}
else {
puk_store[puk_store_entries].cvcert = data;
}
puk_store[puk_store_entries].cvcert_len = data_len;
@@ -206,8 +208,7 @@ int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy)
return CCID_OK;
}
int puk_store_select_chr(const uint8_t *chr)
{
int puk_store_select_chr(const uint8_t *chr) {
for (int i = 0; i < puk_store_entries; i++) {
if (memcmp(puk_store[i].chr, chr, puk_store[i].chr_len) == 0) {
current_puk = &puk_store[i];
@@ -217,8 +218,7 @@ int puk_store_select_chr(const uint8_t *chr)
return CCID_ERR_FILE_NOT_FOUND;
}
void init_sc_hsm()
{
void init_sc_hsm() {
scan_all();
has_session_pin = has_session_sopin = false;
isUserAuthenticated = false;
@@ -246,27 +246,24 @@ void init_sc_hsm()
memset(puk_status, 0, sizeof(puk_status));
}
int sc_hsm_unload()
{
int sc_hsm_unload() {
has_session_pin = has_session_sopin = false;
isUserAuthenticated = false;
sm_session_pin_len = 0;
return CCID_OK;
}
uint16_t get_device_options()
{
uint16_t get_device_options() {
file_t *ef = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
if (file_has_data(ef)) {
return (file_read_uint8(file_get_data(ef)) << 8) | file_read_uint8(file_get_data(ef)+1);
return (file_read_uint8(file_get_data(ef)) << 8) | file_read_uint8(file_get_data(ef) + 1);
}
return 0x0;
}
extern uint32_t board_button_read(void);
bool wait_button_pressed()
{
bool wait_button_pressed() {
uint32_t val = EV_PRESS_BUTTON;
#ifndef ENABLE_EMULATION
uint16_t opts = get_device_options();
@@ -280,8 +277,7 @@ bool wait_button_pressed()
return val == EV_BUTTON_TIMEOUT;
}
int parse_token_info(const file_t *f, int mode)
{
int parse_token_info(const file_t *f, int mode) {
char *label = "SmartCard-HSM";
char *manu = "Pol Henarejos";
if (mode == 1) {
@@ -297,19 +293,18 @@ int parse_token_info(const file_t *f, int mode)
*p++ = 0xC; *p++ = strlen(manu); strcpy((char *) p, manu); p += strlen(manu);
*p++ = 0x80; *p++ = strlen(label); strcpy((char *) p, label); p += strlen(label);
*p++ = 0x3; *p++ = 2; *p++ = 4; *p++ = 0x30;
res_APDU_size = p-res_APDU;
res_APDU[1] = res_APDU_size-2;
res_APDU_size = p - res_APDU;
res_APDU[1] = res_APDU_size - 2;
}
return 2+(2+1)+(2+8)+(2+strlen(manu))+(2+strlen(label))+(2+2);
return 2 + (2 + 1) + (2 + 8) + (2 + strlen(manu)) + (2 + strlen(label)) + (2 + 2);
}
int pin_reset_retries(const file_t *pin, bool force)
{
int pin_reset_retries(const file_t *pin, bool force) {
if (!pin) {
return CCID_ERR_NULL_PARAM;
}
const file_t *max = search_by_fid(pin->fid+1, NULL, SPECIFY_EF);
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
const file_t *max = search_by_fid(pin->fid + 1, NULL, SPECIFY_EF);
const file_t *act = search_by_fid(pin->fid + 2, NULL, SPECIFY_EF);
if (!max || !act) {
return CCID_ERR_FILE_NOT_FOUND;
}
@@ -323,12 +318,11 @@ int pin_reset_retries(const file_t *pin, bool force)
return r;
}
int pin_wrong_retry(const file_t *pin)
{
int pin_wrong_retry(const file_t *pin) {
if (!pin) {
return CCID_ERR_NULL_PARAM;
}
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
const file_t *act = search_by_fid(pin->fid + 2, NULL, SPECIFY_EF);
if (!act) {
return CCID_ERR_FILE_NOT_FOUND;
}
@@ -348,14 +342,12 @@ int pin_wrong_retry(const file_t *pin)
return CCID_ERR_BLOCKED;
}
bool pka_enabled()
{
bool pka_enabled() {
file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF);
return file_has_data(ef_puk) && file_read_uint8(file_get_data(ef_puk)) > 0;
}
int check_pin(const file_t *pin, const uint8_t *data, size_t len)
{
int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
if (!file_has_data((file_t *) pin)) {
return SW_REFERENCE_NOT_FOUND();
}
@@ -371,13 +363,14 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len)
}
return set_res_sw(0x63, 0xc0 | retries);
}
} else {
}
else {
uint8_t dhash[32];
double_hash_pin(data, len, dhash);
if (sizeof(dhash) != file_get_size(pin)-1) { //1 byte for pin len
if (sizeof(dhash) != file_get_size(pin) - 1) { //1 byte for pin len
return SW_CONDITIONS_NOT_SATISFIED();
}
if (memcmp(file_get_data(pin)+1, dhash, sizeof(dhash)) != 0) {
if (memcmp(file_get_data(pin) + 1, dhash, sizeof(dhash)) != 0) {
int retries;
if ((retries = pin_wrong_retry(pin)) < CCID_OK) {
return SW_PIN_BLOCKED();
@@ -398,15 +391,15 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len)
if (pin == file_pin1) {
hash_multi(data, len, session_pin);
has_session_pin = true;
} else if (pin == file_sopin) {
}
else if (pin == file_sopin) {
hash_multi(data, len, session_sopin);
has_session_sopin = true;
}
return SW_OK();
}
const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len)
{
const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) {
if (ef == NULL) {
return NULL;
}
@@ -424,8 +417,7 @@ const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len)
return NULL;
}
uint32_t get_key_counter(file_t *fkey)
{
uint32_t get_key_counter(file_t *fkey) {
size_t tag_len = 0;
const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len);
if (meta_tag) {
@@ -434,8 +426,7 @@ uint32_t get_key_counter(file_t *fkey)
return 0xffffffff;
}
bool key_has_purpose(file_t *ef, uint8_t purpose)
{
bool key_has_purpose(file_t *ef, uint8_t purpose) {
size_t tag_len = 0;
const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len);
if (meta_tag) {
@@ -449,8 +440,7 @@ bool key_has_purpose(file_t *ef, uint8_t purpose)
return true;
}
uint32_t decrement_key_counter(file_t *fkey)
{
uint32_t decrement_key_counter(file_t *fkey) {
if (!fkey) {
return 0xffffff;
}
@@ -488,31 +478,35 @@ uint32_t decrement_key_counter(file_t *fkey)
}
//Stores the private and public keys in flash
int store_keys(void *key_ctx, int type, uint8_t key_id)
{
int store_keys(void *key_ctx, int type, uint8_t key_id) {
int r, key_size = 0;
uint8_t kdata[4096/8]; //worst case
uint8_t kdata[4096 / 8]; //worst case
if (type == HSM_KEY_RSA) {
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
key_size = mbedtls_mpi_size(&rsa->P)+mbedtls_mpi_size(&rsa->Q);
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 == HSM_KEY_EC) {
key_size = mbedtls_mpi_size(&rsa->P) + mbedtls_mpi_size(&rsa->Q);
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 == HSM_KEY_EC) {
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
key_size = mbedtls_mpi_size(&ecdsa->d);
kdata[0] = ecdsa->grp.id & 0xff;
mbedtls_mpi_write_binary(&ecdsa->d, kdata+1, key_size);
mbedtls_mpi_write_binary(&ecdsa->d, kdata + 1, key_size);
key_size++;
} else if (type & HSM_KEY_AES) {
}
else if (type & HSM_KEY_AES) {
if (type == HSM_KEY_AES_128) {
key_size = 16;
} else if (type == HSM_KEY_AES_192) {
}
else if (type == HSM_KEY_AES_192) {
key_size = 24;
} else if (type == HSM_KEY_AES_256) {
}
else if (type == HSM_KEY_AES_256) {
key_size = 32;
}
memcpy(kdata, key_ctx, key_size);
} else {
}
else {
return CCID_WRONG_DATA;
}
file_t *fpk = file_new((KEY_PREFIX << 8) | key_id);
@@ -531,18 +525,17 @@ int store_keys(void *key_ctx, int type, uint8_t key_id)
return CCID_OK;
}
int find_and_store_meta_key(uint8_t key_id)
{
int find_and_store_meta_key(uint8_t key_id) {
size_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0;
uint8_t *pt[4] = { NULL, NULL, NULL, NULL };
uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE };
for (int t = 0; t < 4; t++) {
uint8_t *ptt = NULL;
size_t ltt = 0;
if (asn1_find_tag(apdu.data, apdu.nc, 0x90+t, &ltt, &ptt) && ptt != NULL && ltt > 0) {
if (asn1_find_tag(apdu.data, apdu.nc, 0x90 + t, &ltt, &ptt) && ptt != NULL && ltt > 0) {
lt[t] = ltt;
pt[t] = ptt;
meta_size += asn1_len_tag(0x90+t, lt[t]);
meta_size += asn1_len_tag(0x90 + t, lt[t]);
}
}
if (lt[0] == 0 && pt[0] == NULL) {
@@ -557,7 +550,7 @@ int find_and_store_meta_key(uint8_t key_id)
uint8_t *meta = (uint8_t *) calloc(1, meta_size), *m = meta;
for (int t = 0; t < 4; t++) {
if (lt[t] > 0 && pt[t] != NULL) {
*m++ = 0x90+t;
*m++ = 0x90 + t;
m += format_tlv_len(lt[t], m);
memcpy(m, pt[t], lt[t]);
m += lt[t];
@@ -572,24 +565,23 @@ int find_and_store_meta_key(uint8_t key_id)
return CCID_OK;
}
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey)
{
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
if (wait_button_pressed() == true) { //timeout
return CCID_VERIFICATION_FAILED;
}
int key_size = file_get_size(fkey);
uint8_t kdata[4096/8];
uint8_t kdata[4096 / 8];
memcpy(kdata, file_get_data(fkey), key_size);
if (mkek_decrypt(kdata, key_size) != 0) {
return CCID_EXEC_ERROR;
}
if (mbedtls_mpi_read_binary(&ctx->P, kdata, key_size/2) != 0) {
if (mbedtls_mpi_read_binary(&ctx->P, kdata, key_size / 2) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_WRONG_DATA;
}
if (mbedtls_mpi_read_binary(&ctx->Q, kdata+key_size/2, key_size/2) != 0) {
if (mbedtls_mpi_read_binary(&ctx->Q, kdata + key_size / 2, key_size / 2) != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_rsa_free(ctx);
return CCID_WRONG_DATA;
@@ -617,8 +609,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey)
return CCID_OK;
}
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey)
{
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
if (wait_button_pressed() == true) { //timeout
return CCID_VERIFICATION_FAILED;
}
@@ -630,7 +621,7 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey)
return CCID_EXEC_ERROR;
}
mbedtls_ecp_group_id gid = kdata[0];
int r = mbedtls_ecp_read_key(gid, ctx, kdata+1, key_size-1);
int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1);
if (r != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_ecdsa_free(ctx);
@@ -699,8 +690,7 @@ static const cmd_t cmds[] = {
{ 0x00, 0x0 }
};
int sc_hsm_process_apdu()
{
int sc_hsm_process_apdu() {
int r = sm_unwrap();
if (r != CCID_OK) {
return SW_DATA_INVALID();