Skip to content

Commit

Permalink
Merge branch 'rng-error-check'
Browse files Browse the repository at this point in the history
Check for the errors coming from getting the random data
Add GET_RANDOM command
  • Loading branch information
szszszsz committed Aug 23, 2021
2 parents a86c0f5 + 190715b commit 46f2017
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 33 deletions.
48 changes: 26 additions & 22 deletions src/ccid/CcidLocalAccess.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@


#include <FlashStorage.h>
#include <sys/param.h>
#include "stm32f10x.h"
#include "platform_config.h"
#include "hw_config.h"
Expand Down Expand Up @@ -429,12 +430,8 @@ unsigned short CcidDecipher (unsigned char* nRetSize)
*******************************************************************************/

unsigned short CcidGetChallenge (int nReceiveLength, unsigned char* nReceiveData)
unsigned short CcidGetChallenge (const size_t dest_size, unsigned char* dest)
{
int cRet;

int n;

// Command
tSCT.cAPDU[CCID_CLA] = 0x00;
tSCT.cAPDU[CCID_INS] = 0x84;
Expand All @@ -443,29 +440,30 @@ unsigned short CcidGetChallenge (int nReceiveLength, unsigned char* nReceiveData

tSCT.cAPDU[CCID_LC] = 0;

// Something to receive
// tSCT.cAPDU.nLe = nReceiveLength; // nReceiveLength;

// Encode Le
if (nReceiveLength > 255)
if (dest_size > 255)
{
tSCT.cAPDU[CCID_DATA] = 0;
tSCT.cAPDU[CCID_DATA + 1] = (unsigned char) nReceiveLength >> 8;
tSCT.cAPDU[CCID_DATA + 2] = (unsigned char) (nReceiveLength & 0xFF);
tSCT.cAPDU[CCID_DATA + 1] = (unsigned char) dest_size >> 8;
tSCT.cAPDU[CCID_DATA + 2] = (unsigned char) (dest_size & 0xFF);
}
else
tSCT.cAPDU[CCID_DATA] = nReceiveLength;

cRet = SendAPDU (&tSCT);

n = tSCT.cAPDUAnswerLength;
if (n < nReceiveLength)
{
n = nReceiveLength;
tSCT.cAPDU[CCID_DATA] = dest_size;

int cRet = SendAPDU (&tSCT);

// clamp to the received data size, and requested length
// if response is shorter than requested, the bytes in the target buffer are not touched at all
const int received_data_size_total = tSCT.cAPDUAnswerLength;
const int header_size = CCID_DATA;
const int total_received_data_size = received_data_size_total - header_size;
const size_t total_data_buffer_size = sizeof(tSCT.cAPDU) - header_size;
const int sizeToCopySrc = MIN(total_data_buffer_size, total_received_data_size); // clamp to source data size
const int sizeToCopyFinal = MIN(dest_size, sizeToCopySrc); // clamp to target buffer size
if (cRet == APDU_ANSWER_COMMAND_CORRECT && sizeToCopyFinal > 0) {
memcpy (dest, &(tSCT.cAPDU[CCID_DATA]), sizeToCopyFinal);
}

memcpy (nReceiveData, &(tSCT.cAPDU[CCID_DATA]), n - CCID_DATA);

return cRet;
}

Expand Down Expand Up @@ -618,7 +616,13 @@ u32 getRandomNumber (u32 Size_u32, u8 * Data_pu8)
}

// Get a random number from smartcard
CcidGetChallenge (Size_u32, Data_pu8);
for (int i = 0; i < 10; ++i) {
if (CcidGetChallenge(Size_u32, Data_pu8) == APDU_ANSWER_COMMAND_CORRECT) {
return TRUE;
}
Delay_noUSBCheck(1);
}
return (FALSE);

#ifdef GENERATE_RANDOM_NUMBER_WITH_2ND_SOURCE
// FIXME check does this actually add entropy?
Expand Down
3 changes: 2 additions & 1 deletion src/inc/CcidLocalAccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define CCID_LOCAL_ACCESS

#include "stm32f10x.h"
#include <stddef.h>

// #ifdef NOT_USED
#define APDU_ANSWER_T0_COMMAND_CORRECT 0x6100 /* Command correct, xx bytes available in response (normally used under T=0 or for commands
Expand Down Expand Up @@ -142,7 +143,7 @@ unsigned short CcidChangePin (unsigned char cPinNr, const uint8_t* szPin, const
unsigned short CcidVerifyPin (unsigned char cPinNr, const uint8_t* szPin);
unsigned short CcidUnblockPin(uint8_t *new_pin);
unsigned short CcidDecipher (unsigned char* nRetSize);
unsigned short CcidGetChallenge (int nReceiveLength, unsigned char* nReceiveData);
unsigned short CcidGetChallenge (size_t dest_size, unsigned char* dest);
unsigned short CcidPutAesKey (unsigned int cKeyLen, unsigned char* pcAES_Key);
int CcidAesDecSub (int nSendLength, unsigned char* cSendData, int nReceiveLength, unsigned char* cReceiveData);
int CcidAesDec (int nSendLength, unsigned char* cSendData, int nReceiveLength, unsigned char* cReceiveData);
Expand Down
1 change: 1 addition & 0 deletions src/inc/password_safe.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ u32 BuildPasswordSafeKey_u32 (void);
u8 PWS_WriteSlot (u8 Slot_u8, typePasswordSafeSlot_st * Slot_st);
u8 PWS_ReadSlot (u8 Slot_u8, typePasswordSafeSlot_st * Slot_st);

u32 IsBufferEmpty_u32(const u8 * buffer, size_t buffer_len);


#endif /* PASSWORD_SAFE_H_ */
3 changes: 3 additions & 0 deletions src/inc/report_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define CMD_VERIFY_OTP_CODE 0x18
#define CMD_FIRMWARE_UPDATE 0x19
#define CMD_CHANGE_FIRMWARE_PASSWORD 0x1A
#define CMD_GET_RANDOM 0x1B


#define CMD_GET_PW_SAFE_SLOT_STATUS 0x60
Expand Down Expand Up @@ -236,6 +237,8 @@ uint8_t cmd_enableFirmwareUpdate(uint8_t *report, uint8_t *output);

uint8_t cmd_changeFirmwarePassword(uint8_t *report, uint8_t *output);

uint8_t cmd_get_random(const uint8_t *const report, uint8_t *const output);


// START - OTP Test Routine --------------------------------
/*
Expand Down
13 changes: 13 additions & 0 deletions src/keyboard/report_protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ uint8_t parse_report(uint8_t * const report, uint8_t * const output) {
break;
#endif // ADD_DEBUG_COMMANDS

case CMD_GET_RANDOM:
cmd_get_random(report, output);
break;

case CMD_CHANGE_USER_PIN:
cmd_change_user_pin(report, output);
break;
Expand Down Expand Up @@ -297,6 +301,15 @@ uint8_t parse_report(uint8_t * const report, uint8_t * const output) {
return 0;
}

uint8_t cmd_get_random(const uint8_t *const report, uint8_t *const output) {
const unsigned int size_requested = report[CMD_DATA_OFFSET];
const unsigned int size_clamped = s_min(size_requested, KEYBOARD_FEATURE_COUNT-OUTPUT_CMD_RESULT_OFFSET-2);
const unsigned int operation_success = getRandomNumber(size_clamped, &output[OUTPUT_CMD_RESULT_OFFSET + 2]);
output[OUTPUT_CMD_RESULT_OFFSET] = operation_success;
output[OUTPUT_CMD_RESULT_OFFSET+1] = size_clamped;
return 0;
}

bool is_user_PIN_protection_enabled(void) { return *((uint8_t *) (SLOTS_PAGE1_ADDRESS + GLOBAL_CONFIG_OFFSET + 3)) == 1; }

uint8_t cmd_get_status(uint8_t *report, uint8_t *output) {
Expand Down
8 changes: 6 additions & 2 deletions src/pwd-safe/FlashStorage.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,9 @@ u8 CheckUpdatePin (u8 * Password_pu8, u32 PasswordLen_u32)
if (FALSE == UpdateSaltInit)
{
// Initialize Update Pin with default value
StoreNewUpdatePinHashInFlash ((u8 *) "12345678", 8);
if(!StoreNewUpdatePinHashInFlash((u8 *) "12345678", 8)){
return FALSE;
}
ReadUpdatePinSaltFromFlash (UpdatePinSalt_u8);
}

Expand Down Expand Up @@ -658,7 +660,9 @@ u8 StoreNewUpdatePinHashInFlash (u8 * Password_pu8, u32 PasswordLen_u32)
}

// Generate new salt
getRandomNumber (UPDATE_PIN_SALT_SIZE, UpdatePinSalt_u8);
if (getRandomNumber(UPDATE_PIN_SALT_SIZE, UpdatePinSalt_u8) == FALSE) {
return FALSE;
}

WriteUpdatePinSaltToFlash (UpdatePinSalt_u8);

Expand Down
14 changes: 8 additions & 6 deletions src/pwd-safe/HandleAesStorageKey.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,22 +195,24 @@ u32 BuildNewAesMasterKey_u32 (u8 * AdminPW_pu8, u8 * MasterKey_pu8)
RestartSmartcard ();

// Wait for next smartcard cmd
DelayMs (10);
DelayMs (20);

// Get a random number for the master key
if (FALSE == getRandomNumber (AES_KEYSIZE_256_BIT / 2, MasterKey_pu8))
{
return (FALSE);
return (CMD_STATUS_AES_CREATE_KEY_FAILED);
}

DelayMs (100);

// Get a random number for the master key
if (FALSE == getRandomNumber (AES_KEYSIZE_256_BIT / 2, &MasterKey_pu8[AES_KEYSIZE_256_BIT / 2]))
{
return (FALSE);
return (CMD_STATUS_AES_CREATE_KEY_FAILED);
}

// Wait for next smartcard cmd
DelayMs (10);
DelayMs (20);

// Unlock smartcard for sending master key
if (FALSE == cardAuthenticate (AdminPW_pu8))
Expand All @@ -219,10 +221,10 @@ u32 BuildNewAesMasterKey_u32 (u8 * AdminPW_pu8, u8 * MasterKey_pu8)
}

// Wait for next smartcard cmd
DelayMs (10);
DelayMs (20);

// Store master key in smartcard
int ret = sendAESMasterKey (AES_KEYSIZE_256_BIT, MasterKey_pu8);
int ret = sendAESMasterKey (AES_KEYSIZE_256_BIT, MasterKey_pu8);

if (TRUE != ret)
{
Expand Down
27 changes: 25 additions & 2 deletions src/pwd-safe/password_safe.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,19 @@ u8 Key_au8[AES_KEYSIZE_256_BIT];
return (TRUE);
}

u32 IsBufferEmpty_u32(const u8 * buffer, size_t buffer_len){
// check if buffer is filled with zeroes or 0xFFs
int diff = 0, i, diff_FF = 0xFF;
for (i = 0; i < buffer_len; ++i) {
diff |= buffer[i];
diff_FF &= buffer[i];
}
if (diff == 0 || diff_FF == 0xFF) {
return (TRUE);
}

return (FALSE);
}

/*******************************************************************************
Expand All @@ -651,16 +664,26 @@ u8 PWS_DecryptedPasswordSafeKey (void)

CI_LocalPrintf ("Decrypt password safe key\r\n");

// Get the encrypted hidden volume slots key
// Get the encrypted password safe key
ReadPasswordSafeKey (DecryptedPasswordSafeKey_au8);

// Decrypt the slots key of the hidden volumes
const size_t halfKeySize = sizeof DecryptedPasswordSafeKey_au8 / 2;
if ( IsBufferEmpty_u32(DecryptedPasswordSafeKey_au8, halfKeySize)
|| IsBufferEmpty_u32(DecryptedPasswordSafeKey_au8 + halfKeySize, halfKeySize)) {
return FALSE;
}

// Decrypt the slots key of the password safe
if (FALSE == DecryptKeyViaSmartcard_u32 (DecryptedPasswordSafeKey_au8))
{
return (FALSE);
}

if ( IsBufferEmpty_u32(DecryptedPasswordSafeKey_au8, halfKeySize)
|| IsBufferEmpty_u32(DecryptedPasswordSafeKey_au8 + halfKeySize, halfKeySize)) {
return FALSE;
}

// Key is ready
DecryptedPasswordSafeKey_u8 = TRUE;

Expand Down

0 comments on commit 46f2017

Please sign in to comment.