21 Commits
v1.8 ... v1.10

Author SHA1 Message Date
Pol Henarejos
d41a488eda Adding support for Transport PIN.
Adding support for initialize options.
2022-04-04 10:07:23 +02:00
Pol Henarejos
375a18ebac Update README.md
Fix RSA 4096 doc link.
2022-04-04 10:04:47 +02:00
Pol Henarejos
20216ac4ba Update README.md 2022-04-04 10:01:16 +02:00
Pol Henarejos
d27d8b0c5b Upgrading to version 1.10
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-04-04 09:57:19 +02:00
Pol Henarejos
a619527482 Adding P1=0x2 and P1=0x3 for reset retry counter.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-04-03 20:59:50 +02:00
Pol Henarejos
85ff92c4de Adding check for device options whether it can reset retry counter with PIN or without.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-04-03 20:40:16 +02:00
Pol Henarejos
b1121718db Adding capability to reset retry counter without new PIN
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-04-03 20:37:16 +02:00
Pol Henarejos
2905dcc8c0 Adding custom command to set datetime.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-04-03 19:57:56 +02:00
Pol Henarejos
c9855f7214 Fix displaying device options.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 19:43:33 +02:00
Pol Henarejos
853b8f29a2 Fix returning kcv when pin is not provided. It always return 0x0
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 19:31:56 +02:00
Pol Henarejos
d5378ffa41 If has_session_pin is true, it returns sw_ok
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 19:31:22 +02:00
Pol Henarejos
4400eba974 Fix returning kcv
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 19:31:02 +02:00
Pol Henarejos
0cc656c6c0 Adding transport PIN option. It does not allow to authenticate and returns sw code 0x6984
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 19:12:56 +02:00
Pol Henarejos
c9b32ab5d0 Fix return pin blocked sw code.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 18:59:54 +02:00
Pol Henarejos
f9ffd39661 Adding EF_DEVOPS to store the device options during the initialization.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 18:56:42 +02:00
Pol Henarejos
bfc12d6856 Renaming files
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 18:27:00 +02:00
Pol Henarejos
11874b52de Merge branch 'master' into eac 2022-03-31 14:46:28 +02:00
Pol Henarejos
33a2222cd8 Revert "PIN remaining tries only returned when user is not logged in. If so, it returns always OK."
This reverts commit 86e38419ac.
2022-03-31 14:30:50 +02:00
Pol Henarejos
923e05a36c Revert "Also for SOPIN."
This reverts commit ad66170379.
2022-03-31 14:30:50 +02:00
Pol Henarejos
ad66170379 Also for SOPIN.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 13:18:56 +02:00
Pol Henarejos
86e38419ac PIN remaining tries only returned when user is not logged in. If so, it returns always OK.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-03-31 13:17:16 +02:00
13 changed files with 139 additions and 46 deletions

View File

@@ -51,7 +51,7 @@ target_sources(pico_hsm PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c
${CMAKE_CURRENT_LIST_DIR}/src/rng/neug.c
${CMAKE_CURRENT_LIST_DIR}/src/hsm/hash_utils.c
${CMAKE_CURRENT_LIST_DIR}/src/hsm/crypto_utils.c
${CMAKE_CURRENT_LIST_DIR}/src/hsm/dkek.c
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha256.c
@@ -119,7 +119,7 @@ pico_add_extra_outputs(pico_hsm)
#target_compile_definitions(pico_hsm PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
target_link_libraries(pico_hsm PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id)
target_link_libraries(pico_hsm PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc)
#
#project(flash_nuke C CXX ASM)

View File

@@ -23,10 +23,12 @@ This is a project to create a Hardware Security Module (HSM) with a Raspberry Pi
- DKEK n-of-m threshold scheme.
- USB/CCID support with OpenSC, openssl, etc.
- Extended APDU support.
- Private keys and certificates import from WKY or PKCS#12 files.[^2]
- Private keys and certificates import from WKY or PKCS#12 files.[^2][^3]
- Transport PIN for provisioning and forcing to set a new PIN.[^2]
[^1]: PKCS11 modules (`pkcs11-tool` and `sc-tool`) do not support CMAC and key derivation. It must be processed through raw APDU command (`opensc-tool -s`).
[^2]: Imports are available via SCS3 tool, and only if the Pico HSM is previously initialized with a DKEK and the DKEK shares are available during the import process. See [SCS3](/doc/rsa_4096_support.md "SCS3") for more information.
[^2]: Available via SCS3 tool. See [SCS3](/doc/rsa_4096.md "SCS3") for more information.
[^3]: Imports are available only if the Pico HSM is previously initialized with a DKEK and the DKEK shares are available during the import process.
## Security considerations
All secret keys (asymmetric and symmetric) are stored encrypted in the flash memory of the Raspberry Pico. DKEK is used as a 256 bit AES key to protect private and secret keys. Keys are never stored in RAM except for signature and decryption operations and only during the process. All keys (including DKEK) are loaded and cleared every time to avoid potential security flaws.
@@ -82,7 +84,7 @@ For backup, restore and DKEK share management, check [doc/backup-and-restore.md]
For AES key generation, encryption and decryption, check [doc/aes.md](/doc/aes.md).
For 4096 bits RSA support, check [doc/rsa_4096_support.md](/doc/rsa_4096_support.md).
For 4096 bits RSA support, check [doc/rsa_4096_support.md](/doc/rsa_4096.md).
## Key generation time
Generating EC keys is almost instant. RSA keypair generation takes some time, specially for `2048` and `4096` bits.
@@ -104,7 +106,7 @@ The way to communicate is exactly the same as with other cards, such as OpenPGP
For an advanced usage, see the docs and examples.
Pico HSM also supports SCS3 tool. See [SCS3](/doc/rsa_4096_support.md "SCS3") for more information.
Pico HSM also supports SCS3 tool. See [SCS3](/doc/rsa_4096.md "SCS3") for more information.
### Important
OpenSC relies on PCSC driver, which reads a list (`Info.plist`) that contains a pair of VID/PID of supported readers. In order to be detectable, you must patch the UF2 binary (if you just downloaded from the [Release section](https://github.com/polhenarejos/pico-hsm/releases "Release section")) or configure the project with the proper VID/PID with `USB_VID` and `USB_PID` parameters in `CMake` (see [Build section](#build "Build section")). Note that you cannot distribute the patched/compiled binary if you do not own the VID/PID or have an explicit authorization.

View File

@@ -1,7 +1,7 @@
#!/bin/bash
VERSION_MAJOR="1"
VERSION_MINOR="8"
VERSION_MINOR="10"
rm -rf release/*
cd build_release

View File

@@ -18,7 +18,7 @@
#
VERSION_MAJOR="1"
VERSION_MINOR="8"
VERSION_MINOR="0A"
echo "----------------------------"
echo "VID/PID patcher for Pico HSM"

View File

@@ -99,15 +99,16 @@ file_t file_entries[] = {
/* 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_PRKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs
/* 17 */ { .fid = EF_PUKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs
/* 18 */ { .fid = EF_CDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs
/* 19 */ { .fid = EF_AODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs
/* 20 */ { .fid = EF_DODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs
/* 21 */ { .fid = EF_SKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs
///* 22 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
/* 23 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
/* 24 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end
/* 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];

View File

@@ -60,6 +60,7 @@
#define EF_AODFS 0x6043
#define EF_DODFS 0x6044
#define EF_SKDFS 0x6045
#define EF_DEVOPS 0x100E
#define MAX_DEPTH 4

View File

@@ -19,7 +19,7 @@
#include "mbedtls/md.h"
#include "mbedtls/sha256.h"
#include "mbedtls/aes.h"
#include "hash_utils.h"
#include "crypto_utils.h"
#include "sc_hsm.h"
#include "libopensc/card-sc-hsm.h"

View File

@@ -15,8 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _HASH_UTILS_H_
#define _HASH_UTILS_H_
#ifndef _CRYPTO_UTILS_H_
#define _CRYPTO_UTILS_H_
#include "stdlib.h"
#include "pico/stdlib.h"

View File

@@ -20,7 +20,7 @@
#include "stdlib.h"
#include "pico/stdlib.h"
#include "dkek.h"
#include "hash_utils.h"
#include "crypto_utils.h"
#include "random.h"
#include "sc_hsm.h"
#include "mbedtls/md.h"
@@ -88,6 +88,7 @@ int dkek_kcv(uint8_t *kcv) { //kcv 8 bytes
hash256(dkek+IV_SIZE, 32, hsh);
release_dkek();
memcpy(kcv, hsh, 8);
return HSM_OK;
}
int dkek_kenc(uint8_t *kenc) { //kenc 32 bytes

View File

@@ -33,6 +33,7 @@
#include "pico/multicore.h"
#include "random.h"
#include "hsm2040.h"
#include "hardware/rtc.h"
extern void do_flash();
extern void low_flash_init();
@@ -1628,6 +1629,7 @@ int main(void)
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
#endif
#endif
led_off_all();
@@ -1638,6 +1640,8 @@ int main(void)
random_init();
low_flash_init();
rtc_init();
while (1)
{

View File

@@ -30,8 +30,9 @@
#include "mbedtls/hkdf.h"
#include "version.h"
#include "cvcerts.h"
#include "hash_utils.h"
#include "crypto_utils.h"
#include "dkek.h"
#include "hardware/rtc.h"
const uint8_t sc_hsm_aid[] = {
11,
@@ -92,6 +93,14 @@ void select_file(file_t *pe) {
//sc_hsm_unload(); //reset auth status
}
}
uint16_t get_device_options() {
file_t *ef = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
if (ef && ef->data)
return (file_read_uint8(ef->data+2) << 8) | file_read_uint8(ef->data+3);
return 0x0;
}
static int cmd_select() {
uint8_t p1 = P1(apdu);
uint8_t p2 = P2(apdu);
@@ -171,8 +180,9 @@ static int cmd_select() {
if (pe == file_sc_hsm) {
res_APDU[res_APDU_size++] = 0x85;
res_APDU[res_APDU_size++] = 4;
res_APDU[res_APDU_size++] = 0xff; //options
res_APDU[res_APDU_size++] = 0xff;
uint16_t opts = get_device_options();
res_APDU[res_APDU_size++] = opts & 0xff;
res_APDU[res_APDU_size++] = opts >> 8;
res_APDU[res_APDU_size++] = HSM_VERSION_MAJOR;
res_APDU[res_APDU_size++] = HSM_VERSION_MINOR;
res_APDU[1] = res_APDU_size-2;
@@ -400,11 +410,12 @@ int pin_wrong_retry(const file_t *pin) {
int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
if (!pin)
return SW_FILE_NOT_FOUND();
return SW_REFERENCE_NOT_FOUND();
if (!pin->data) {
return SW_REFERENCE_NOT_FOUND();
}
isUserAuthenticated = false;
has_session_pin = has_session_sopin = false;
uint8_t dhash[32];
double_hash_pin(data, len, dhash);
if (sizeof(dhash) != file_read_uint16(pin->data)-1) //1 byte for pin len
@@ -422,7 +433,10 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
return SW_MEMORY_FAILURE();
isUserAuthenticated = true;
hash_multi(data, len, session_pin);
has_session_pin = true;
if (pin == file_pin1)
has_session_pin = true;
else if (pin == file_sopin)
has_session_sopin = true;
return SW_OK();
}
@@ -434,46 +448,94 @@ static int cmd_verify() {
return SW_WRONG_P1P2();
uint8_t qualifier = p2&0x1f;
if (p2 == 0x81) { //UserPin
uint16_t opts = get_device_options();
if (opts & HSM_OPT_TRANSPORT_PIN)
return SW_DATA_INVALID();
if (file_read_uint8(file_pin1->data+2) == 0) //not initialized
return SW_REFERENCE_NOT_FOUND();
if (apdu.cmd_apdu_data_len > 0) {
return check_pin(file_pin1, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
}
if (file_read_uint8(file_retries_pin1->data+2) == 0)
return SW_PIN_BLOCKED();
if (has_session_pin)
return SW_OK();
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_pin1->data+2));
}
else if (p2 == 0x88) { //SOPin
if (file_read_uint8(file_sopin->data+2) == 0) //not initialized
return SW_REFERENCE_NOT_FOUND();
if (apdu.cmd_apdu_data_len > 0) {
return check_pin(file_sopin, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
}
if (file_read_uint8(file_retries_sopin->data+2) == 0)
return SW_PIN_BLOCKED();
if (has_session_sopin)
return SW_OK();
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_sopin->data+2));
}
return SW_REFERENCE_NOT_FOUND();
}
static int cmd_reset_retry() {
if (P1(apdu) == 0x0) {
if (P2(apdu) == 0x81) {
if (!file_sopin || !file_pin1) {
return SW_FILE_NOT_FOUND();
}
if (!file_sopin->data) {
return SW_REFERENCE_NOT_FOUND();
}
if (P2(apdu) != 0x81)
return SW_REFERENCE_NOT_FOUND();
if (!file_sopin || !file_pin1) {
return SW_FILE_NOT_FOUND();
}
if (!file_sopin->data) {
return SW_REFERENCE_NOT_FOUND();
}
uint16_t opts = get_device_options();
if (!(opts & HSM_OPT_RRC))
return SW_COMMAND_NOT_ALLOWED();
if (P1(apdu) == 0x0 || P1(apdu) == 0x2) {
int newpin_len = 0;
if (P1(apdu) == 0x0) {
if (apdu.cmd_apdu_data_len <= 8)
return SW_WRONG_LENGTH();
uint16_t r = check_pin(file_sopin, apdu.cmd_apdu_data, 8);
if (r != 0x9000)
return r;
uint8_t dhash[33];
dhash[0] = apdu.cmd_apdu_data_len-8;
double_hash_pin(apdu.cmd_apdu_data+8, apdu.cmd_apdu_data_len-8, dhash+1);
flash_write_data_to_file(file_pin1, dhash, sizeof(dhash));
if (pin_reset_retries(file_pin1, true) != HSM_OK)
return SW_MEMORY_FAILURE();
low_flash_available();
return SW_OK();
newpin_len = apdu.cmd_apdu_data_len-8;
}
else if (P1(apdu) == 0x2) {
if (!has_session_sopin)
return SW_CONDITIONS_NOT_SATISFIED();
if (apdu.cmd_apdu_data_len > 16)
return SW_WRONG_LENGTH();
newpin_len = apdu.cmd_apdu_data_len;
}
uint8_t dhash[33];
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)
return SW_MEMORY_FAILURE();
low_flash_available();
return SW_OK();
}
else if (P1(apdu) == 0x1 || P1(apdu) == 0x3) {
if (!(opts & HSM_OPT_RRC_RESET_ONLY))
return SW_COMMAND_NOT_ALLOWED();
if (P1(apdu) == 0x1) {
if (apdu.cmd_apdu_data_len != 8)
return SW_WRONG_LENGTH();
uint16_t r = check_pin(file_sopin, apdu.cmd_apdu_data, 8);
if (r != 0x9000)
return r;
}
else if (P1(apdu) == 0x3) {
if (!has_session_sopin)
return SW_CONDITIONS_NOT_SATISFIED();
if (apdu.cmd_apdu_data_len != 0)
return SW_WRONG_LENGTH();
}
if (pin_reset_retries(file_pin1, true) != HSM_OK)
return SW_MEMORY_FAILURE();
return SW_OK();
}
return SW_INCORRECT_P1P2();
}
static int cmd_challenge() {
@@ -503,6 +565,8 @@ static int cmd_initialize() {
uint8_t tag = *p++;
uint8_t tag_len = *p++;
if (tag == 0x80) { //options
file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, p, tag_len);
}
else if (tag == 0x81) { //user pin
if (file_pin1 && file_pin1->data) {
@@ -581,6 +645,7 @@ static int cmd_import_dkek() {
}
}
memset(res_APDU,0,10);
res_APDU[0] = dkeks;
res_APDU[1] = dkeks-current_dkeks;
dkek_kcv(res_APDU+2);
@@ -1036,7 +1101,7 @@ static int cmd_delete_file() {
if (apdu.cmd_apdu_data_len == 0) {
ef = currentEF;
if (!(ef = search_dynamic_file(ef->fid)))
return SW_FILE_INVALID();
return SW_FILE_NOT_FOUND();
}
else {
uint16_t fid = (apdu.cmd_apdu_data[0] << 8) | apdu.cmd_apdu_data[1];
@@ -1649,6 +1714,24 @@ static int cmd_derive_asym() {
return SW_OK();
}
static int cmd_datetime() {
if (P1(apdu) != 0x0 || P2(apdu) != 0x0)
return SW_INCORRECT_P1P2();
if (apdu.cmd_apdu_data_len != 8)
return SW_WRONG_LENGTH();
datetime_t dt;
dt.year = (apdu.cmd_apdu_data[0] << 8) | (apdu.cmd_apdu_data[1]);
dt.month = apdu.cmd_apdu_data[2];
dt.day = apdu.cmd_apdu_data[3];
dt.dotw = apdu.cmd_apdu_data[4];
dt.hour = apdu.cmd_apdu_data[5];
dt.min = apdu.cmd_apdu_data[6];
dt.sec = apdu.cmd_apdu_data[7];
if (!rtc_set_datetime(&dt))
return SW_WRONG_DATA();
return SW_OK();
}
typedef struct cmd
{
uint8_t ins;
@@ -1670,6 +1753,7 @@ typedef struct cmd
#define INS_DERIVE_ASYM 0x76
#define INS_CIPHER_SYM 0x78
#define INS_CHALLENGE 0x84
#define INS_DATETIME 0x88
#define INS_SELECT_FILE 0xA4
#define INS_READ_BINARY 0xB0
#define INS_READ_BINARY_ODD 0xB1
@@ -1697,6 +1781,7 @@ static const cmd_t cmds[] = {
{ INS_DECRYPT_ASYM, cmd_decrypt_asym },
{ INS_CIPHER_SYM, cmd_cipher_sym },
{ INS_DERIVE_ASYM, cmd_derive_asym },
{ INS_DATETIME, cmd_datetime },
{ 0x00, 0x0}
};

View File

@@ -26,7 +26,6 @@ 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_PIN_BLOCKED() set_res_sw (0x63, 0x00)
#define SW_EXEC_ERROR() set_res_sw (0x64, 0x00)
#define SW_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
#define SW_WRONG_LENGTH() set_res_sw (0x67, 0x00)
@@ -34,7 +33,7 @@ extern const uint8_t sc_hsm_aid[];
#define SW_LOGICAL_CHANNEL_NOT_SUPPORTED() set_res_sw (0x68, 0x81)
#define SW_SECURE_MESSAGING_NOT_SUPPORTED() set_res_sw (0x68, 0x82)
#define SW_SECURITY_STATUS_NOT_SATISFIED() set_res_sw (0x69, 0x82)
#define SW_FILE_INVALID() set_res_sw (0x69, 0x83)
#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)

View File

@@ -18,7 +18,7 @@
#ifndef __VERSION_H_
#define __VERSION_H_
#define HSM_VERSION 0x0108
#define HSM_VERSION 0x010A
#define HSM_VERSION_MAJOR ((HSM_VERSION >> 8) & 0xff)
#define HSM_VERSION_MINOR (HSM_VERSION & 0xff)