Initialization now returns free memory if no parameters are given.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
121
src/hsm/sc_hsm.c
121
src/hsm/sc_hsm.c
@@ -516,62 +516,83 @@ static int cmd_challenge() {
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
extern char __StackLimit;
|
||||
int heapLeft() {
|
||||
char *p = malloc(256); // try to avoid undue fragmentation
|
||||
int left = &__StackLimit - p;
|
||||
free(p);
|
||||
return left;
|
||||
}
|
||||
|
||||
static int cmd_initialize() {
|
||||
initialize_flash(true);
|
||||
scan_flash();
|
||||
dkeks = 0;
|
||||
const uint8_t *p = apdu.cmd_apdu_data;
|
||||
while (p-apdu.cmd_apdu_data < apdu.cmd_apdu_data_len) {
|
||||
uint8_t tag = *p++;
|
||||
uint8_t tag_len = *p++;
|
||||
if (tag == 0x80) { //options
|
||||
}
|
||||
else if (tag == 0x81) { //user pin
|
||||
if (file_pin1 && file_pin1->data) {
|
||||
uint8_t dhash[33];
|
||||
dhash[0] = tag_len;
|
||||
double_hash_pin(p, tag_len, dhash+1);
|
||||
flash_write_data_to_file(file_pin1, dhash, sizeof(dhash));
|
||||
hash_multi(p, tag_len, session_pin);
|
||||
has_session_pin = true;
|
||||
}
|
||||
}
|
||||
else if (tag == 0x82) { //user pin
|
||||
if (file_sopin && file_sopin->data) {
|
||||
uint8_t dhash[33];
|
||||
dhash[0] = tag_len;
|
||||
double_hash_pin(p, tag_len, dhash+1);
|
||||
flash_write_data_to_file(file_sopin, dhash, sizeof(dhash));
|
||||
hash_multi(p, tag_len, session_sopin);
|
||||
has_session_sopin = true;
|
||||
}
|
||||
}
|
||||
else if (tag == 0x91) { //user pin
|
||||
file_t *tf = search_by_fid(0x1082, NULL, SPECIFY_EF);
|
||||
if (tf && tf->data) {
|
||||
flash_write_data_to_file(tf, p, tag_len);
|
||||
if (apdu.cmd_apdu_data_len > 0) {
|
||||
initialize_flash(true);
|
||||
scan_flash();
|
||||
dkeks = 0;
|
||||
const uint8_t *p = apdu.cmd_apdu_data;
|
||||
while (p-apdu.cmd_apdu_data < apdu.cmd_apdu_data_len) {
|
||||
uint8_t tag = *p++;
|
||||
uint8_t tag_len = *p++;
|
||||
if (tag == 0x80) { //options
|
||||
}
|
||||
if (file_retries_pin1 && file_retries_pin1->data) {
|
||||
flash_write_data_to_file(file_retries_pin1, p, tag_len);
|
||||
else if (tag == 0x81) { //user pin
|
||||
if (file_pin1 && file_pin1->data) {
|
||||
uint8_t dhash[33];
|
||||
dhash[0] = tag_len;
|
||||
double_hash_pin(p, tag_len, dhash+1);
|
||||
flash_write_data_to_file(file_pin1, dhash, sizeof(dhash));
|
||||
hash_multi(p, tag_len, session_pin);
|
||||
has_session_pin = true;
|
||||
}
|
||||
}
|
||||
else if (tag == 0x82) { //user pin
|
||||
if (file_sopin && file_sopin->data) {
|
||||
uint8_t dhash[33];
|
||||
dhash[0] = tag_len;
|
||||
double_hash_pin(p, tag_len, dhash+1);
|
||||
flash_write_data_to_file(file_sopin, dhash, sizeof(dhash));
|
||||
hash_multi(p, tag_len, session_sopin);
|
||||
has_session_sopin = true;
|
||||
}
|
||||
}
|
||||
else if (tag == 0x91) { //user pin
|
||||
file_t *tf = search_by_fid(0x1082, NULL, SPECIFY_EF);
|
||||
if (tf && tf->data) {
|
||||
flash_write_data_to_file(tf, p, tag_len);
|
||||
}
|
||||
if (file_retries_pin1 && file_retries_pin1->data) {
|
||||
flash_write_data_to_file(file_retries_pin1, p, tag_len);
|
||||
}
|
||||
}
|
||||
else if (tag == 0x92) {
|
||||
dkeks = *p;
|
||||
current_dkeks = 0;
|
||||
}
|
||||
p += tag_len;
|
||||
}
|
||||
else if (tag == 0x92) {
|
||||
dkeks = *p;
|
||||
current_dkeks = 0;
|
||||
}
|
||||
p += tag_len;
|
||||
}
|
||||
p = random_bytes_get(32);
|
||||
memset(tmp_dkek, 0, sizeof(tmp_dkek));
|
||||
memcpy(tmp_dkek, p, IV_SIZE);
|
||||
if (dkeks == 0) {
|
||||
p = random_bytes_get(32);
|
||||
memcpy(tmp_dkek+IV_SIZE, p, 32);
|
||||
encrypt(session_pin, tmp_dkek, tmp_dkek+IV_SIZE, 32);
|
||||
file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF);
|
||||
flash_write_data_to_file(tf, tmp_dkek, sizeof(tmp_dkek));
|
||||
memset(tmp_dkek, 0, sizeof(tmp_dkek));
|
||||
memcpy(tmp_dkek, p, IV_SIZE);
|
||||
if (dkeks == 0) {
|
||||
p = random_bytes_get(32);
|
||||
memcpy(tmp_dkek+IV_SIZE, p, 32);
|
||||
encrypt(session_pin, tmp_dkek, tmp_dkek+IV_SIZE, 32);
|
||||
file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF);
|
||||
flash_write_data_to_file(tf, tmp_dkek, sizeof(tmp_dkek));
|
||||
}
|
||||
low_flash_available();
|
||||
}
|
||||
else { //free memory bytes request
|
||||
int heap_left = heapLeft();
|
||||
res_APDU[0] = ((heap_left >> 24) & 0xff);
|
||||
res_APDU[1] = ((heap_left >> 16) & 0xff);
|
||||
res_APDU[2] = ((heap_left >> 8) & 0xff);
|
||||
res_APDU[3] = ((heap_left >> 0) & 0xff);
|
||||
res_APDU[4] = 0;
|
||||
res_APDU[5] = HSM_VERSION_MAJOR;
|
||||
res_APDU[6] = HSM_VERSION_MINOR;
|
||||
res_APDU_size = 7;
|
||||
}
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2015 Frank Morgner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
*/
|
||||
#ifndef _CCID_TYPES_H
|
||||
#define _CCID_TYPES_H
|
||||
|
||||
#include "pico/types.h"
|
||||
#include "hardware/structs/usb.h"
|
||||
|
||||
#define USB_REQ_CCID 0xA1
|
||||
|
||||
#define CCID_CONTROL_ABORT 0x01
|
||||
#define CCID_CONTROL_GET_CLOCK_FREQUENCIES 0x02
|
||||
#define CCID_CONTROL_GET_DATA_RATES 0x03
|
||||
|
||||
#define CCID_OPERATION_VERIFY 0x00;
|
||||
#define CCID_OPERATION_MODIFY 0x01;
|
||||
#define CCID_ENTRY_VALIDATE 0x02
|
||||
|
||||
#define CCID_BERROR_CMD_ABORTED 0xff /** Host aborted the current activity */
|
||||
#define CCID_BERROR_ICC_MUTE 0xfe /** CCID timed out while talking to the ICC */
|
||||
#define CCID_BERROR_XFR_PARITY_ERROR 0xfd /** Parity error while talking to the ICC */
|
||||
#define CCID_BERROR_XFR_OVERRUN 0xfc /** Overrun error while talking to the ICC */
|
||||
#define CCID_BERROR_HW_ERROR 0xfb /** An all inclusive hardware error occurred */
|
||||
#define CCID_BERROR_BAD_ATR_TS 0xf
|
||||
#define CCID_BERROR_BAD_ATR_TCK 0xf
|
||||
#define CCID_BERROR_ICC_PROTOCOL_NOT_SUPPORTED 0xf6
|
||||
#define CCID_BERROR_ICC_CLASS_NOT_SUPPORTED 0xf5
|
||||
#define CCID_BERROR_PROCEDURE_BYTE_CONFLICT 0xf4
|
||||
#define CCID_BERROR_DEACTIVATED_PROTOCOL 0xf3
|
||||
#define CCID_BERROR_BUSY_WITH_AUTO_SEQUENCE 0xf2 /** Automatic Sequence Ongoing */
|
||||
#define CCID_BERROR_PIN_TIMEOUT 0xf0
|
||||
#define CCID_BERROR_PIN_CANCELLED 0xef
|
||||
#define CCID_BERROR_CMD_SLOT_BUSY 0xe0 /** A second command was sent to a slot which was already processing a command. */
|
||||
#define CCID_BERROR_CMD_NOT_SUPPORTED 0x00
|
||||
#define CCID_BERROR_OK 0x00
|
||||
|
||||
#define CCID_BSTATUS_OK_ACTIVE 0x00 /** No error. An ICC is present and active */
|
||||
#define CCID_BSTATUS_OK_INACTIVE 0x01 /** No error. ICC is present and inactive */
|
||||
#define CCID_BSTATUS_OK_NOICC 0x02 /** No error. No ICC is present */
|
||||
#define CCID_BSTATUS_ERROR_ACTIVE 0x40 /** Failed. An ICC is present and active */
|
||||
#define CCID_BSTATUS_ERROR_INACTIVE 0x41 /** Failed. ICC is present and inactive */
|
||||
#define CCID_BSTATUS_ERROR_NOICC 0x42 /** Failed. No ICC is present */
|
||||
|
||||
#define CCID_WLEVEL_DIRECT __constant_cpu_to_le16(0) /** APDU begins and ends with this command */
|
||||
#define CCID_WLEVEL_CHAIN_NEXT_XFRBLOCK __constant_cpu_to_le16(1) /** APDU begins with this command, and continue in the next PC_to_RDR_XfrBlock */
|
||||
#define CCID_WLEVEL_CHAIN_END __constant_cpu_to_le16(2) /** abData field continues a command APDU and ends the APDU command */
|
||||
#define CCID_WLEVEL_CHAIN_CONTINUE __constant_cpu_to_le16(3) /** abData field continues a command APDU and another block is to follow */
|
||||
#define CCID_WLEVEL_RESPONSE_IN_DATABLOCK __constant_cpu_to_le16(0x10) /** empty abData field, continuation of response APDU is expected in the next RDR_to_PC_DataBlock */
|
||||
|
||||
#define CCID_PIN_ENCODING_BIN 0x00
|
||||
#define CCID_PIN_ENCODING_BCD 0x01
|
||||
#define CCID_PIN_ENCODING_ASCII 0x02
|
||||
#define CCID_PIN_UNITS_BYTES 0x80
|
||||
#define CCID_PIN_JUSTIFY_RIGHT 0x04
|
||||
#define CCID_PIN_CONFIRM_NEW 0x01
|
||||
#define CCID_PIN_INSERT_OLD 0x02
|
||||
#define CCID_PIN_NO_MSG 0x00
|
||||
#define CCID_PIN_MSG1 0x01
|
||||
#define CCID_PIN_MSG2 0x02
|
||||
#define CCID_PIN_MSG_REF 0x03
|
||||
#define CCID_PIN_MSG_DEFAULT 0xff
|
||||
|
||||
#define CCID_SLOTS_UNCHANGED 0x00
|
||||
#define CCID_SLOT1_CARD_PRESENT 0x01
|
||||
#define CCID_SLOT1_CHANGED 0x02
|
||||
#define CCID_SLOT2_CARD_PRESENT 0x04
|
||||
#define CCID_SLOT2_CHANGED 0x08
|
||||
#define CCID_SLOT3_CARD_PRESENT 0x10
|
||||
#define CCID_SLOT3_CHANGED 0x20
|
||||
#define CCID_SLOT4_CARD_PRESENT 0x40
|
||||
#define CCID_SLOT4_CHANGED 0x80
|
||||
|
||||
#define CCID_EXT_APDU_MAX (4 + 3 + 0xffff + 3)
|
||||
#define CCID_SHORT_APDU_MAX (4 + 1 + 0xff + 1)
|
||||
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdCCID;
|
||||
uint8_t bMaxSlotIndex;
|
||||
uint8_t bVoltageSupport;
|
||||
uint32_t dwProtocols;
|
||||
uint32_t dwDefaultClock;
|
||||
uint32_t dwMaximumClock;
|
||||
uint8_t bNumClockSupport;
|
||||
uint32_t dwDataRate;
|
||||
uint32_t dwMaxDataRate;
|
||||
uint8_t bNumDataRatesSupported;
|
||||
uint32_t dwMaxIFSD;
|
||||
uint32_t dwSynchProtocols;
|
||||
uint32_t dwMechanical;
|
||||
uint32_t dwFeatures;
|
||||
uint32_t dwMaxCCIDMessageLength;
|
||||
uint8_t bClassGetResponse;
|
||||
uint8_t bclassEnvelope;
|
||||
uint16_t wLcdLayout;
|
||||
uint8_t bPINSupport;
|
||||
uint8_t bMaxCCIDBusySlots;
|
||||
} class_desc_ccid_t;
|
||||
|
||||
struct abProtocolDataStructure_T0 {
|
||||
uint8_t bmFindexDindex;
|
||||
uint8_t bmTCCKST0;
|
||||
uint8_t bGuardTimeT0;
|
||||
uint8_t bWaitingIntegerT0;
|
||||
uint8_t bClockStop;
|
||||
} __packed;
|
||||
|
||||
struct abProtocolDataStructure_T1 {
|
||||
uint8_t bmFindexDindex;
|
||||
uint8_t bmTCCKST1;
|
||||
uint8_t bGuardTimeT1;
|
||||
uint8_t bWaitingIntegersT1;
|
||||
uint8_t bClockStop;
|
||||
uint8_t bIFSC;
|
||||
uint8_t bNadValue;
|
||||
} __packed;
|
||||
|
||||
struct abPINDataStucture_Verification {
|
||||
uint8_t bTimeOut;
|
||||
uint8_t bmFormatString;
|
||||
uint8_t bmPINBlockString;
|
||||
uint8_t bmPINLengthFormat;
|
||||
uint16_t wPINMaxExtraDigit;
|
||||
uint8_t bEntryValidationCondition;
|
||||
uint8_t bNumberMessage;
|
||||
uint16_t wLangId;
|
||||
uint8_t bMsgIndex;
|
||||
uint8_t bTeoPrologue1;
|
||||
uint16_t bTeoPrologue2;
|
||||
} __packed;
|
||||
|
||||
struct abPINDataStucture_Modification {
|
||||
uint8_t bTimeOut;
|
||||
uint8_t bmFormatString;
|
||||
uint8_t bmPINBlockString;
|
||||
uint8_t bmPINLengthFormat;
|
||||
uint8_t bInsertionOffsetOld;
|
||||
uint8_t bInsertionOffsetNew;
|
||||
uint16_t wPINMaxExtraDigit;
|
||||
uint8_t bConfirmPIN;
|
||||
uint8_t bEntryValidationCondition;
|
||||
uint8_t bNumberMessage;
|
||||
uint16_t wLangId;
|
||||
uint8_t bMsgIndex1;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_XfrBlock {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bBWI;
|
||||
uint16_t wLevelParameter;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_IccPowerOff {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_GetSlotStatus {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_GetParameters {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_ResetParameters {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_SetParameters {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bProtocolNum;
|
||||
uint16_t abRFU;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_Secure {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bBWI;
|
||||
uint16_t wLevelParameter;
|
||||
} __packed;
|
||||
|
||||
struct PC_to_RDR_IccPowerOn {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bPowerSelect;
|
||||
uint16_t abRFU;
|
||||
} __packed;
|
||||
|
||||
struct RDR_to_PC_SlotStatus {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bStatus;
|
||||
uint8_t bError;
|
||||
uint8_t bClockStatus;
|
||||
} __packed;
|
||||
|
||||
struct RDR_to_PC_DataBlock {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bStatus;
|
||||
uint8_t bError;
|
||||
uint8_t bChainParameter;
|
||||
} __packed;
|
||||
|
||||
struct RDR_to_PC_Parameters {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bStatus;
|
||||
uint8_t bError;
|
||||
uint8_t bProtocolNum;
|
||||
} __packed;
|
||||
|
||||
struct RDR_to_PC_NotifySlotChange {
|
||||
uint8_t bMessageType;
|
||||
uint8_t bmSlotICCState; /* we support 1 slots, so we need 2*1 bits = 1 byte */
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user