Splitting the core onto another repo, which can be reused by other smart applications.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -85,7 +85,7 @@ int aes_encrypt(const uint8_t *key, const uint8_t *iv, int key_size, int mode, u
|
||||
memcpy(tmp_iv, iv, IV_SIZE);
|
||||
int r = mbedtls_aes_setkey_enc(&aes, key, key_size);
|
||||
if (r != 0)
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
if (mode == HSM_AES_MODE_CBC)
|
||||
return mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, len, tmp_iv, data, data);
|
||||
return mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_ENCRYPT, len, &iv_offset, tmp_iv, data, data);
|
||||
@@ -101,7 +101,7 @@ int aes_decrypt(const uint8_t *key, const uint8_t *iv, int key_size, int mode, u
|
||||
memcpy(tmp_iv, iv, IV_SIZE);
|
||||
int r = mbedtls_aes_setkey_dec(&aes, key, key_size);
|
||||
if (r != 0)
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
if (mode == HSM_AES_MODE_CBC)
|
||||
return mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, len, tmp_iv, data, data);
|
||||
r = mbedtls_aes_setkey_enc(&aes, key, key_size); //CFB requires set_enc instead set_dec
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "mbedtls/cmac.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "files.h"
|
||||
|
||||
static uint8_t dkek[IV_SIZE+32];
|
||||
static uint8_t tmp_dkek[32];
|
||||
@@ -35,15 +36,15 @@ extern uint8_t session_pin[32];
|
||||
|
||||
int load_dkek() {
|
||||
if (has_session_pin == false)
|
||||
return HSM_NO_LOGIN;
|
||||
return CCID_NO_LOGIN;
|
||||
file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF);
|
||||
if (!tf)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
memcpy(dkek, file_read(tf->data+sizeof(uint16_t)), IV_SIZE+32);
|
||||
int ret = aes_decrypt_cfb_256(session_pin, dkek, dkek+IV_SIZE, 32);
|
||||
if (ret != 0)
|
||||
return HSM_EXEC_ERROR;
|
||||
return HSM_OK;
|
||||
return CCID_EXEC_ERROR;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
void release_dkek() {
|
||||
@@ -59,11 +60,11 @@ int store_dkek_key() {
|
||||
aes_encrypt_cfb_256(session_pin, dkek, dkek+IV_SIZE, 32);
|
||||
file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF);
|
||||
if (!tf)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
flash_write_data_to_file(tf, dkek, sizeof(dkek));
|
||||
low_flash_available();
|
||||
release_dkek();
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int save_dkek_key(const uint8_t *key) {
|
||||
@@ -83,43 +84,43 @@ void import_dkek_share(const uint8_t *share) {
|
||||
int dkek_kcv(uint8_t *kcv) { //kcv 8 bytes
|
||||
uint8_t hsh[32];
|
||||
int r = load_dkek();
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
hash256(dkek+IV_SIZE, 32, hsh);
|
||||
release_dkek();
|
||||
memcpy(kcv, hsh, 8);
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_kenc(uint8_t *kenc) { //kenc 32 bytes
|
||||
uint8_t buf[32+4];
|
||||
int r = load_dkek();
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
memcpy(buf, dkek+IV_SIZE, 32);
|
||||
release_dkek();
|
||||
memcpy(buf+32, "\x0\x0\x0\x1", 4);
|
||||
hash256(buf, sizeof(buf), kenc);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_kmac(uint8_t *kmac) { //kmac 32 bytes
|
||||
uint8_t buf[32+4];
|
||||
int r = load_dkek();
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
memcpy(buf, dkek+IV_SIZE, 32);
|
||||
release_dkek();
|
||||
memcpy(buf+32, "\x0\x0\x0\x2", 4);
|
||||
hash256(buf, sizeof(buf), kmac);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_encrypt(uint8_t *data, size_t len) {
|
||||
int r;
|
||||
if ((r = load_dkek()) != HSM_OK)
|
||||
if ((r = load_dkek()) != CCID_OK)
|
||||
return r;
|
||||
r = aes_encrypt_cfb_256(dkek+IV_SIZE, dkek, data, len);
|
||||
release_dkek();
|
||||
@@ -128,7 +129,7 @@ int dkek_encrypt(uint8_t *data, size_t len) {
|
||||
|
||||
int dkek_decrypt(uint8_t *data, size_t len) {
|
||||
int r;
|
||||
if ((r = load_dkek()) != HSM_OK)
|
||||
if ((r = load_dkek()) != CCID_OK)
|
||||
return r;
|
||||
r = aes_decrypt_cfb_256(dkek+IV_SIZE, dkek, data, len);
|
||||
release_dkek();
|
||||
@@ -137,7 +138,7 @@ int dkek_decrypt(uint8_t *data, size_t len) {
|
||||
|
||||
int dkek_encode_key(void *key_ctx, int key_type, uint8_t *out, size_t *out_len) {
|
||||
if (!(key_type & HSM_KEY_RSA) && !(key_type & HSM_KEY_EC) && !(key_type & HSM_KEY_AES))
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
|
||||
uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes padding)
|
||||
memset(kb, 0, sizeof(kb));
|
||||
@@ -167,9 +168,9 @@ int dkek_encode_key(void *key_ctx, int key_type, uint8_t *out, size_t *out_len)
|
||||
kb_len = 32;
|
||||
|
||||
if (kb_len != 16 && kb_len != 24 && kb_len != 32)
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
if (*out_len < 8+1+10+6+4+(2+32+14)+16)
|
||||
return HSM_WRONG_LENGTH;
|
||||
return CCID_WRONG_LENGTH;
|
||||
|
||||
put_uint16_t(kb_len, kb+8);
|
||||
memcpy(kb+10, key_ctx, kb_len);
|
||||
@@ -182,7 +183,7 @@ int dkek_encode_key(void *key_ctx, int key_type, uint8_t *out, size_t *out_len)
|
||||
}
|
||||
else if (key_type & HSM_KEY_RSA) {
|
||||
if (*out_len < 8+1+12+6+(8+2*4+2*4096/8+3+13)+16) //13 bytes pading
|
||||
return HSM_WRONG_LENGTH;
|
||||
return CCID_WRONG_LENGTH;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *)key_ctx;
|
||||
kb_len = 0;
|
||||
put_uint16_t(mbedtls_rsa_get_len(rsa)*8, kb+8+kb_len); kb_len += 2;
|
||||
@@ -199,7 +200,7 @@ int dkek_encode_key(void *key_ctx, int key_type, uint8_t *out, size_t *out_len)
|
||||
}
|
||||
else if (key_type & HSM_KEY_EC) {
|
||||
if (*out_len < 8+1+12+6+(8+2*8+9*66+2+4)+16) //4 bytes pading
|
||||
return HSM_WRONG_LENGTH;
|
||||
return CCID_WRONG_LENGTH;
|
||||
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)key_ctx;
|
||||
kb_len = 0;
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P)*8, kb+8+kb_len); kb_len += 2;
|
||||
@@ -265,7 +266,7 @@ int dkek_encode_key(void *key_ctx, int key_type, uint8_t *out, size_t *out_len)
|
||||
kb[kb_len] = 0x80;
|
||||
}
|
||||
int r = aes_encrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, kb_len_pad);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
|
||||
memcpy(out+*out_len, kb, kb_len_pad);
|
||||
@@ -276,7 +277,7 @@ int dkek_encode_key(void *key_ctx, int key_type, uint8_t *out, size_t *out_len)
|
||||
*out_len += 16;
|
||||
if (r != 0)
|
||||
return r;
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_type_key(const uint8_t *in) {
|
||||
@@ -303,27 +304,27 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
dkek_kenc(kenc);
|
||||
|
||||
if (memcmp(kcv, in, 8) != 0)
|
||||
return HSM_WRONG_DKEK;
|
||||
return CCID_WRONG_DKEK;
|
||||
|
||||
uint8_t signature[16];
|
||||
int r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), kmac, 256, in, in_len-16, signature);
|
||||
if (r != 0)
|
||||
return HSM_WRONG_SIGNATURE;
|
||||
return CCID_WRONG_SIGNATURE;
|
||||
if (memcmp(signature, in+in_len-16, 16) != 0)
|
||||
return HSM_WRONG_SIGNATURE;
|
||||
return CCID_WRONG_SIGNATURE;
|
||||
|
||||
int key_type = in[8];
|
||||
if (key_type != 5 && key_type != 6 && key_type != 12 && key_type != 15)
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
|
||||
if ((key_type == 5 || key_type == 6) && memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02", 12) != 0)
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
|
||||
if (key_type == 12 && memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03", 12) != 0)
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
|
||||
if (key_type == 15 && memcmp(in+9, "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01", 10) != 0)
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
|
||||
size_t ofs = 9;
|
||||
|
||||
@@ -344,12 +345,12 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
ofs += len+2;
|
||||
|
||||
if ((in_len-16-ofs) % 16 != 0)
|
||||
return HSM_WRONG_PADDING;
|
||||
return CCID_WRONG_PADDING;
|
||||
uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes padding)
|
||||
memset(kb, 0, sizeof(kb));
|
||||
memcpy(kb, in+ofs, in_len-16-ofs);
|
||||
r = aes_decrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, in_len-16-ofs);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
|
||||
int key_size = get_uint16_t(kb, 8);
|
||||
@@ -364,14 +365,14 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
r = mbedtls_mpi_read_binary(&rsa->D, kb+ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
r = mbedtls_mpi_read_binary(&rsa->N, kb+ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
}
|
||||
else if (key_type == 6) {
|
||||
@@ -385,7 +386,7 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
r = mbedtls_mpi_read_binary(&rsa->P, kb+ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
//PQ
|
||||
@@ -395,7 +396,7 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
r = mbedtls_mpi_read_binary(&rsa->Q, kb+ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
//N
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
@@ -405,33 +406,33 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
r = mbedtls_mpi_read_binary(&rsa->E, kb+ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
if (key_type == 5) {
|
||||
r = mbedtls_rsa_import(rsa, &rsa->N, NULL, NULL, &rsa->D, &rsa->E);
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
}
|
||||
else if (key_type == 6) {
|
||||
r = mbedtls_rsa_import(rsa, NULL, &rsa->P, &rsa->Q, NULL, &rsa->E);
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
r = mbedtls_rsa_complete(rsa);
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
r = mbedtls_rsa_check_privkey(rsa);
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
}
|
||||
else if (key_type == 12) {
|
||||
@@ -449,7 +450,7 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(kb+ofs, len);
|
||||
if (ec_id == MBEDTLS_ECP_DP_NONE) {
|
||||
mbedtls_ecdsa_free(ecdsa);
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
ofs += len;
|
||||
|
||||
@@ -464,11 +465,11 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len, int *key_si
|
||||
r = mbedtls_ecp_read_key(ec_id, ecdsa, kb+ofs, len);
|
||||
if (r != 0) {
|
||||
mbedtls_ecdsa_free(ecdsa);
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
}
|
||||
else if (key_type == 15) {
|
||||
memcpy(key_ctx, kb+ofs, key_size);
|
||||
}
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
@@ -83,9 +83,9 @@ int sm_sign(uint8_t *in, size_t in_len, uint8_t *out) {
|
||||
int sm_unwrap() {
|
||||
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
|
||||
if (sm_indicator == 0)
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
int r = sm_verify();
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
int le = sm_get_le();
|
||||
if (le >= 0)
|
||||
@@ -106,22 +106,22 @@ int sm_unwrap() {
|
||||
}
|
||||
}
|
||||
if (!body)
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
if (is87 && *body++ != 0x1) {
|
||||
return HSM_WRONG_PADDING;
|
||||
return CCID_WRONG_PADDING;
|
||||
}
|
||||
sm_update_iv();
|
||||
aes_decrypt(sm_kenc, sm_iv, 128, HSM_AES_MODE_CBC, body, body_size);
|
||||
memmove(apdu.cmd_apdu_data, body, body_size);
|
||||
apdu.cmd_apdu_data_len = sm_remove_padding(apdu.cmd_apdu_data, body_size);
|
||||
DEBUG_PAYLOAD(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int sm_wrap() {
|
||||
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
|
||||
if (sm_indicator == 0)
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
uint8_t input[1024];
|
||||
size_t input_len = 0;
|
||||
memset(input, 0, sizeof(input));
|
||||
@@ -176,7 +176,7 @@ int sm_wrap() {
|
||||
res_APDU_size += 8;
|
||||
if (apdu.expected_res_size > 0)
|
||||
apdu.expected_res_size = res_APDU_size;
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int sm_get_le() {
|
||||
@@ -210,7 +210,7 @@ int sm_verify() {
|
||||
if (data_len % sm_blocksize)
|
||||
data_len += sm_blocksize;
|
||||
if (data_len+(add_header ? sm_blocksize : 0) > 1024)
|
||||
return HSM_WRONG_LENGTH;
|
||||
return CCID_WRONG_LENGTH;
|
||||
mbedtls_mpi ssc;
|
||||
mbedtls_mpi_init(&ssc);
|
||||
mbedtls_mpi_add_int(&ssc, &sm_mSSC, 1);
|
||||
@@ -219,7 +219,7 @@ int sm_verify() {
|
||||
input_len += sm_blocksize;
|
||||
mbedtls_mpi_free(&ssc);
|
||||
if (r != 0)
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
if (add_header) {
|
||||
input[input_len++] = CLA(apdu);
|
||||
input[input_len++] = INS(apdu);
|
||||
@@ -248,7 +248,7 @@ int sm_verify() {
|
||||
}
|
||||
}
|
||||
if (!mac)
|
||||
return HSM_WRONG_DATA;
|
||||
return CCID_WRONG_DATA;
|
||||
if (some_added) {
|
||||
input[input_len++] = 0x80;
|
||||
input_len += (sm_blocksize - (input_len%sm_blocksize));
|
||||
@@ -256,10 +256,10 @@ int sm_verify() {
|
||||
uint8_t signature[16];
|
||||
r = sm_sign(input, input_len, signature);
|
||||
if (r != 0)
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
if (memcmp(signature, mac, mac_len) == 0)
|
||||
return HSM_OK;
|
||||
return HSM_VERIFICATION_FAILED;
|
||||
return CCID_OK;
|
||||
return CCID_VERIFICATION_FAILED;
|
||||
}
|
||||
|
||||
int sm_remove_padding(const uint8_t *data, size_t data_len) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hsm2040.h"
|
||||
#include "ccid2040.h"
|
||||
|
||||
typedef enum MSE_protocol {
|
||||
MSE_AES = 0,
|
||||
|
||||
60
src/hsm/files.c
Normal file
60
src/hsm/files.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "files.h"
|
||||
|
||||
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
|
||||
/* 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
|
||||
/* 7 */ { .fid = 0x5032 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo
|
||||
/* 8 */ { .fid = 0x5033 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.UnusedSpace
|
||||
/* 9 */ { .fid = 0x1081 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (PIN1)
|
||||
/* 10 */ { .fid = 0x1082 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (PIN1)
|
||||
/* 11 */ { .fid = 0x1083 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (PIN1)
|
||||
/* 12 */ { .fid = 0x1088 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (SOPIN)
|
||||
/* 13 */ { .fid = 0x1089 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (SOPIN)
|
||||
/* 14 */ { .fid = 0x108A , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN)
|
||||
/* 15 */ { .fid = EF_DKEK , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //DKEK
|
||||
/* 16 */ { .fid = EF_DEVOPS , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Device options
|
||||
/* 17 */ { .fid = EF_PRKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs
|
||||
/* 18 */ { .fid = EF_PUKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs
|
||||
/* 19 */ { .fid = EF_CDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs
|
||||
/* 20 */ { .fid = EF_AODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs
|
||||
/* 21 */ { .fid = EF_DODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs
|
||||
/* 22 */ { .fid = EF_SKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs
|
||||
///* 23 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
|
||||
/* 24 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
|
||||
/* 25 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end
|
||||
};
|
||||
|
||||
const file_t *MF = &file_entries[0];
|
||||
const file_t *file_last = &file_entries[sizeof(file_entries)/sizeof(file_t)-1];
|
||||
const file_t *file_openpgp = &file_entries[sizeof(file_entries)/sizeof(file_t)-3];
|
||||
const file_t *file_sc_hsm = &file_entries[sizeof(file_entries)/sizeof(file_t)-2];
|
||||
file_t *file_pin1 = NULL;
|
||||
file_t *file_retries_pin1 = NULL;
|
||||
file_t *file_sopin = NULL;
|
||||
file_t *file_retries_sopin = NULL;
|
||||
38
src/hsm/files.h
Normal file
38
src/hsm/files.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FILES_H_
|
||||
#define _FILES_H_
|
||||
|
||||
#include "file.h"
|
||||
|
||||
#define EF_DKEK 0x108F
|
||||
#define EF_PRKDFS 0x6040
|
||||
#define EF_PUKDFS 0x6041
|
||||
#define EF_CDFS 0x6042
|
||||
#define EF_AODFS 0x6043
|
||||
#define EF_DODFS 0x6044
|
||||
#define EF_SKDFS 0x6045
|
||||
#define EF_DEVOPS 0x100E
|
||||
|
||||
extern file_t *file_pin1;
|
||||
extern file_t *file_retries_pin1;
|
||||
extern file_t *file_sopin;
|
||||
extern file_t *file_retries_sopin;
|
||||
|
||||
#endif
|
||||
1691
src/hsm/hsm2040.c
1691
src/hsm/hsm2040.c
File diff suppressed because it is too large
Load Diff
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _HSM2040_H_
|
||||
#define _HSM2040_H_
|
||||
|
||||
#include "ccid.h"
|
||||
#include "tusb.h"
|
||||
#include "file.h"
|
||||
#include "pico/unique_id.h"
|
||||
#include "pico/util/queue.h"
|
||||
|
||||
#define USB_REQ_CCID 0xA1
|
||||
|
||||
typedef struct app {
|
||||
const uint8_t *aid;
|
||||
int (*process_apdu)();
|
||||
struct app* (*select_aid)();
|
||||
int (*unload)();
|
||||
} app_t;
|
||||
|
||||
extern int register_app(app_t * (*)());
|
||||
|
||||
extern const uint8_t historical_bytes[];
|
||||
|
||||
#define DEBUG_PAYLOAD(p,s) { \
|
||||
printf("Payload %s (%d bytes):\r\n", #p,s);\
|
||||
for (int i = 0; i < s; i += 16) {\
|
||||
printf("%07Xh : ",i+p);\
|
||||
for (int j = 0; j < 16; j++) {\
|
||||
if (j < s-i) printf("%02X ",(p)[i+j]);\
|
||||
else printf(" ");\
|
||||
if (j == 7) printf(" ");\
|
||||
} printf(": "); \
|
||||
for (int j = 0; j < MIN(16,s-i); j++) {\
|
||||
printf("%c",(p)[i+j] == 0x0a || (p)[i+j] == 0x0d ? '\\' : (p)[i+j]);\
|
||||
if (j == 7) printf(" ");\
|
||||
}\
|
||||
printf("\r\n");\
|
||||
} printf("\r\n"); \
|
||||
}
|
||||
|
||||
struct apdu {
|
||||
uint8_t seq;
|
||||
|
||||
/* command APDU */
|
||||
uint8_t *cmd_apdu_head; /* CLS INS P1 P2 [ internal Lc ] */
|
||||
uint8_t *cmd_apdu_data;
|
||||
size_t cmd_apdu_data_len; /* Nc, calculated by Lc field */
|
||||
size_t expected_res_size; /* Ne, calculated by Le field */
|
||||
|
||||
/* response APDU */
|
||||
uint16_t sw;
|
||||
uint16_t res_apdu_data_len;
|
||||
uint8_t *res_apdu_data;
|
||||
};
|
||||
|
||||
#define MAX_CMD_APDU_DATA_SIZE (24+4+512*4)
|
||||
#define MAX_RES_APDU_DATA_SIZE (5+9+512*4)
|
||||
#define CCID_MSG_HEADER_SIZE 10
|
||||
#define USB_LL_BUF_SIZE 64
|
||||
|
||||
/* CCID thread */
|
||||
#define EV_CARD_CHANGE 1
|
||||
#define EV_TX_FINISHED 2 /* CCID Tx finished */
|
||||
#define EV_EXEC_ACK_REQUIRED 4 /* OpenPGPcard Execution ACK required */
|
||||
#define EV_EXEC_FINISHED 8 /* OpenPGPcard Execution finished */
|
||||
#define EV_RX_DATA_READY 16 /* USB Rx data available */
|
||||
#define EV_PRESS_BUTTON 32
|
||||
|
||||
/* SC HSM thread */
|
||||
#define EV_MODIFY_CMD_AVAILABLE 1
|
||||
#define EV_VERIFY_CMD_AVAILABLE 2
|
||||
#define EV_CMD_AVAILABLE 4
|
||||
#define EV_EXIT 8
|
||||
#define EV_BUTTON_PRESSED 16
|
||||
|
||||
//Variables set by core1
|
||||
extern queue_t *ccid_comm;
|
||||
extern queue_t *card_comm;
|
||||
|
||||
enum ccid_state {
|
||||
CCID_STATE_NOCARD, /* No card available */
|
||||
CCID_STATE_START, /* Initial */
|
||||
CCID_STATE_WAIT, /* Waiting APDU */
|
||||
|
||||
CCID_STATE_EXECUTE, /* Executing command */
|
||||
CCID_STATE_ACK_REQUIRED_0, /* Ack required (executing)*/
|
||||
CCID_STATE_ACK_REQUIRED_1, /* Waiting user's ACK (execution finished) */
|
||||
|
||||
CCID_STATE_EXITED, /* CCID Thread Terminated */
|
||||
CCID_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||
};
|
||||
|
||||
#define CLA(a) a.cmd_apdu_head[0]
|
||||
#define INS(a) a.cmd_apdu_head[1]
|
||||
#define P1(a) a.cmd_apdu_head[2]
|
||||
#define P2(a) a.cmd_apdu_head[3]
|
||||
|
||||
#define res_APDU apdu.res_apdu_data
|
||||
#define res_APDU_size apdu.res_apdu_data_len
|
||||
|
||||
extern struct apdu apdu;
|
||||
|
||||
uint16_t set_res_sw (uint8_t sw1, uint8_t sw2);
|
||||
|
||||
|
||||
static inline const uint16_t make_uint16_t(uint8_t b1, uint8_t b2) {
|
||||
return (b1 << 8) | b2;
|
||||
}
|
||||
static inline const uint16_t get_uint16_t(const uint8_t *b, uint16_t offset) {
|
||||
return make_uint16_t(b[offset], b[offset+1]);
|
||||
}
|
||||
static inline const void put_uint16_t(uint16_t n, uint8_t *b) {
|
||||
*b++ = (n >> 8) & 0xff;
|
||||
*b = n & 0xff;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void stdout_init (void);
|
||||
#define DEBUG_MORE 1
|
||||
/*
|
||||
* Debug functions in debug.c
|
||||
*/
|
||||
void put_byte (uint8_t b);
|
||||
void put_byte_with_no_nl (uint8_t b);
|
||||
void put_short (uint16_t x);
|
||||
void put_word (uint32_t x);
|
||||
void put_int (uint32_t x);
|
||||
void put_string (const char *s);
|
||||
void put_binary (const char *s, int len);
|
||||
|
||||
#define DEBUG_INFO(msg) put_string (msg)
|
||||
#define DEBUG_WORD(w) put_word (w)
|
||||
#define DEBUG_SHORT(h) put_short (h)
|
||||
#define DEBUG_BYTE(b) put_byte (b)
|
||||
#define DEBUG_BINARY(s,len) put_binary ((const char *)s,len)
|
||||
#else
|
||||
#define DEBUG_INFO(msg)
|
||||
#define DEBUG_WORD(w)
|
||||
#define DEBUG_SHORT(h)
|
||||
#define DEBUG_BYTE(b)
|
||||
#define DEBUG_BINARY(s,len)
|
||||
#endif
|
||||
|
||||
extern int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len);
|
||||
extern void low_flash_available();
|
||||
extern int flash_clear_file(file_t *file);
|
||||
|
||||
extern pico_unique_board_id_t unique_id;
|
||||
|
||||
enum {
|
||||
BLINK_NOT_MOUNTED = (250 << 16) | 250,
|
||||
BLINK_MOUNTED = (250 << 16) | 250,
|
||||
BLINK_SUSPENDED = (500 << 16) | 1000,
|
||||
BLINK_PROCESSING = (50 << 16) | 50,
|
||||
|
||||
BLINK_ALWAYS_ON = UINT32_MAX,
|
||||
BLINK_ALWAYS_OFF = 0
|
||||
};
|
||||
extern void led_set_blink(uint32_t mode);
|
||||
|
||||
#endif
|
||||
189
src/hsm/sc_hsm.c
189
src/hsm/sc_hsm.c
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "sc_hsm.h"
|
||||
#include "file.h"
|
||||
#include "files.h"
|
||||
#include "libopensc/card-sc-hsm.h"
|
||||
#include "random.h"
|
||||
#include "common.h"
|
||||
@@ -65,8 +65,85 @@ void __attribute__ ((constructor)) sc_hsm_ctor() {
|
||||
register_app(sc_hsm_select_aid);
|
||||
}
|
||||
|
||||
void init_sc_hsm() {
|
||||
void scan_files() {
|
||||
file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF);
|
||||
if (file_pin1) {
|
||||
if (!file_pin1->data) {
|
||||
TU_LOG1("PIN1 is empty. Initializing with default password\r\n");
|
||||
const uint8_t empty[33] = { 0 };
|
||||
flash_write_data_to_file(file_pin1, empty, sizeof(empty));
|
||||
}
|
||||
}
|
||||
else {
|
||||
TU_LOG1("FATAL ERROR: PIN1 not found in memory!\r\n");
|
||||
}
|
||||
file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF);
|
||||
if (file_sopin) {
|
||||
if (!file_sopin->data) {
|
||||
TU_LOG1("SOPIN is empty. Initializing with default password\r\n");
|
||||
const uint8_t empty[33] = { 0 };
|
||||
flash_write_data_to_file(file_sopin, empty, sizeof(empty));
|
||||
}
|
||||
}
|
||||
else {
|
||||
TU_LOG1("FATAL ERROR: SOPIN not found in memory!\r\n");
|
||||
}
|
||||
file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF);
|
||||
if (file_retries_pin1) {
|
||||
if (!file_retries_pin1->data) {
|
||||
TU_LOG1("Retries PIN1 is empty. Initializing with default retriesr\n");
|
||||
const uint8_t retries = 3;
|
||||
flash_write_data_to_file(file_retries_pin1, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
TU_LOG1("FATAL ERROR: Retries PIN1 not found in memory!\r\n");
|
||||
}
|
||||
file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF);
|
||||
if (file_retries_sopin) {
|
||||
if (!file_retries_sopin->data) {
|
||||
TU_LOG1("Retries SOPIN is empty. Initializing with default retries\r\n");
|
||||
const uint8_t retries = 15;
|
||||
flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
TU_LOG1("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
|
||||
}
|
||||
file_t *tf = NULL;
|
||||
|
||||
tf = search_by_fid(0x1082, NULL, SPECIFY_EF);
|
||||
if (tf) {
|
||||
if (!tf->data) {
|
||||
TU_LOG1("Max retries PIN1 is empty. Initializing with default max retriesr\n");
|
||||
const uint8_t retries = 3;
|
||||
flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
TU_LOG1("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n");
|
||||
}
|
||||
tf = search_by_fid(0x1089, NULL, SPECIFY_EF);
|
||||
if (tf) {
|
||||
if (!tf->data) {
|
||||
TU_LOG1("Max Retries SOPIN is empty. Initializing with default max retries\r\n");
|
||||
const uint8_t retries = 15;
|
||||
flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
TU_LOG1("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
|
||||
}
|
||||
low_flash_available();
|
||||
}
|
||||
|
||||
void scan_all() {
|
||||
scan_flash();
|
||||
scan_files();
|
||||
}
|
||||
|
||||
void init_sc_hsm() {
|
||||
scan_all();
|
||||
has_session_pin = has_session_sopin = false;
|
||||
isUserAuthenticated = false;
|
||||
cmd_select();
|
||||
@@ -76,7 +153,7 @@ int sc_hsm_unload() {
|
||||
has_session_pin = has_session_sopin = false;
|
||||
isUserAuthenticated = false;
|
||||
sm_session_pin_len = 0;
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
void select_file(file_t *pe) {
|
||||
@@ -302,7 +379,7 @@ int cvc_prepare_signatures(sc_pkcs15_card_t *p15card, sc_cvc_t *cvc, size_t sig_
|
||||
}
|
||||
hash256(cvcbin, cvclen, hsh);
|
||||
free(cvcbin);
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int parse_token_info(const file_t *f, int mode) {
|
||||
@@ -446,14 +523,14 @@ static int cmd_read_binary()
|
||||
|
||||
int pin_reset_retries(const file_t *pin, bool force) {
|
||||
if (!pin)
|
||||
return HSM_ERR_NULL_PARAM;
|
||||
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);
|
||||
if (!max || !act)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
uint8_t retries = file_read_uint8(act->data+2);
|
||||
if (retries == 0 && force == false) //blocked
|
||||
return HSM_ERR_BLOCKED;
|
||||
return CCID_ERR_BLOCKED;
|
||||
retries = file_read_uint8(max->data+2);
|
||||
int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries));
|
||||
low_flash_available();
|
||||
@@ -462,22 +539,22 @@ int pin_reset_retries(const file_t *pin, bool force) {
|
||||
|
||||
int pin_wrong_retry(const file_t *pin) {
|
||||
if (!pin)
|
||||
return HSM_ERR_NULL_PARAM;
|
||||
return CCID_ERR_NULL_PARAM;
|
||||
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
|
||||
if (!act)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
uint8_t retries = file_read_uint8(act->data+2);
|
||||
if (retries > 0) {
|
||||
retries -= 1;
|
||||
int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries));
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
low_flash_available();
|
||||
if (retries == 0)
|
||||
return HSM_ERR_BLOCKED;
|
||||
return CCID_ERR_BLOCKED;
|
||||
return retries;
|
||||
}
|
||||
return HSM_ERR_BLOCKED;
|
||||
return CCID_ERR_BLOCKED;
|
||||
}
|
||||
|
||||
int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
||||
@@ -491,7 +568,7 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
||||
if (is_secured_apdu() && sm_session_pin_len > 0 && pin == file_pin1) {
|
||||
if (len == sm_session_pin_len && memcmp(data, sm_session_pin, len) != 0) {
|
||||
uint8_t retries;
|
||||
if ((retries = pin_wrong_retry(pin)) < HSM_OK)
|
||||
if ((retries = pin_wrong_retry(pin)) < CCID_OK)
|
||||
return SW_PIN_BLOCKED();
|
||||
return set_res_sw(0x63, 0xc0 | retries);
|
||||
}
|
||||
@@ -503,15 +580,15 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
||||
return SW_CONDITIONS_NOT_SATISFIED();
|
||||
if (memcmp(file_read(pin->data+3), dhash, sizeof(dhash)) != 0) {
|
||||
uint8_t retries;
|
||||
if ((retries = pin_wrong_retry(pin)) < HSM_OK)
|
||||
if ((retries = pin_wrong_retry(pin)) < CCID_OK)
|
||||
return SW_PIN_BLOCKED();
|
||||
return set_res_sw(0x63, 0xc0 | retries);
|
||||
}
|
||||
}
|
||||
int r = pin_reset_retries(pin, false);
|
||||
if (r == HSM_ERR_BLOCKED)
|
||||
if (r == CCID_ERR_BLOCKED)
|
||||
return SW_PIN_BLOCKED();
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_MEMORY_FAILURE();
|
||||
isUserAuthenticated = true;
|
||||
hash_multi(data, len, session_pin);
|
||||
@@ -595,7 +672,7 @@ static int cmd_reset_retry() {
|
||||
dhash[0] = newpin_len;
|
||||
double_hash_pin(apdu.cmd_apdu_data+(apdu.cmd_apdu_data_len-newpin_len), newpin_len, dhash+1);
|
||||
flash_write_data_to_file(file_pin1, dhash, sizeof(dhash));
|
||||
if (pin_reset_retries(file_pin1, true) != HSM_OK)
|
||||
if (pin_reset_retries(file_pin1, true) != CCID_OK)
|
||||
return SW_MEMORY_FAILURE();
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
@@ -616,7 +693,7 @@ static int cmd_reset_retry() {
|
||||
if (apdu.cmd_apdu_data_len != 0)
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
if (pin_reset_retries(file_pin1, true) != HSM_OK)
|
||||
if (pin_reset_retries(file_pin1, true) != CCID_OK)
|
||||
return SW_MEMORY_FAILURE();
|
||||
return SW_OK();
|
||||
}
|
||||
@@ -643,7 +720,7 @@ int heapLeft() {
|
||||
static int cmd_initialize() {
|
||||
if (apdu.cmd_apdu_data_len > 0) {
|
||||
initialize_flash(true);
|
||||
scan_flash();
|
||||
scan_all();
|
||||
dkeks = current_dkeks = 0;
|
||||
uint8_t tag = 0x0, *tag_data = NULL, *p = NULL;
|
||||
size_t tag_len = 0;
|
||||
@@ -687,7 +764,7 @@ static int cmd_initialize() {
|
||||
}
|
||||
if (dkeks == 0) {
|
||||
int r = save_dkek_key(random_bytes_get(32));
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
else
|
||||
@@ -723,7 +800,7 @@ static int cmd_import_dkek() {
|
||||
return SW_WRONG_LENGTH();
|
||||
import_dkek_share(apdu.cmd_apdu_data);
|
||||
if (++current_dkeks == dkeks) {
|
||||
if (save_dkek_key(NULL) != HSM_OK)
|
||||
if (save_dkek_key(NULL) != CCID_OK)
|
||||
return SW_FILE_NOT_FOUND();
|
||||
|
||||
}
|
||||
@@ -765,14 +842,14 @@ int store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx) {
|
||||
memcpy(kdata, key_ctx, key_size);
|
||||
}
|
||||
r = dkek_encrypt(kdata, key_size);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
file_t *fpk = file_new((KEY_PREFIX << 8) | key_id);
|
||||
if (!fpk)
|
||||
return SW_MEMORY_FAILURE();
|
||||
r = flash_write_data_to_file(fpk, kdata, key_size);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
//add_file_to_chain(fpk, &ef_kf);
|
||||
if (type == SC_PKCS15_TYPE_PRKEY_RSA || type == SC_PKCS15_TYPE_PRKEY_EC) {
|
||||
@@ -806,7 +883,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx) {
|
||||
r = flash_write_data_to_file(fpk, asn1bin, asn1len);
|
||||
if (asn1bin)
|
||||
free(asn1bin);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
//add_file_to_chain(fpk, &ef_prkdf);
|
||||
/*
|
||||
@@ -837,12 +914,12 @@ int store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx) {
|
||||
fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id);
|
||||
r = flash_write_data_to_file(fpk, asn1bin, asn1len);
|
||||
free(asn1bin);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
//add_file_to_chain(fpk, &ef_cdf);
|
||||
*/
|
||||
low_flash_available();
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
static int cmd_keypair_gen() {
|
||||
@@ -909,7 +986,7 @@ static int cmd_keypair_gen() {
|
||||
|
||||
uint8_t hsh[32];
|
||||
ret = cvc_prepare_signatures(&p15card, &cvc, key_size/8, hsh);
|
||||
if (ret != HSM_OK) {
|
||||
if (ret != CCID_OK) {
|
||||
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
||||
mbedtls_rsa_free(&rsa);
|
||||
free(ctx);
|
||||
@@ -925,7 +1002,7 @@ static int cmd_keypair_gen() {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
ret = store_keys(&rsa, SC_PKCS15_TYPE_PRKEY_RSA, key_id, ctx);
|
||||
if (ret != HSM_OK) {
|
||||
if (ret != CCID_OK) {
|
||||
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
||||
mbedtls_rsa_free(&rsa);
|
||||
free(ctx);
|
||||
@@ -1034,7 +1111,7 @@ static int cmd_keypair_gen() {
|
||||
|
||||
uint8_t hsh[32];
|
||||
ret = cvc_prepare_signatures(&p15card, &cvc, ecdsa.grp.pbits*2/8+9, hsh);
|
||||
if (ret != HSM_OK) {
|
||||
if (ret != CCID_OK) {
|
||||
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
free(ctx);
|
||||
@@ -1051,7 +1128,7 @@ static int cmd_keypair_gen() {
|
||||
}
|
||||
|
||||
ret = store_keys(&ecdsa, SC_PKCS15_TYPE_PRKEY_EC, key_id, ctx);
|
||||
if (ret != HSM_OK) {
|
||||
if (ret != CCID_OK) {
|
||||
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
free(ctx);
|
||||
@@ -1148,7 +1225,7 @@ static int cmd_update_ef() {
|
||||
}
|
||||
if (offset == 0) {
|
||||
int r = flash_write_data_to_file(ef, data, data_len);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_MEMORY_FAILURE();
|
||||
}
|
||||
else {
|
||||
@@ -1159,7 +1236,7 @@ static int cmd_update_ef() {
|
||||
memcpy(data_merge+offset, data, data_len);
|
||||
int r = flash_write_data_to_file(ef, data_merge, offset+data_len);
|
||||
free(data_merge);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_MEMORY_FAILURE();
|
||||
}
|
||||
low_flash_available();
|
||||
@@ -1184,9 +1261,9 @@ static int cmd_delete_file() {
|
||||
}
|
||||
if (!authenticate_action(ef, ACL_OP_DELETE_SELF))
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
if (flash_clear_file(ef) != HSM_OK)
|
||||
if (flash_clear_file(ef) != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
if (delete_dynamic_file(ef) != HSM_OK)
|
||||
if (delete_dynamic_file(ef) != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
@@ -1205,12 +1282,12 @@ static int cmd_change_pin() {
|
||||
uint16_t r = check_pin(file_pin1, apdu.cmd_apdu_data, pin_len);
|
||||
if (r != 0x9000)
|
||||
return r;
|
||||
if (load_dkek() != HSM_OK) //loads the DKEK with old pin
|
||||
if (load_dkek() != CCID_OK) //loads the DKEK with old pin
|
||||
return SW_EXEC_ERROR();
|
||||
//encrypt DKEK with new pin
|
||||
hash_multi(apdu.cmd_apdu_data+pin_len, apdu.cmd_apdu_data_len-pin_len, session_pin);
|
||||
has_session_pin = true;
|
||||
if (store_dkek_key() != HSM_OK)
|
||||
if (store_dkek_key() != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
uint8_t dhash[33];
|
||||
dhash[0] = apdu.cmd_apdu_data_len-pin_len;
|
||||
@@ -1248,7 +1325,7 @@ static int cmd_key_gen() {
|
||||
sc_context_t *card_ctx = create_context();
|
||||
r = store_keys(aes_key, aes_type, key_id, card_ctx);
|
||||
free(card_ctx);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_MEMORY_FAILURE();
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
@@ -1286,7 +1363,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
||||
mbedtls_rsa_free(ctx);
|
||||
return SW_DATA_INVALID();
|
||||
}
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
||||
@@ -1295,15 +1372,15 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
||||
uint8_t kdata[67]; //Worst case, 521 bit + 1byte
|
||||
memcpy(kdata, file_read(fkey->data+2), key_size);
|
||||
if (dkek_decrypt(kdata, key_size) != 0) {
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
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);
|
||||
return HSM_EXEC_ERROR;
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
return HSM_OK;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
static int cmd_signature() {
|
||||
@@ -1332,7 +1409,7 @@ static int cmd_signature() {
|
||||
|
||||
int r;
|
||||
r = load_private_key_rsa(&ctx, fkey);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
const uint8_t *hash = apdu.cmd_apdu_data;
|
||||
size_t hash_len = apdu.cmd_apdu_data_len;
|
||||
@@ -1428,7 +1505,7 @@ static int cmd_signature() {
|
||||
md = MBEDTLS_MD_SHA256;
|
||||
int r;
|
||||
r = load_private_key_ecdsa(&ctx, fkey);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_CONDITIONS_NOT_SATISFIED();
|
||||
size_t olen = 0;
|
||||
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
|
||||
@@ -1463,7 +1540,7 @@ static int cmd_key_wrap() {
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_rsa_init(&ctx);
|
||||
r = load_private_key_rsa(&ctx, ef);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_rsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
@@ -1474,7 +1551,7 @@ static int cmd_key_wrap() {
|
||||
mbedtls_ecdsa_context ctx;
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
r = load_private_key_ecdsa(&ctx, ef);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
@@ -1497,7 +1574,7 @@ static int cmd_key_wrap() {
|
||||
aes_type = HSM_KEY_AES_128;
|
||||
r = dkek_encode_key(kdata, aes_type, res_APDU, &wrap_len);
|
||||
}
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
res_APDU_size = wrap_len;
|
||||
return SW_OK();
|
||||
@@ -1516,7 +1593,7 @@ static int cmd_key_unwrap() {
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_rsa_init(&ctx);
|
||||
r = dkek_decode_key(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, NULL);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_rsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
@@ -1524,7 +1601,7 @@ static int cmd_key_unwrap() {
|
||||
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_RSA, key_id, card_ctx);
|
||||
free(card_ctx);
|
||||
mbedtls_rsa_free(&ctx);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
@@ -1532,7 +1609,7 @@ static int cmd_key_unwrap() {
|
||||
mbedtls_ecdsa_context ctx;
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
r = dkek_decode_key(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, NULL);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
@@ -1540,7 +1617,7 @@ static int cmd_key_unwrap() {
|
||||
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_EC, key_id, card_ctx);
|
||||
free(card_ctx);
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
@@ -1548,7 +1625,7 @@ static int cmd_key_unwrap() {
|
||||
uint8_t aes_key[32];
|
||||
int key_size = 0, aes_type;
|
||||
r = dkek_decode_key(aes_key, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, &key_size);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
if (key_size == 32)
|
||||
@@ -1560,7 +1637,7 @@ static int cmd_key_unwrap() {
|
||||
sc_context_t *card_ctx = create_context();
|
||||
r = store_keys(aes_key, aes_type, key_id, card_ctx);
|
||||
free(card_ctx);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
@@ -1578,7 +1655,7 @@ static int cmd_decrypt_asym() {
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_rsa_init(&ctx);
|
||||
int r = load_private_key_rsa(&ctx, ef);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
int key_size = file_read_uint16(ef->data);
|
||||
if (apdu.cmd_apdu_data_len < key_size) //needs padding
|
||||
@@ -1747,7 +1824,7 @@ static int cmd_derive_asym() {
|
||||
|
||||
int r;
|
||||
r = load_private_key_ecdsa(&ctx, fkey);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
@@ -1778,7 +1855,7 @@ static int cmd_derive_asym() {
|
||||
sc_context_t *card_ctx = create_context();
|
||||
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_EC, dest_id, card_ctx);
|
||||
free(card_ctx);
|
||||
if (r != HSM_OK) {
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
mbedtls_mpi_free(&a);
|
||||
mbedtls_mpi_free(&nd);
|
||||
@@ -1935,7 +2012,7 @@ int cmd_general_authenticate() {
|
||||
r = sm_sign(t, pubkey_len+16, res_APDU+res_APDU_size);
|
||||
|
||||
free(t);
|
||||
if (r != HSM_OK)
|
||||
if (r != CCID_OK)
|
||||
return SW_EXEC_ERROR();
|
||||
res_APDU_size += 8;
|
||||
}
|
||||
|
||||
@@ -20,80 +20,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hsm2040.h"
|
||||
#include "ccid2040.h"
|
||||
|
||||
extern const uint8_t sc_hsm_aid[];
|
||||
|
||||
#define SW_BYTES_REMAINING_00() set_res_sw (0x61, 0x00)
|
||||
#define SW_WARNING_STATE_UNCHANGED() set_res_sw (0x62, 0x00)
|
||||
#define SW_WARNING_CORRUPTED() set_res_sw (0x62, 0x81)
|
||||
#define SW_WARNING_EOF() set_res_sw (0x62, 0x82)
|
||||
#define SW_WARNING_EF_DEACTIVATED() set_res_sw (0x62, 0x83)
|
||||
#define SW_WARNING_WRONG_FCI() set_res_sw (0x62, 0x84)
|
||||
#define SW_WARNING_EF_TERMINATED() set_res_sw (0x62, 0x85)
|
||||
|
||||
#define SW_WARNING_NOINFO() set_res_sw (0x63, 0x00)
|
||||
#define SW_WARNING_FILLUP() set_res_sw (0x63, 0x81)
|
||||
|
||||
#define SW_EXEC_ERROR() set_res_sw (0x64, 0x00)
|
||||
|
||||
#define SW_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
|
||||
|
||||
#define SW_SECURE_MESSAGE_EXEC_ERROR() set_res_sw (0x66, 0x00)
|
||||
|
||||
#define SW_WRONG_LENGTH() set_res_sw (0x67, 0x00)
|
||||
#define SW_WRONG_DATA() set_res_sw (0x67, 0x00)
|
||||
|
||||
#define SW_LOGICAL_CHANNEL_NOT_SUPPORTED() set_res_sw (0x68, 0x81)
|
||||
#define SW_SECURE_MESSAGING_NOT_SUPPORTED() set_res_sw (0x68, 0x82)
|
||||
|
||||
#define SW_COMMAND_INCOMPATIBLE() set_res_sw (0x69, 0x81)
|
||||
#define SW_SECURITY_STATUS_NOT_SATISFIED() set_res_sw (0x69, 0x82)
|
||||
#define SW_PIN_BLOCKED() set_res_sw (0x69, 0x83)
|
||||
#define SW_DATA_INVALID() set_res_sw (0x69, 0x84)
|
||||
#define SW_CONDITIONS_NOT_SATISFIED() set_res_sw (0x69, 0x85)
|
||||
#define SW_COMMAND_NOT_ALLOWED() set_res_sw (0x69, 0x86)
|
||||
#define SW_SECURE_MESSAGING_MISSING_DO() set_res_sw (0x69, 0x87)
|
||||
#define SW_SECURE_MESSAGING_INCORRECT_DO() set_res_sw (0x69, 0x88)
|
||||
#define SW_APPLET_SELECT_FAILED() set_res_sw (0x69, 0x99)
|
||||
|
||||
#define SW_INCORRECT_PARAMS() set_res_sw (0x6A, 0x80)
|
||||
#define SW_FUNC_NOT_SUPPORTED() set_res_sw (0x6A, 0x81)
|
||||
#define SW_FILE_NOT_FOUND() set_res_sw (0x6A, 0x82)
|
||||
#define SW_RECORD_NOT_FOUND() set_res_sw (0x6A, 0x83)
|
||||
#define SW_FILE_FULL() set_res_sw (0x6A, 0x84)
|
||||
#define SW_WRONG_NE() set_res_sw (0x6A, 0x85)
|
||||
#define SW_INCORRECT_P1P2() set_res_sw (0x6A, 0x86)
|
||||
#define SW_WRONG_NC() set_res_sw (0x6A, 0x87)
|
||||
#define SW_REFERENCE_NOT_FOUND() set_res_sw (0x6A, 0x88)
|
||||
#define SW_FILE_EXISTS() set_res_sw (0x6A, 0x89)
|
||||
|
||||
#define SW_WRONG_P1P2() set_res_sw (0x6B, 0x00)
|
||||
|
||||
#define SW_CORRECT_LENGTH_00() set_res_sw (0x6C, 0x00)
|
||||
|
||||
#define SW_INS_NOT_SUPPORTED() set_res_sw (0x6D, 0x00)
|
||||
|
||||
#define SW_CLA_NOT_SUPPORTED() set_res_sw (0x6E, 0x00)
|
||||
|
||||
#define SW_UNKNOWN() set_res_sw (0x6F, 0x00)
|
||||
|
||||
#define SW_OK() set_res_sw (0x90, 0x00)
|
||||
|
||||
#define HSM_OK 0
|
||||
#define HSM_ERR_NO_MEMORY -1000
|
||||
#define HSM_ERR_MEMORY_FATAL -1001
|
||||
#define HSM_ERR_NULL_PARAM -1002
|
||||
#define HSM_ERR_FILE_NOT_FOUND -1003
|
||||
#define HSM_ERR_BLOCKED -1004
|
||||
#define HSM_NO_LOGIN -1005
|
||||
#define HSM_EXEC_ERROR -1006
|
||||
#define HSM_WRONG_LENGTH -1007
|
||||
#define HSM_WRONG_DATA -1008
|
||||
#define HSM_WRONG_DKEK -1009
|
||||
#define HSM_WRONG_SIGNATURE -1010
|
||||
#define HSM_WRONG_PADDING -1011
|
||||
#define HSM_VERIFICATION_FAILED -1012
|
||||
|
||||
#define ALGO_RSA_RAW 0x20 /* RSA signature with external padding */
|
||||
#define ALGO_RSA_DECRYPT 0x21 /* RSA decrypt */
|
||||
|
||||
Reference in New Issue
Block a user