mirror of
https://github.com/polhenarejos/pico-openpgp.git
synced 2024-09-20 03:10:10 +00:00
Adapted to Pico CCID 2.0.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
d0c167345e
commit
167b6d9770
@ -36,12 +36,14 @@ if (NOT DEFINED USB_PID)
|
|||||||
set(USB_PID 0xFCFD)
|
set(USB_PID 0xFCFD)
|
||||||
endif()
|
endif()
|
||||||
add_definitions(-DUSB_PID=${USB_PID})
|
add_definitions(-DUSB_PID=${USB_PID})
|
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_LIST_DIR}/pico-ccid/config/mbedtls_config.h ${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/include/mbedtls COPYONLY)
|
||||||
|
|
||||||
target_sources(pico_openpgp PUBLIC
|
target_sources(pico_openpgp PUBLIC
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/ccid2040.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/usb/usb.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/openpgp.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/files.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/usb/usb_descriptors.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/usb/usb_descriptors.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/ccid2040.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/asn1.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/file.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/file.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/flash.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/flash.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/low_flash.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/low_flash.c
|
||||||
@ -49,40 +51,30 @@ target_sources(pico_openpgp PUBLIC
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/rng/neug.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/rng/neug.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/crypto_utils.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/crypto_utils.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/eac.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/eac.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/openpgp.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/files.c
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha256.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/aes.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/aes.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha512.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/asn1parse.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/rsa.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/bignum.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/bignum.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/platform_util.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/md.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/oid.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/rsa_alt_helpers.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/constant_time.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecdsa.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecp.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecp_curves.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/asn1write.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/hmac_drbg.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/md5.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ripemd160.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha1.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecdh.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cmac.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cmac.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cipher.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cipher.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cipher_wrap.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cipher_wrap.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/chachapoly.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/constant_time.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/camellia.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecdsa.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/chacha20.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecdh.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/aria.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecp.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/poly1305.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecp_curves.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/gcm.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/md.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ccm.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/md5.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/des.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/oid.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/nist_kw.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/platform_util.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/hkdf.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ripemd160.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/asn1parse.c
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/rsa.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/rsa_alt_helpers.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha1.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha256.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha512.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(pico_openpgp PUBLIC
|
target_include_directories(pico_openpgp PUBLIC
|
||||||
@ -95,6 +87,11 @@ target_include_directories(pico_openpgp PUBLIC
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library
|
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_options(pico_openpgp PUBLIC
|
||||||
|
-Wall
|
||||||
|
-Werror
|
||||||
|
)
|
||||||
|
|
||||||
pico_add_extra_outputs(pico_openpgp)
|
pico_add_extra_outputs(pico_openpgp)
|
||||||
|
|
||||||
#target_compile_definitions(pico_openpgp PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
|
#target_compile_definitions(pico_openpgp PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit efb6c8d8cdd9f5a27281465c1dc72d5d227b473c
|
Subproject commit 2b8c23f5931a95bf773ecfe7e8f73def60d94951
|
@ -26,6 +26,7 @@
|
|||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
#include "mbedtls/ecdh.h"
|
#include "mbedtls/ecdh.h"
|
||||||
#include "mbedtls/asn1.h"
|
#include "mbedtls/asn1.h"
|
||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
bool has_pw1 = false;
|
bool has_pw1 = false;
|
||||||
bool has_pw2 = false;
|
bool has_pw2 = false;
|
||||||
@ -60,9 +61,9 @@ static bool wait_button(uint16_t fid) {
|
|||||||
file_t *ef = search_by_fid(fid, NULL, SPECIFY_ANY);
|
file_t *ef = search_by_fid(fid, NULL, SPECIFY_ANY);
|
||||||
uint32_t val = EV_PRESS_BUTTON;
|
uint32_t val = EV_PRESS_BUTTON;
|
||||||
if (ef && ef->data && file_read_uint8(ef->data+2) > 0) {
|
if (ef && ef->data && file_read_uint8(ef->data+2) > 0) {
|
||||||
queue_try_add(ccid_comm, &val);
|
queue_try_add(&card_to_ccid_q, &val);
|
||||||
do {
|
do {
|
||||||
queue_remove_blocking(card_comm, &val);
|
queue_remove_blocking(&ccid_to_card_q, &val);
|
||||||
}
|
}
|
||||||
while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT);
|
while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT);
|
||||||
}
|
}
|
||||||
@ -94,16 +95,16 @@ static int cmd_select() {
|
|||||||
file_t *pe = NULL;
|
file_t *pe = NULL;
|
||||||
uint16_t fid = 0x0;
|
uint16_t fid = 0x0;
|
||||||
|
|
||||||
if (apdu.cmd_apdu_data_len >= 2)
|
if (apdu.nc >= 2)
|
||||||
fid = get_uint16_t(apdu.cmd_apdu_data, 0);
|
fid = get_uint16_t(apdu.data, 0);
|
||||||
|
|
||||||
if (!pe) {
|
if (!pe) {
|
||||||
if (p1 == 0x0) { //Select MF, DF or EF - File identifier or absent
|
if (p1 == 0x0) { //Select MF, DF or EF - File identifier or absent
|
||||||
if (apdu.cmd_apdu_data_len == 0) {
|
if (apdu.nc == 0) {
|
||||||
pe = (file_t *)MF;
|
pe = (file_t *)MF;
|
||||||
//ac_fini();
|
//ac_fini();
|
||||||
}
|
}
|
||||||
else if (apdu.cmd_apdu_data_len == 2) {
|
else if (apdu.nc == 2) {
|
||||||
if (!(pe = search_by_fid(fid, NULL, SPECIFY_ANY))) {
|
if (!(pe = search_by_fid(fid, NULL, SPECIFY_ANY))) {
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
@ -120,11 +121,11 @@ static int cmd_select() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (p1 == 0x03) { //Select parent DF of the current DF - Absent
|
else if (p1 == 0x03) { //Select parent DF of the current DF - Absent
|
||||||
if (apdu.cmd_apdu_data_len != 0)
|
if (apdu.nc != 0)
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
else if (p1 == 0x04) { //Select by DF name - e.g., [truncated] application identifier
|
else if (p1 == 0x04) { //Select by DF name - e.g., [truncated] application identifier
|
||||||
if (!(pe = search_by_name(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len))) {
|
if (!(pe = search_by_name(apdu.data, apdu.nc))) {
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
if (card_terminated) {
|
if (card_terminated) {
|
||||||
@ -132,12 +133,12 @@ static int cmd_select() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (p1 == 0x08) { //Select from the MF - Path without the MF identifier
|
else if (p1 == 0x08) { //Select from the MF - Path without the MF identifier
|
||||||
if (!(pe = search_by_path(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, MF))) {
|
if (!(pe = search_by_path(apdu.data, apdu.nc, MF))) {
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (p1 == 0x09) { //Select from the current DF - Path without the current DF identifier
|
else if (p1 == 0x09) { //Select from the current DF - Path without the current DF identifier
|
||||||
if (!(pe = search_by_path(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, currentDF))) {
|
if (!(pe = search_by_path(apdu.data, apdu.nc, currentDF))) {
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,11 +158,11 @@ void scan_files() {
|
|||||||
file_t *ef;
|
file_t *ef;
|
||||||
if ((ef = search_by_fid(EF_FULL_AID, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_FULL_AID, NULL, SPECIFY_ANY))) {
|
||||||
ef->data = openpgp_aid_full;
|
ef->data = openpgp_aid_full;
|
||||||
pico_get_unique_board_id_string(ef->data+12, 4);
|
pico_get_unique_board_id_string((char *)ef->data+12, 4);
|
||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_PW1, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_PW1, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("PW1 is empty. Initializing with default password\r\n");
|
printf("PW1 is empty. Initializing with default password\r\n");
|
||||||
const uint8_t def[6] = { 0x31,0x32,0x33,0x34,0x35,0x36 };
|
const uint8_t def[6] = { 0x31,0x32,0x33,0x34,0x35,0x36 };
|
||||||
uint8_t dhash[33];
|
uint8_t dhash[33];
|
||||||
dhash[0] = sizeof(def);
|
dhash[0] = sizeof(def);
|
||||||
@ -171,7 +172,7 @@ void scan_files() {
|
|||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_RC, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_RC, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("RC is empty. Initializing with default password\r\n");
|
printf("RC is empty. Initializing with default password\r\n");
|
||||||
|
|
||||||
const uint8_t def[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 };
|
const uint8_t def[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 };
|
||||||
uint8_t dhash[33];
|
uint8_t dhash[33];
|
||||||
@ -182,7 +183,7 @@ void scan_files() {
|
|||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_PW3, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_PW3, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("PW3 is empty. Initializing with default password\r\n");
|
printf("PW3 is empty. Initializing with default password\r\n");
|
||||||
|
|
||||||
const uint8_t def[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 };
|
const uint8_t def[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 };
|
||||||
uint8_t dhash[33];
|
uint8_t dhash[33];
|
||||||
@ -193,21 +194,21 @@ void scan_files() {
|
|||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_SIG_COUNT, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_SIG_COUNT, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("SigCount is empty. Initializing to zero\r\n");
|
printf("SigCount is empty. Initializing to zero\r\n");
|
||||||
const uint8_t def[3] = { 0 };
|
const uint8_t def[3] = { 0 };
|
||||||
flash_write_data_to_file(ef, def, sizeof(def));
|
flash_write_data_to_file(ef, def, sizeof(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("PW status is empty. Initializing to default\r\n");
|
printf("PW status is empty. Initializing to default\r\n");
|
||||||
const uint8_t def[] = { 0x1, 127, 127, 127, 3, 3, 3 };
|
const uint8_t def[] = { 0x1, 127, 127, 127, 3, 3, 3 };
|
||||||
flash_write_data_to_file(ef, def, sizeof(def));
|
flash_write_data_to_file(ef, def, sizeof(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_DEK, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_DEK, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("DEK is empty\r\n");
|
printf("DEK is empty\r\n");
|
||||||
const uint8_t def1[6] = { 0x31,0x32,0x33,0x34,0x35,0x36 };
|
const uint8_t def1[6] = { 0x31,0x32,0x33,0x34,0x35,0x36 };
|
||||||
const uint8_t def3[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 };
|
const uint8_t def3[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 };
|
||||||
|
|
||||||
@ -227,28 +228,28 @@ void scan_files() {
|
|||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_UIF_SIG, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_UIF_SIG, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("UIF SIG is empty. Initializing to default\r\n");
|
printf("UIF SIG is empty. Initializing to default\r\n");
|
||||||
const uint8_t def[] = { 0x0, 0x20 };
|
const uint8_t def[] = { 0x0, 0x20 };
|
||||||
flash_write_data_to_file(ef, def, sizeof(def));
|
flash_write_data_to_file(ef, def, sizeof(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_UIF_DEC, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_UIF_DEC, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("UIF DEC is empty. Initializing to default\r\n");
|
printf("UIF DEC is empty. Initializing to default\r\n");
|
||||||
const uint8_t def[] = { 0x0, 0x20 };
|
const uint8_t def[] = { 0x0, 0x20 };
|
||||||
flash_write_data_to_file(ef, def, sizeof(def));
|
flash_write_data_to_file(ef, def, sizeof(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_UIF_AUT, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_UIF_AUT, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("UIF AUT is empty. Initializing to default\r\n");
|
printf("UIF AUT is empty. Initializing to default\r\n");
|
||||||
const uint8_t def[] = { 0x0, 0x20 };
|
const uint8_t def[] = { 0x0, 0x20 };
|
||||||
flash_write_data_to_file(ef, def, sizeof(def));
|
flash_write_data_to_file(ef, def, sizeof(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ef = search_by_fid(EF_KDF, NULL, SPECIFY_ANY))) {
|
if ((ef = search_by_fid(EF_KDF, NULL, SPECIFY_ANY))) {
|
||||||
if (!ef->data) {
|
if (!ef->data) {
|
||||||
TU_LOG1("KDF is empty. Initializing to default\r\n");
|
printf("KDF is empty. Initializing to default\r\n");
|
||||||
const uint8_t def[] = { 0x81, 0x1, 0x0 };
|
const uint8_t def[] = { 0x81, 0x1, 0x0 };
|
||||||
flash_write_data_to_file(ef, def, sizeof(def));
|
flash_write_data_to_file(ef, def, sizeof(def));
|
||||||
}
|
}
|
||||||
@ -329,7 +330,7 @@ int heapLeft() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app_t *openpgp_select_aid(app_t *a) {
|
app_t *openpgp_select_aid(app_t *a) {
|
||||||
if (!memcmp(apdu.cmd_apdu_data, openpgp_aid+1, openpgp_aid[0])) {
|
if (!memcmp(apdu.data, openpgp_aid+1, openpgp_aid[0])) {
|
||||||
a->aid = openpgp_aid;
|
a->aid = openpgp_aid;
|
||||||
a->process_apdu = openpgp_process_apdu;
|
a->process_apdu = openpgp_process_apdu;
|
||||||
a->unload = openpgp_unload;
|
a->unload = openpgp_unload;
|
||||||
@ -349,7 +350,7 @@ app_t *openpgp_select_aid(app_t *a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__ ((constructor)) openpgp_ctor() {
|
void __attribute__ ((constructor)) openpgp_ctor() {
|
||||||
ccid_atr = atr_openpgp;
|
ccid_atr = (uint8_t *)atr_openpgp;
|
||||||
register_app(openpgp_select_aid);
|
register_app(openpgp_select_aid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +415,7 @@ int parse_ch_data(const file_t *f, int mode) {
|
|||||||
res_APDU[res_APDU_size++] = 0x82;
|
res_APDU[res_APDU_size++] = 0x82;
|
||||||
uint8_t *lp = res_APDU+res_APDU_size;
|
uint8_t *lp = res_APDU+res_APDU_size;
|
||||||
res_APDU_size += 2;
|
res_APDU_size += 2;
|
||||||
uint16_t data_len = parse_do(fids, mode);
|
parse_do(fids, mode);
|
||||||
uint16_t lpdif = res_APDU+res_APDU_size-lp-2;
|
uint16_t lpdif = res_APDU+res_APDU_size-lp-2;
|
||||||
*lp++ = lpdif >> 8;
|
*lp++ = lpdif >> 8;
|
||||||
*lp++ = lpdif & 0xff;
|
*lp++ = lpdif & 0xff;
|
||||||
@ -641,14 +642,6 @@ static const uint8_t algorithm_attr_cv25519[] = {
|
|||||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01
|
0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t *algorithm_attr[] = {
|
|
||||||
algorithm_attr_rsa1k, algorithm_attr_rsa2k, algorithm_attr_rsa3k, algorithm_attr_rsa4k,
|
|
||||||
algorithm_attr_x448, algorithm_attr_p256k1,
|
|
||||||
algorithm_attr_p256r1, algorithm_attr_p384r1, algorithm_attr_p521r1,
|
|
||||||
algorithm_attr_bp256r1, algorithm_attr_bp384r1, algorithm_attr_bp512r1,
|
|
||||||
algorithm_attr_cv25519
|
|
||||||
};
|
|
||||||
|
|
||||||
int parse_algo(const uint8_t *algo, uint16_t tag) {
|
int parse_algo(const uint8_t *algo, uint16_t tag) {
|
||||||
res_APDU[res_APDU_size++] = tag & 0xff;
|
res_APDU[res_APDU_size++] = tag & 0xff;
|
||||||
memcpy(res_APDU+res_APDU_size, algo, algo[0]+1);
|
memcpy(res_APDU+res_APDU_size, algo, algo[0]+1);
|
||||||
@ -731,7 +724,7 @@ int parse_app_data(const file_t *f, int mode) {
|
|||||||
res_APDU[res_APDU_size++] = 0x82;
|
res_APDU[res_APDU_size++] = 0x82;
|
||||||
uint8_t *lp = res_APDU+res_APDU_size;
|
uint8_t *lp = res_APDU+res_APDU_size;
|
||||||
res_APDU_size += 2;
|
res_APDU_size += 2;
|
||||||
uint16_t data_len = parse_do(fids, mode);
|
parse_do(fids, mode);
|
||||||
uint16_t lpdif = res_APDU+res_APDU_size-lp-2;
|
uint16_t lpdif = res_APDU+res_APDU_size-lp-2;
|
||||||
*lp++ = lpdif >> 8;
|
*lp++ = lpdif >> 8;
|
||||||
*lp++ = lpdif & 0xff;
|
*lp++ = lpdif & 0xff;
|
||||||
@ -747,7 +740,7 @@ int parse_discrete_do(const file_t *f, int mode) {
|
|||||||
res_APDU[res_APDU_size++] = 0x82;
|
res_APDU[res_APDU_size++] = 0x82;
|
||||||
uint8_t *lp = res_APDU+res_APDU_size;
|
uint8_t *lp = res_APDU+res_APDU_size;
|
||||||
res_APDU_size += 2;
|
res_APDU_size += 2;
|
||||||
uint16_t data_len = parse_do(fids, mode);
|
parse_do(fids, mode);
|
||||||
uint16_t lpdif = res_APDU+res_APDU_size-lp-2;
|
uint16_t lpdif = res_APDU+res_APDU_size-lp-2;
|
||||||
*lp++ = lpdif >> 8;
|
*lp++ = lpdif >> 8;
|
||||||
*lp++ = lpdif & 0xff;
|
*lp++ = lpdif & 0xff;
|
||||||
@ -755,7 +748,7 @@ int parse_discrete_do(const file_t *f, int mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_get_data() {
|
static int cmd_get_data() {
|
||||||
if (apdu.cmd_apdu_data_len > 0)
|
if (apdu.nc > 0)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
uint16_t fid = (P1(apdu) << 8) | P2(apdu);
|
uint16_t fid = (P1(apdu) << 8) | P2(apdu);
|
||||||
file_t *ef;
|
file_t *ef;
|
||||||
@ -772,8 +765,8 @@ static int cmd_get_data() {
|
|||||||
if (ef->data) {
|
if (ef->data) {
|
||||||
uint16_t fids[] = {1,fid};
|
uint16_t fids[] = {1,fid};
|
||||||
uint16_t data_len = parse_do(fids, 1);
|
uint16_t data_len = parse_do(fids, 1);
|
||||||
if (apdu.expected_res_size > data_len)
|
if (apdu.ne > data_len)
|
||||||
apdu.expected_res_size = data_len;
|
apdu.ne = data_len;
|
||||||
}
|
}
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
@ -861,7 +854,7 @@ static int cmd_verify() {
|
|||||||
uint8_t p2 = P2(apdu);
|
uint8_t p2 = P2(apdu);
|
||||||
|
|
||||||
if (p1 == 0xFF) {
|
if (p1 == 0xFF) {
|
||||||
if (apdu.cmd_apdu_data_len != 0)
|
if (apdu.nc != 0)
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
if (p2 == 0x81)
|
if (p2 == 0x81)
|
||||||
has_pw1 = false;
|
has_pw1 = false;
|
||||||
@ -873,9 +866,8 @@ static int cmd_verify() {
|
|||||||
}
|
}
|
||||||
else if (p1 != 0x0 || (p2 & 0x60) != 0x0)
|
else if (p1 != 0x0 || (p2 & 0x60) != 0x0)
|
||||||
return SW_WRONG_P1P2();
|
return SW_WRONG_P1P2();
|
||||||
uint8_t qualifier = p2&0x1f;
|
|
||||||
uint16_t fid = 0x1000 | p2;
|
uint16_t fid = 0x1000 | p2;
|
||||||
if (fid == EF_RC && apdu.cmd_apdu_data_len > 0)
|
if (fid == EF_RC && apdu.nc > 0)
|
||||||
fid = EF_PW1;
|
fid = EF_PW1;
|
||||||
file_t *pw, *pw_status;
|
file_t *pw, *pw_status;
|
||||||
if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF)))
|
if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF)))
|
||||||
@ -884,8 +876,8 @@ static int cmd_verify() {
|
|||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (file_read_uint8(pw->data+2) == 0) //not initialized
|
if (file_read_uint8(pw->data+2) == 0) //not initialized
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (apdu.cmd_apdu_data_len > 0) {
|
if (apdu.nc > 0) {
|
||||||
return check_pin(pw, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
return check_pin(pw, apdu.data, apdu.nc);
|
||||||
}
|
}
|
||||||
uint8_t retries = file_read_uint8(pw_status->data+2+3+(fid&0x3));
|
uint8_t retries = file_read_uint8(pw_status->data+2+3+(fid&0x3));
|
||||||
if (retries == 0)
|
if (retries == 0)
|
||||||
@ -909,13 +901,13 @@ static int cmd_put_data() {
|
|||||||
}
|
}
|
||||||
if (fid == EF_PW_STATUS) {
|
if (fid == EF_PW_STATUS) {
|
||||||
fid = EF_PW_PRIV;
|
fid = EF_PW_PRIV;
|
||||||
apdu.cmd_apdu_data_len = 4; //we silently ommit the reset parameters
|
apdu.nc = 4; //we silently ommit the reset parameters
|
||||||
}
|
}
|
||||||
if (currentEF && (currentEF->fid & 0x1FF0) == (fid & 0x1FF0)) { //previously selected
|
if (currentEF && (currentEF->fid & 0x1FF0) == (fid & 0x1FF0)) { //previously selected
|
||||||
ef = currentEF;
|
ef = currentEF;
|
||||||
}
|
}
|
||||||
if (apdu.cmd_apdu_data_len > 0 && (ef->type & FILE_DATA_FLASH)) {
|
if (apdu.nc > 0 && (ef->type & FILE_DATA_FLASH)) {
|
||||||
int r = flash_write_data_to_file(ef, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
int r = flash_write_data_to_file(ef, apdu.data, apdu.nc);
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
@ -931,12 +923,12 @@ static int cmd_change_pin() {
|
|||||||
if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF)))
|
if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF)))
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
uint8_t pin_len = file_read_uint8(pw->data+2);
|
uint8_t pin_len = file_read_uint8(pw->data+2);
|
||||||
uint16_t r = check_pin(pw, apdu.cmd_apdu_data, pin_len);
|
uint16_t r = check_pin(pw, apdu.data, pin_len);
|
||||||
if (r != 0x9000)
|
if (r != 0x9000)
|
||||||
return r;
|
return r;
|
||||||
uint8_t dhash[33];
|
uint8_t dhash[33];
|
||||||
dhash[0] = apdu.cmd_apdu_data_len-pin_len;
|
dhash[0] = apdu.nc-pin_len;
|
||||||
double_hash_pin(apdu.cmd_apdu_data+pin_len, apdu.cmd_apdu_data_len-pin_len, dhash+1);
|
double_hash_pin(apdu.data+pin_len, apdu.nc-pin_len, dhash+1);
|
||||||
flash_write_data_to_file(pw, dhash, sizeof(dhash));
|
flash_write_data_to_file(pw, dhash, sizeof(dhash));
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
@ -951,25 +943,25 @@ static int cmd_reset_retry() {
|
|||||||
if (!(pw = search_by_fid(EF_PW1, NULL, SPECIFY_EF)))
|
if (!(pw = search_by_fid(EF_PW1, NULL, SPECIFY_EF)))
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (P1(apdu) == 0x0) {
|
if (P1(apdu) == 0x0) {
|
||||||
file_t *rc, *pw;
|
file_t *rc;
|
||||||
if (!(rc = search_by_fid(EF_RC, NULL, SPECIFY_EF)))
|
if (!(rc = search_by_fid(EF_RC, NULL, SPECIFY_EF)))
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
uint8_t pin_len = file_read_uint8(rc->data+2);
|
uint8_t pin_len = file_read_uint8(rc->data+2);
|
||||||
if (apdu.cmd_apdu_data_len <= pin_len)
|
if (apdu.nc <= pin_len)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
uint16_t r = check_pin(rc, apdu.cmd_apdu_data, pin_len);
|
uint16_t r = check_pin(rc, apdu.data, pin_len);
|
||||||
if (r != 0x9000)
|
if (r != 0x9000)
|
||||||
return r;
|
return r;
|
||||||
newpin_len = apdu.cmd_apdu_data_len-pin_len;
|
newpin_len = apdu.nc-pin_len;
|
||||||
}
|
}
|
||||||
else if (P1(apdu) == 0x2) {
|
else if (P1(apdu) == 0x2) {
|
||||||
if (!has_pw3)
|
if (!has_pw3)
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
newpin_len = apdu.cmd_apdu_data_len;
|
newpin_len = apdu.nc;
|
||||||
}
|
}
|
||||||
uint8_t dhash[33];
|
uint8_t dhash[33];
|
||||||
dhash[0] = newpin_len;
|
dhash[0] = newpin_len;
|
||||||
double_hash_pin(apdu.cmd_apdu_data+(apdu.cmd_apdu_data_len-newpin_len), newpin_len, dhash+1);
|
double_hash_pin(apdu.data+(apdu.nc-newpin_len), newpin_len, dhash+1);
|
||||||
flash_write_data_to_file(pw, dhash, sizeof(dhash));
|
flash_write_data_to_file(pw, dhash, sizeof(dhash));
|
||||||
if (pin_reset_retries(pw, true) != CCID_OK)
|
if (pin_reset_retries(pw, true) != CCID_OK)
|
||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
@ -980,7 +972,7 @@ static int cmd_reset_retry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int store_keys(void *key_ctx, int type, uint16_t key_id) {
|
int store_keys(void *key_ctx, int type, uint16_t key_id) {
|
||||||
int r, key_size;
|
int r, key_size = 0;
|
||||||
uint8_t kdata[4096/8]; //worst
|
uint8_t kdata[4096/8]; //worst
|
||||||
|
|
||||||
//if (!has_pw3)
|
//if (!has_pw3)
|
||||||
@ -1137,18 +1129,18 @@ void make_ecdsa_response(mbedtls_ecdsa_context *ecdsa) {
|
|||||||
static int cmd_keypair_gen() {
|
static int cmd_keypair_gen() {
|
||||||
if (P2(apdu) != 0x0)
|
if (P2(apdu) != 0x0)
|
||||||
return SW_INCORRECT_P1P2();
|
return SW_INCORRECT_P1P2();
|
||||||
if (apdu.cmd_apdu_data_len != 2 && apdu.cmd_apdu_data_len != 5)
|
if (apdu.nc != 2 && apdu.nc != 5)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
if (!has_pw3 && P1(apdu) == 0x80)
|
if (!has_pw3 && P1(apdu) == 0x80)
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
|
|
||||||
uint16_t fid = 0x0;
|
uint16_t fid = 0x0;
|
||||||
int r = CCID_OK;
|
int r = CCID_OK;
|
||||||
if (apdu.cmd_apdu_data[0] == 0xB6)
|
if (apdu.data[0] == 0xB6)
|
||||||
fid = EF_PK_SIG;
|
fid = EF_PK_SIG;
|
||||||
else if (apdu.cmd_apdu_data[0] == 0xB8)
|
else if (apdu.data[0] == 0xB8)
|
||||||
fid = EF_PK_DEC;
|
fid = EF_PK_DEC;
|
||||||
else if (apdu.cmd_apdu_data[0] == 0xA4)
|
else if (apdu.data[0] == 0xA4)
|
||||||
fid = EF_PK_AUT;
|
fid = EF_PK_AUT;
|
||||||
else
|
else
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
@ -1291,17 +1283,6 @@ int rsa_sign(mbedtls_rsa_context *ctx, const uint8_t *data, size_t data_len, uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ecdsa_sign(mbedtls_ecdsa_context *ctx, const uint8_t *data, size_t data_len, uint8_t *out, size_t *out_len) {
|
int ecdsa_sign(mbedtls_ecdsa_context *ctx, const uint8_t *data, size_t data_len, uint8_t *out, size_t *out_len) {
|
||||||
mbedtls_md_type_t md = MBEDTLS_MD_SHA256;
|
|
||||||
if (data_len == 32)
|
|
||||||
md = MBEDTLS_MD_SHA256;
|
|
||||||
else if (data_len == 20)
|
|
||||||
md = MBEDTLS_MD_SHA1;
|
|
||||||
else if (data_len == 28)
|
|
||||||
md = MBEDTLS_MD_SHA224;
|
|
||||||
else if (data_len == 48)
|
|
||||||
md = MBEDTLS_MD_SHA384;
|
|
||||||
else if (data_len == 64)
|
|
||||||
md = MBEDTLS_MD_SHA512;
|
|
||||||
mbedtls_mpi ri, si;
|
mbedtls_mpi ri, si;
|
||||||
mbedtls_mpi_init(&ri);
|
mbedtls_mpi_init(&ri);
|
||||||
mbedtls_mpi_init(&si);
|
mbedtls_mpi_init(&si);
|
||||||
@ -1339,13 +1320,11 @@ static int cmd_pso() {
|
|||||||
if (!algo_ef)
|
if (!algo_ef)
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
||||||
uint16_t algo_len = algorithm_attr_rsa2k[0];
|
|
||||||
if (algo_ef && algo_ef->data) {
|
if (algo_ef && algo_ef->data) {
|
||||||
algo_len = file_read_uint16(algo_ef->data);
|
|
||||||
algo = file_read(algo_ef->data+2);
|
algo = file_read(algo_ef->data+2);
|
||||||
}
|
}
|
||||||
if (apdu.cmd_apdu_data[0] == 0x2) { //AES PSO?
|
if (apdu.data[0] == 0x2) { //AES PSO?
|
||||||
if (((apdu.cmd_apdu_data_len - 1)%16 == 0 && P1(apdu) == 0x80 && P2(apdu) == 0x86) || (apdu.cmd_apdu_data_len%16 == 0 && P1(apdu) == 0x86 && P2(apdu) == 0x80)) {
|
if (((apdu.nc - 1)%16 == 0 && P1(apdu) == 0x80 && P2(apdu) == 0x86) || (apdu.nc%16 == 0 && P1(apdu) == 0x86 && P2(apdu) == 0x80)) {
|
||||||
pk_fid = EF_AES_KEY;
|
pk_fid = EF_AES_KEY;
|
||||||
is_aes = true;
|
is_aes = true;
|
||||||
}
|
}
|
||||||
@ -1365,21 +1344,21 @@ static int cmd_pso() {
|
|||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
if (P1(apdu) == 0x80 && P2(apdu) == 0x86) { //decipher
|
if (P1(apdu) == 0x80 && P2(apdu) == 0x86) { //decipher
|
||||||
r = aes_decrypt(aes_key, NULL, key_size, HSM_AES_MODE_CBC, apdu.cmd_apdu_data+1, apdu.cmd_apdu_data_len-1);
|
r = aes_decrypt(aes_key, NULL, key_size, HSM_AES_MODE_CBC, apdu.data+1, apdu.nc-1);
|
||||||
memset(aes_key, 0, sizeof(aes_key));
|
memset(aes_key, 0, sizeof(aes_key));
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
memcpy(res_APDU, apdu.cmd_apdu_data+1, apdu.cmd_apdu_data_len-1);
|
memcpy(res_APDU, apdu.data+1, apdu.nc-1);
|
||||||
res_APDU_size = apdu.cmd_apdu_data_len-1;
|
res_APDU_size = apdu.nc-1;
|
||||||
}
|
}
|
||||||
else if (P1(apdu) == 0x86 && P2(apdu) == 0x80) { //encipher
|
else if (P1(apdu) == 0x86 && P2(apdu) == 0x80) { //encipher
|
||||||
r = aes_encrypt(aes_key, NULL, key_size, HSM_AES_MODE_CBC, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
r = aes_encrypt(aes_key, NULL, key_size, HSM_AES_MODE_CBC, apdu.data, apdu.nc);
|
||||||
memset(aes_key, 0, sizeof(aes_key));
|
memset(aes_key, 0, sizeof(aes_key));
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
res_APDU[0] = 0x2;
|
res_APDU[0] = 0x2;
|
||||||
memcpy(res_APDU+1, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
memcpy(res_APDU+1, apdu.data, apdu.nc);
|
||||||
res_APDU_size = apdu.cmd_apdu_data_len+1;
|
res_APDU_size = apdu.nc+1;
|
||||||
}
|
}
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
@ -1393,18 +1372,18 @@ static int cmd_pso() {
|
|||||||
}
|
}
|
||||||
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
r = rsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
r = rsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
res_APDU_size = olen;
|
res_APDU_size = olen;
|
||||||
//apdu.expected_res_size = key_size;
|
//apdu.ne = key_size;
|
||||||
}
|
}
|
||||||
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
||||||
if (apdu.cmd_apdu_data_len < key_size) //needs padding
|
if (apdu.nc < key_size) //needs padding
|
||||||
memset(apdu.cmd_apdu_data+apdu.cmd_apdu_data_len, 0, key_size-apdu.cmd_apdu_data_len);
|
memset(apdu.data+apdu.nc, 0, key_size-apdu.nc);
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.cmd_apdu_data+1, res_APDU, key_size);
|
r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.data+1, res_APDU, key_size);
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
@ -1422,7 +1401,7 @@ static int cmd_pso() {
|
|||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
r = ecdsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
@ -1431,7 +1410,7 @@ static int cmd_pso() {
|
|||||||
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
||||||
mbedtls_ecdh_context ctx;
|
mbedtls_ecdh_context ctx;
|
||||||
uint8_t kdata[67];
|
uint8_t kdata[67];
|
||||||
uint8_t *data = apdu.cmd_apdu_data, *end = data+apdu.cmd_apdu_data_len;
|
uint8_t *data = apdu.data, *end = data+apdu.nc;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
if (mbedtls_asn1_get_tag(&data, end, &len, 0xA6) != 0)
|
if (mbedtls_asn1_get_tag(&data, end, &len, 0xA6) != 0)
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
@ -1483,7 +1462,7 @@ static int cmd_terminate_df() {
|
|||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (!has_pw3 && file_read_uint8(retries->data+2+6) > 0)
|
if (!has_pw3 && file_read_uint8(retries->data+2+6) > 0)
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
if (apdu.cmd_apdu_data_len != 0)
|
if (apdu.nc != 0)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
initialize_flash(true);
|
initialize_flash(true);
|
||||||
scan_files();
|
scan_files();
|
||||||
@ -1495,11 +1474,11 @@ static int cmd_activate_file() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_challenge() {
|
static int cmd_challenge() {
|
||||||
uint8_t *rb = (uint8_t *)random_bytes_get(apdu.expected_res_size);
|
uint8_t *rb = (uint8_t *)random_bytes_get(apdu.ne);
|
||||||
if (!rb)
|
if (!rb)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
memcpy(res_APDU, rb, apdu.expected_res_size);
|
memcpy(res_APDU, rb, apdu.ne);
|
||||||
res_APDU_size = apdu.expected_res_size;
|
res_APDU_size = apdu.ne;
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1512,9 +1491,7 @@ static int cmd_internal_aut() {
|
|||||||
if (!algo_ef)
|
if (!algo_ef)
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
||||||
uint16_t algo_len = algorithm_attr_rsa2k[0];
|
|
||||||
if (algo_ef && algo_ef->data) {
|
if (algo_ef && algo_ef->data) {
|
||||||
algo_len = file_read_uint16(algo_ef->data);
|
|
||||||
algo = file_read(algo_ef->data+2);
|
algo = file_read(algo_ef->data+2);
|
||||||
}
|
}
|
||||||
file_t *ef = search_by_fid(pk_aut, NULL, SPECIFY_EF);
|
file_t *ef = search_by_fid(pk_aut, NULL, SPECIFY_EF);
|
||||||
@ -1532,7 +1509,7 @@ static int cmd_internal_aut() {
|
|||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
r = rsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
r = rsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
@ -1547,7 +1524,7 @@ static int cmd_internal_aut() {
|
|||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
r = ecdsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
@ -1559,24 +1536,24 @@ static int cmd_internal_aut() {
|
|||||||
static int cmd_mse() {
|
static int cmd_mse() {
|
||||||
if (P1(apdu) != 0x41 || (P2(apdu) != 0xA4 && P2(apdu) != 0xB8))
|
if (P1(apdu) != 0x41 || (P2(apdu) != 0xA4 && P2(apdu) != 0xB8))
|
||||||
return SW_WRONG_P1P2();
|
return SW_WRONG_P1P2();
|
||||||
if (apdu.cmd_apdu_data[0] != 0x83 || apdu.cmd_apdu_data[1] != 0x1 || (apdu.cmd_apdu_data[2] != 0x2 && apdu.cmd_apdu_data[2] != 0x3))
|
if (apdu.data[0] != 0x83 || apdu.data[1] != 0x1 || (apdu.data[2] != 0x2 && apdu.data[2] != 0x3))
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
if (P2(apdu) == 0xA4) {
|
if (P2(apdu) == 0xA4) {
|
||||||
if (apdu.cmd_apdu_data[2] == 0x2) {
|
if (apdu.data[2] == 0x2) {
|
||||||
algo_dec = EF_ALGO_PRIV2;
|
algo_dec = EF_ALGO_PRIV2;
|
||||||
pk_dec = EF_PK_DEC;
|
pk_dec = EF_PK_DEC;
|
||||||
}
|
}
|
||||||
else if (apdu.cmd_apdu_data[2] == 0x3) {
|
else if (apdu.data[2] == 0x3) {
|
||||||
algo_dec = EF_ALGO_PRIV3;
|
algo_dec = EF_ALGO_PRIV3;
|
||||||
pk_dec = EF_PK_AUT;
|
pk_dec = EF_PK_AUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (P2(apdu) == 0xB8) {
|
else if (P2(apdu) == 0xB8) {
|
||||||
if (apdu.cmd_apdu_data[2] == 0x2) {
|
if (apdu.data[2] == 0x2) {
|
||||||
algo_aut = EF_ALGO_PRIV2;
|
algo_aut = EF_ALGO_PRIV2;
|
||||||
pk_aut = EF_PK_DEC;
|
pk_aut = EF_PK_DEC;
|
||||||
}
|
}
|
||||||
else if (apdu.cmd_apdu_data[2] == 0x3) {
|
else if (apdu.data[2] == 0x3) {
|
||||||
algo_aut = EF_ALGO_PRIV3;
|
algo_aut = EF_ALGO_PRIV3;
|
||||||
pk_aut = EF_PK_AUT;
|
pk_aut = EF_PK_AUT;
|
||||||
}
|
}
|
||||||
@ -1589,15 +1566,15 @@ static int cmd_import_data() {
|
|||||||
uint16_t fid = 0x0;
|
uint16_t fid = 0x0;
|
||||||
if (P1(apdu) != 0x3F || P2(apdu) != 0xFF)
|
if (P1(apdu) != 0x3F || P2(apdu) != 0xFF)
|
||||||
return SW_WRONG_P1P2();
|
return SW_WRONG_P1P2();
|
||||||
if (apdu.cmd_apdu_data_len < 5)
|
if (apdu.nc < 5)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
if (apdu.cmd_apdu_data[0] != 0x4D || (apdu.cmd_apdu_data[2] != 0xB6 && apdu.cmd_apdu_data[2] != 0xB8 && apdu.cmd_apdu_data[2] != 0xA4))
|
if (apdu.data[0] != 0x4D || (apdu.data[2] != 0xB6 && apdu.data[2] != 0xB8 && apdu.data[2] != 0xA4))
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
if (apdu.cmd_apdu_data[2] == 0xB6)
|
if (apdu.data[2] == 0xB6)
|
||||||
fid = EF_PK_SIG;
|
fid = EF_PK_SIG;
|
||||||
else if (apdu.cmd_apdu_data[2] != 0xB8)
|
else if (apdu.data[2] != 0xB8)
|
||||||
fid = EF_PK_DEC;
|
fid = EF_PK_DEC;
|
||||||
else if (apdu.cmd_apdu_data[2] != 0xA4)
|
else if (apdu.data[2] != 0xA4)
|
||||||
fid = EF_PK_AUT;
|
fid = EF_PK_AUT;
|
||||||
else
|
else
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
@ -1607,7 +1584,7 @@ static int cmd_import_data() {
|
|||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *start = apdu.cmd_apdu_data + 4 + apdu.cmd_apdu_data[3];
|
uint8_t *start = apdu.data + 4 + apdu.data[3];
|
||||||
if (*start++ != 0x7F || *start++ != 0x48)
|
if (*start++ != 0x7F || *start++ != 0x48)
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
uint8_t tag_len = *start++, *end = start+tag_len, len[9] = {0}, *p[9] = {NULL};
|
uint8_t tag_len = *start++, *end = start+tag_len, len[9] = {0}, *p[9] = {NULL};
|
||||||
@ -1715,16 +1692,16 @@ static int cmd_select_data() {
|
|||||||
uint16_t fid = 0x0;
|
uint16_t fid = 0x0;
|
||||||
if (P2(apdu) != 0x4)
|
if (P2(apdu) != 0x4)
|
||||||
return SW_WRONG_P1P2();
|
return SW_WRONG_P1P2();
|
||||||
if (apdu.cmd_apdu_data[0] != 0x60)
|
if (apdu.data[0] != 0x60)
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
if (apdu.cmd_apdu_data_len != apdu.cmd_apdu_data[1]+2 || apdu.cmd_apdu_data_len < 5)
|
if (apdu.nc != apdu.data[1]+2 || apdu.nc < 5)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
if (apdu.cmd_apdu_data[2] != 0x5C)
|
if (apdu.data[2] != 0x5C)
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
if (apdu.cmd_apdu_data[3] == 2)
|
if (apdu.data[3] == 2)
|
||||||
fid = (apdu.cmd_apdu_data[4] << 8) | apdu.cmd_apdu_data[5];
|
fid = (apdu.data[4] << 8) | apdu.data[5];
|
||||||
else
|
else
|
||||||
fid = apdu.cmd_apdu_data[4];
|
fid = apdu.data[4];
|
||||||
if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)))
|
if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)))
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) {
|
if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) {
|
||||||
@ -1740,7 +1717,7 @@ static int cmd_select_data() {
|
|||||||
|
|
||||||
static int cmd_get_next_data() {
|
static int cmd_get_next_data() {
|
||||||
file_t *ef = NULL;
|
file_t *ef = NULL;
|
||||||
if (apdu.cmd_apdu_data_len > 0)
|
if (apdu.nc > 0)
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
if (!currentEF)
|
if (!currentEF)
|
||||||
return SW_RECORD_NOT_FOUND();
|
return SW_RECORD_NOT_FOUND();
|
||||||
@ -1805,7 +1782,7 @@ static const cmd_t cmds[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int openpgp_process_apdu() {
|
int openpgp_process_apdu() {
|
||||||
int r = sm_unwrap();
|
sm_unwrap();
|
||||||
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
|
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
|
||||||
if (cmd->ins == INS(apdu)) {
|
if (cmd->ins == INS(apdu)) {
|
||||||
int r = cmd->cmd_handler();
|
int r = cmd->cmd_handler();
|
||||||
|
Loading…
Reference in New Issue
Block a user