diff --git a/.gitmodules b/.gitmodules index 5c7a3a7..6f7c861 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "OpenSC"] path = OpenSC url = https://github.com/polhenarejos/OpenSC -[submodule "mbedtls"] - path = mbedtls - url = https://github.com/ARMmbed/mbedtls [submodule "pico-ccid"] path = pico-ccid url = https://github.com/polhenarejos/pico-ccid diff --git a/CMakeLists.txt b/CMakeLists.txt index 0047b02..2e14549 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,9 +60,9 @@ target_sources(pico_hsm PUBLIC ${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/rng/random.c ${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/rng/neug.c ${CMAKE_CURRENT_LIST_DIR}/src/hsm/files.c - ${CMAKE_CURRENT_LIST_DIR}/src/hsm/crypto_utils.c + ${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/crypto_utils.c ${CMAKE_CURRENT_LIST_DIR}/src/hsm/dkek.c - ${CMAKE_CURRENT_LIST_DIR}/src/hsm/eac.c + ${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/eac.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha256.c ${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aes.c diff --git a/pico-ccid b/pico-ccid index cffee42..5e51c9a 160000 --- a/pico-ccid +++ b/pico-ccid @@ -1 +1 @@ -Subproject commit cffee4264a531b52a5991c916e131280adeb1c9d +Subproject commit 5e51c9a072fecc7113702b74e13b8a2d346186b2 diff --git a/src/hsm/crypto_utils.c b/src/hsm/crypto_utils.c deleted file mode 100644 index 287277e..0000000 --- a/src/hsm/crypto_utils.c +++ /dev/null @@ -1,142 +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 . - */ - -#include -#include "mbedtls/md.h" -#include "mbedtls/sha256.h" -#include "mbedtls/aes.h" -#include "crypto_utils.h" -#include "sc_hsm.h" -#include "libopensc/card-sc-hsm.h" - -void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]) { - uint8_t o1[32]; - hash_multi(pin, len, o1); - for (int i = 0; i < sizeof(o1); i++) - o1[i] ^= pin[i%len]; - hash_multi(o1, sizeof(o1), output); -} - -void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]) { - mbedtls_sha256_context ctx; - mbedtls_sha256_init(&ctx); - int iters = 256; - pico_unique_board_id_t unique_id; - - pico_get_unique_board_id(&unique_id); - - mbedtls_sha256_starts (&ctx, 0); - mbedtls_sha256_update (&ctx, unique_id.id, sizeof(unique_id.id)); - - while (iters > len) - { - mbedtls_sha256_update (&ctx, input, len); - iters -= len; - } - if (iters > 0) // remaining iterations - mbedtls_sha256_update (&ctx, input, iters); - mbedtls_sha256_finish (&ctx, output); - mbedtls_sha256_free (&ctx); -} - -void hash256(const uint8_t *input, size_t len, uint8_t output[32]) { - mbedtls_sha256_context ctx; - mbedtls_sha256_init(&ctx); - - mbedtls_sha256_starts (&ctx, 0); - mbedtls_sha256_update (&ctx, input, len); - - mbedtls_sha256_finish (&ctx, output); - mbedtls_sha256_free (&ctx); -} - -void generic_hash(mbedtls_md_type_t md, const uint8_t *input, size_t len, uint8_t *output) { - mbedtls_md_context_t ctx; - mbedtls_md_init(&ctx); - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md); - mbedtls_md_setup(&ctx, md_info, 0); - mbedtls_md_starts(&ctx); - mbedtls_md_update(&ctx, input, len); - mbedtls_md_finish(&ctx, output); - mbedtls_md_free(&ctx); -} - -int aes_encrypt(const uint8_t *key, const uint8_t *iv, int key_size, int mode, uint8_t *data, int len) { - mbedtls_aes_context aes; - mbedtls_aes_init(&aes); - uint8_t tmp_iv[IV_SIZE]; - size_t iv_offset = 0; - memset(tmp_iv, 0, IV_SIZE); - if (iv) - memcpy(tmp_iv, iv, IV_SIZE); - int r = mbedtls_aes_setkey_enc(&aes, key, key_size); - if (r != 0) - 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); -} - -int aes_decrypt(const uint8_t *key, const uint8_t *iv, int key_size, int mode, uint8_t *data, int len) { - mbedtls_aes_context aes; - mbedtls_aes_init(&aes); - uint8_t tmp_iv[IV_SIZE]; - size_t iv_offset = 0; - memset(tmp_iv, 0, IV_SIZE); - if (iv) - memcpy(tmp_iv, iv, IV_SIZE); - int r = mbedtls_aes_setkey_dec(&aes, key, key_size); - if (r != 0) - 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 - return mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_DECRYPT, len, &iv_offset, tmp_iv, data, data); -} - -int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len) { - return aes_encrypt(key, iv, 256, HSM_AES_MODE_CFB, data, len); -} -int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len) { - return aes_decrypt(key, iv, 256, HSM_AES_MODE_CFB, data, len); -} - -struct ec_curve_mbed_id { - struct sc_lv_data curve; - mbedtls_ecp_group_id id; -}; -struct ec_curve_mbed_id ec_curves_mbed[] = { - { { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 24}, MBEDTLS_ECP_DP_SECP192R1 }, - { { (unsigned char *) "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 32}, MBEDTLS_ECP_DP_SECP256R1 }, - { { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF", 48}, MBEDTLS_ECP_DP_SECP384R1 }, - { { (unsigned char *) "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 66}, MBEDTLS_ECP_DP_SECP521R1 }, - { { (unsigned char *) "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC\x3E\x66\x0A\x90\x9D\x83\x8D\x72\x6E\x3B\xF6\x23\xD5\x26\x20\x28\x20\x13\x48\x1D\x1F\x6E\x53\x77", 32}, MBEDTLS_ECP_DP_BP256R1 }, - { { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB4\x12\xB1\xDA\x19\x7F\xB7\x11\x23\xAC\xD3\xA7\x29\x90\x1D\x1A\x71\x87\x47\x00\x13\x31\x07\xEC\x53", 48}, MBEDTLS_ECP_DP_BP384R1 }, - { { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x71\x7D\x4D\x9B\x00\x9B\xC6\x68\x42\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6\x28\x81\xFF\x2F\x2D\x82\xC6\x85\x28\xAA\x60\x56\x58\x3A\x48\xF3", 64}, MBEDTLS_ECP_DP_BP512R1 }, - { { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xEE\x37", 24}, MBEDTLS_ECP_DP_SECP192K1 }, - { { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFC\x2F", 32}, MBEDTLS_ECP_DP_SECP256K1 }, - { { NULL, 0 }, MBEDTLS_ECP_DP_NONE } -}; - -mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len) { - for (struct ec_curve_mbed_id *ec = ec_curves_mbed; ec->id != MBEDTLS_ECP_DP_NONE; ec++) { - if (prime_len == ec->curve.len && memcmp(prime, ec->curve.value, prime_len) == 0) { - return ec->id; - } - } - return MBEDTLS_ECP_DP_NONE; -} \ No newline at end of file diff --git a/src/hsm/crypto_utils.h b/src/hsm/crypto_utils.h deleted file mode 100644 index 3b686c1..0000000 --- a/src/hsm/crypto_utils.h +++ /dev/null @@ -1,46 +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 . - */ - -#ifndef _CRYPTO_UTILS_H_ -#define _CRYPTO_UTILS_H_ - -#include "stdlib.h" -#include "pico/stdlib.h" -#include "mbedtls/ecp.h" -#include "mbedtls/md.h" - -#define HSM_KEY_RSA 0x1 -#define HSM_KEY_EC 0x10 -#define HSM_KEY_AES 0x100 -#define HSM_KEY_AES_128 0x300 -#define HSM_KEY_AES_192 0x500 -#define HSM_KEY_AES_256 0x900 - -#define HSM_AES_MODE_CBC 1 -#define HSM_AES_MODE_CFB 2 - -extern void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]); -extern void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]); -extern void hash256(const uint8_t *input, size_t len, uint8_t output[32]); -extern void generic_hash(mbedtls_md_type_t md, const uint8_t *input, size_t len, uint8_t *output); -extern int aes_encrypt(const uint8_t *key, const uint8_t *iv, int key_size, int mode, uint8_t *data, int len); -extern int aes_decrypt(const uint8_t *key, const uint8_t *iv, int key_size, int mode, uint8_t *data, int len); -extern int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len); -extern int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len); -extern mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len); - -#endif diff --git a/src/hsm/eac.c b/src/hsm/eac.c deleted file mode 100644 index 2db30c0..0000000 --- a/src/hsm/eac.c +++ /dev/null @@ -1,271 +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 . - */ - -#include "eac.h" -#include "sc_hsm.h" -#include "crypto_utils.h" -#include "random.h" -#include "mbedtls/cmac.h" - -static uint8_t nonce[8]; -static uint8_t auth_token[8]; -static uint8_t sm_kmac[16]; -static uint8_t sm_kenc[16]; -static MSE_protocol sm_protocol = MSE_NONE; -static mbedtls_mpi sm_mSSC; -static uint8_t sm_blocksize = 0; -static uint8_t sm_iv[16]; -size_t sm_session_pin_len = 0; -uint8_t sm_session_pin[16]; - -bool is_secured_apdu() { - return (CLA(apdu) & 0xC); -} - -void sm_derive_key(const uint8_t *input, size_t input_len, uint8_t counter, const uint8_t *nonce, size_t nonce_len, uint8_t *out) { - uint8_t *b = (uint8_t *)calloc(1, input_len+nonce_len+4); - if (input) - memcpy(b, input, input_len); - if (nonce) - memcpy(b+input_len, nonce, nonce_len); - b[input_len+nonce_len+3] = counter; - uint8_t digest[20]; - generic_hash(MBEDTLS_MD_SHA1, b, input_len+nonce_len+4, digest); - memcpy(out, digest, 16); - free(b); -} - -void sm_derive_all_keys(const uint8_t *derived, size_t derived_len) { - memcpy(nonce, random_bytes_get(8), 8); - sm_derive_key(derived, derived_len, 1, nonce, sizeof(nonce), sm_kenc); - sm_derive_key(derived, derived_len, 2, nonce, sizeof(nonce), sm_kmac); - mbedtls_mpi_init(&sm_mSSC); - mbedtls_mpi_grow(&sm_mSSC, sm_blocksize); - mbedtls_mpi_lset(&sm_mSSC, 0); - memset(sm_iv, 0, sizeof(sm_iv)); - sm_session_pin_len = 0; -} - -void sm_set_protocol(MSE_protocol proto) { - sm_protocol = proto; - if (proto == MSE_AES) - sm_blocksize = 16; - else if (proto == MSE_3DES) - sm_blocksize = 8; -} - -MSE_protocol sm_get_protocol() { - return sm_protocol; -} - -uint8_t *sm_get_nonce() { - return nonce; -} - -int sm_sign(uint8_t *in, size_t in_len, uint8_t *out) { - return mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB), sm_kmac, 128, in, in_len, out); -} - -int sm_unwrap() { - uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3; - if (sm_indicator == 0) - return CCID_OK; - int r = sm_verify(); - if (r != CCID_OK) - return r; - int le = sm_get_le(); - if (le >= 0) - apdu.expected_res_size = le; - uint8_t *body = NULL; - size_t body_size = 0; - bool is87 = false; - uint8_t tag = 0x0, *tag_data = NULL, *p = NULL; - size_t tag_len = 0; - while (walk_tlv(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, &p, &tag, &tag_len, &tag_data)) { - if (tag == 0x87 || tag == 0x85) { - body = tag_data; - body_size = tag_len; - if (tag == 0x87) { - is87 = true; - body_size--; - } - } - } - if (!body) - return CCID_WRONG_DATA; - if (is87 && *body++ != 0x1) { - 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 CCID_OK; -} - -int sm_wrap() { - uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3; - if (sm_indicator == 0) - return CCID_OK; - uint8_t input[1024]; - size_t input_len = 0; - memset(input, 0, sizeof(input)); - mbedtls_mpi ssc; - mbedtls_mpi_init(&ssc); - mbedtls_mpi_add_int(&ssc, &sm_mSSC, 1); - mbedtls_mpi_copy(&sm_mSSC, &ssc); - int r = mbedtls_mpi_write_binary(&ssc, input, sm_blocksize); - input_len += sm_blocksize; - mbedtls_mpi_free(&ssc); - if (res_APDU_size > 0) { - res_APDU[res_APDU_size++] = 0x80; - memset(res_APDU+res_APDU_size, 0, (sm_blocksize - (res_APDU_size%sm_blocksize))); - res_APDU_size += (sm_blocksize - (res_APDU_size%sm_blocksize)); - DEBUG_PAYLOAD(res_APDU, res_APDU_size); - sm_update_iv(); - aes_encrypt(sm_kenc, sm_iv, 128, HSM_AES_MODE_CBC, res_APDU, res_APDU_size); - memmove(res_APDU+1, res_APDU, res_APDU_size); - res_APDU[0] = 0x1; - res_APDU_size++; - if (res_APDU_size < 128) { - memmove(res_APDU+2, res_APDU, res_APDU_size); - res_APDU[1] = res_APDU_size; - res_APDU_size += 2; - } - else if (res_APDU_size < 256) { - memmove(res_APDU+3, res_APDU, res_APDU_size); - res_APDU[1] = 0x81; - res_APDU[2] = res_APDU_size; - res_APDU_size += 3; - } - else { - memmove(res_APDU+4, res_APDU, res_APDU_size); - res_APDU[1] = 0x82; - res_APDU[2] = res_APDU_size >> 8; - res_APDU[3] = res_APDU_size & 0xff; - res_APDU_size += 4; - } - res_APDU[0] = 0x87; - } - res_APDU[res_APDU_size++] = 0x99; - res_APDU[res_APDU_size++] = 2; - res_APDU[res_APDU_size++] = apdu.sw >> 8; - res_APDU[res_APDU_size++] = apdu.sw & 0xff; - memcpy(input+input_len, res_APDU, res_APDU_size); - input_len += res_APDU_size; - input[input_len++] = 0x80; - input_len += (sm_blocksize - (input_len%sm_blocksize)); - r = sm_sign(input, input_len, res_APDU+res_APDU_size+2); - res_APDU[res_APDU_size++] = 0x8E; - res_APDU[res_APDU_size++] = 8; - res_APDU_size += 8; - if (apdu.expected_res_size > 0) - apdu.expected_res_size = res_APDU_size; - return CCID_OK; -} - -int sm_get_le() { - uint8_t tag = 0x0, *tag_data = NULL, *p = NULL; - size_t tag_len = 0; - while (walk_tlv(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, &p, &tag, &tag_len, &tag_data)) { - if (tag == 0x97) { - uint32_t le = 0; - for (int t = 1; t <= tag_len; t++) - le |= (*tag_data++) << (tag_len-t); - return le; - } - } - return -1; -} - -void sm_update_iv() { - uint8_t tmp_iv[16], sc_counter[16]; - memset(tmp_iv, 0, sizeof(tmp_iv)); //IV is always 0 for encryption of IV based on counter - mbedtls_mpi_write_binary(&sm_mSSC, sc_counter, sizeof(sc_counter)); - aes_encrypt(sm_kenc, tmp_iv, 128, HSM_AES_MODE_CBC, sc_counter, sizeof(sc_counter)); - memcpy(sm_iv, sc_counter, sizeof(sc_counter)); -} - -int sm_verify() { - uint8_t input[1024]; - memset(input, 0, sizeof(input)); - int input_len = 0, r = 0; - bool add_header = (CLA(apdu) & 0xC) == 0xC; - int data_len = (int)(apdu.cmd_apdu_data_len/sm_blocksize)*sm_blocksize; - if (data_len % sm_blocksize) - data_len += sm_blocksize; - if (data_len+(add_header ? sm_blocksize : 0) > 1024) - return CCID_WRONG_LENGTH; - mbedtls_mpi ssc; - mbedtls_mpi_init(&ssc); - mbedtls_mpi_add_int(&ssc, &sm_mSSC, 1); - mbedtls_mpi_copy(&sm_mSSC, &ssc); - r = mbedtls_mpi_write_binary(&ssc, input, sm_blocksize); - input_len += sm_blocksize; - mbedtls_mpi_free(&ssc); - if (r != 0) - return CCID_EXEC_ERROR; - if (add_header) { - input[input_len++] = CLA(apdu); - input[input_len++] = INS(apdu); - input[input_len++] = P1(apdu); - input[input_len++] = P2(apdu); - input[input_len++] = 0x80; - input_len += sm_blocksize-5; - } - bool some_added = false; - const uint8_t *mac = NULL; - size_t mac_len = 0; - uint8_t tag = 0x0, *tag_data = NULL, *p = NULL; - size_t tag_len = 0; - while (walk_tlv(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, &p, &tag, &tag_len, &tag_data)) { - if (tag & 0x1) { - input[input_len++] = tag; - int tlen = format_tlv_len(tag_len, input+input_len); - input_len += tlen; - memcpy(input+input_len, tag_data, tag_len); - input_len += tag_len; - some_added = true; - } - if (tag == 0x8E) { - mac = tag_data; - mac_len = tag_len; - } - } - if (!mac) - return CCID_WRONG_DATA; - if (some_added) { - input[input_len++] = 0x80; - input_len += (sm_blocksize - (input_len%sm_blocksize)); - } - uint8_t signature[16]; - r = sm_sign(input, input_len, signature); - if (r != 0) - return CCID_EXEC_ERROR; - if (memcmp(signature, mac, mac_len) == 0) - return CCID_OK; - return CCID_VERIFICATION_FAILED; -} - -int sm_remove_padding(const uint8_t *data, size_t data_len) { - int i = data_len-1; - for (; i >= 0 && data[i] == 0; i--); - if (i < 0 || data[i] != 0x80) - return -1; - return i; -} \ No newline at end of file diff --git a/src/hsm/eac.h b/src/hsm/eac.h deleted file mode 100644 index c1e315a..0000000 --- a/src/hsm/eac.h +++ /dev/null @@ -1,46 +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 . - */ - -#ifndef _EAC_H_ -#define _EAC_H_ - -#include -#include "pico/stdlib.h" -#include "ccid2040.h" - -typedef enum MSE_protocol { - MSE_AES = 0, - MSE_3DES, - MSE_NONE -}MSE_protocol; - -extern void sm_derive_all_keys(const uint8_t *input, size_t input_len); -extern void sm_set_protocol(MSE_protocol proto); -extern MSE_protocol sm_get_protocol(); -extern uint8_t *sm_get_nonce(); -extern int sm_sign(uint8_t *in, size_t in_len, uint8_t *out); -int sm_verify(); -void sm_update_iv(); -int sm_get_le(); -extern int sm_unwrap(); -int sm_remove_padding(const uint8_t *data, size_t data_len); -extern int sm_wrap(); -extern bool is_secured_apdu(); -extern uint8_t sm_session_pin[16]; -extern size_t sm_session_pin_len; - -#endif diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index eb4abab..73c0d98 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -40,6 +40,11 @@ const uint8_t sc_hsm_aid[] = { 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02,0x01 }; +char atr_sc_hsm[] = { + 24, + 0x3B,0xFE,0x18,0x00,0x00,0x81,0x31,0xFE,0x45,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0xFA +}; + uint8_t session_pin[32], session_sopin[32]; bool has_session_pin = false, has_session_sopin = false; static uint8_t dkeks = 0, current_dkeks = 0; @@ -62,6 +67,7 @@ app_t *sc_hsm_select_aid(app_t *a) { } void __attribute__ ((constructor)) sc_hsm_ctor() { + ccid_atr = atr_sc_hsm; register_app(sc_hsm_select_aid); } @@ -196,53 +202,6 @@ static void wait_button() { } } -int format_tlv_len(size_t len, uint8_t *out) { - if (len < 128) { - *out = len; - return 1; - } - else if (len < 256) { - *out++ = 0x81; - *out++ = len; - return 2; - } - else { - *out++ = 0x82; - *out++ = (len >> 8) & 0xff; - *out++ = len & 0xff; - return 3; - } - return 0; -} - -int walk_tlv(const uint8_t *cdata, size_t cdata_len, uint8_t **p, uint8_t *tag, size_t *tag_len, uint8_t **data) { - if (!p) - return 0; - if (!*p) - *p = (uint8_t *)cdata; - if (*p-cdata >= cdata_len) - return 0; - uint8_t tg = 0x0; - size_t tgl = 0; - tg = *(*p)++; - tgl = *(*p)++; - if (tgl == 0x82) { - tgl = *(*p)++ << 8; - tgl |= *(*p)++; - } - else if (tgl == 0x81) { - tgl = *(*p)++; - } - if (tag) - *tag = tg; - if (tag_len) - *tag_len = tgl; - if (data) - *data = *p; - *p = *p+tgl; - return 1; -} - static int cmd_select() { uint8_t p1 = P1(apdu); uint8_t p2 = P2(apdu); diff --git a/src/hsm/sc_hsm.h b/src/hsm/sc_hsm.h index 24c8d17..df05535 100644 --- a/src/hsm/sc_hsm.h +++ b/src/hsm/sc_hsm.h @@ -68,11 +68,6 @@ extern void hash(const uint8_t *input, size_t len, uint8_t output[32]); extern void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]); extern void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]); -extern int walk_tlv(const uint8_t *cdata, size_t cdata_len, uint8_t **p, uint8_t *tag, size_t *tag_len, uint8_t **data); -extern int format_tlv_len(size_t len, uint8_t *out); - extern uint8_t session_pin[32], session_sopin[32]; -#define IV_SIZE 16 - #endif \ No newline at end of file