u8 GetHiddenVolumeKeyFromUserpassword (u8 * Userpassword_pu8, u8 * DecryptedHiddenVolumeKey_au8) { u8 ret_u8; // Expand user password to 256 bit size CI_LocalPrintf ("User password : "******"\r\n"); ret_u8 = GetHiddenVolumeDataKeyFromUserpassword (Userpassword_pu8, DecryptedHiddenVolumeKey_au8); if (HIDDEN_VOLUME_OUTPUT_STATUS_OK != ret_u8) { return (ret_u8); } CI_LocalPrintf ("Uncrypted hidden volume key : "); HexPrint (AES_KEYSIZE_256_BIT, DecryptedHiddenVolumeKey_au8); CI_LocalPrintf ("\r\n"); // Clear the critical memory memset (Userpassword_pu8, 0, strlen ((char *) Userpassword_pu8)); return (ret_u8); }
u8 GetHiddenVolumeSlotKey (u8 * HiddenVolumeKey_pu8, u8 * Password_pu8, u32 PasswordLen_u32, u8 * Salt_pu8, u32 SaltLen_u32) { u8 output_au8[64]; #ifdef LOCAL_DEBUG CI_LocalPrintf ("Password_pu8 : Len %2d -%s-\r\n", PasswordLen_u32, Password_pu8); CI_LocalPrintf ("Salt : "); HexPrint (SaltLen_u32, Salt_pu8); CI_LocalPrintf ("\r\n"); #endif #ifndef SAVE_FLASH_MEMORY_NO_PBKDF2 pbkdf2 (output_au8, Password_pu8, PasswordLen_u32, Salt_pu8, SaltLen_u32); memcpy (HiddenVolumeKey_pu8, output_au8, AES_KEYSIZE_256_BIT); // copy 256 bit from the 512 bit output #else CI_LocalPrintf ("*** WARNING low security for hidden volumes ***\r\n"); // use the base key as the key #endif #ifdef LOCAL_DEBUG CI_LocalPrintf ("Key : "); HexPrint (32, HiddenVolumeKey_pu8); CI_LocalPrintf ("\r\n"); #endif return (TRUE); }
u8 HV_WriteSlot_u8 (u8 SlotNr_u8, HiddenVolumeKeySlot_tst * SlotData_st, u8 * SlotKey_pu8) { u32 i; u8 Buffer_au8[HV_SLOT_SIZE]; // u8 HiddenVolumeSlotsKey_au8[AES_KEYSIZE_256_BIT]; if (FALSE == DecryptedHiddenVolumeSlotsActive_u8) { return (FALSE); // Slot data is not in ram } // Fill buffer with random numbers for (i = 0; i < HV_SLOT_SIZE; i++) { Buffer_au8[i] = rand () % 256; } // Set magic number // SlotData_st->MagicNumber_u32 = HV_MAGIC_NUMBER_SLOT_ENTRY; // Set CRC32 SlotData_st->Crc_u32 = generateCRC_len ((u8 *) SlotData_st, (sizeof (HiddenVolumeKeySlot_tst) / 4) - 1); // -1 for CRC variable #ifdef DEBUG_KEYS CI_LocalPrintf ("HV_WriteSlot_u8 %d - CRC 0x%08x\r\n", SlotNr_u8, SlotData_st->Crc_u32); CI_LocalPrintf ("Decrypted data :\r\n"); HexPrint (sizeof (HiddenVolumeKeySlot_tst), SlotData_st); CI_LocalPrintf ("\r\n"); #endif memcpy (Buffer_au8, (u8 *) SlotData_st, sizeof (HiddenVolumeKeySlot_tst)); // Encrypt slot data AES_KeyEncryption (HV_SLOT_SIZE, Buffer_au8, SlotKey_pu8, AES_PMODE_CIPHER, SlotNr_u8); // Write encrypted slot data into ram memcpy ((u8 *) (DecryptedHiddenVolumeSlotsData_au8 + HV_SALT_SIZE + SlotNr_u8 * HV_SLOT_SIZE), Buffer_au8, HV_SLOT_SIZE); #ifdef DEBUG_KEYS CI_LocalPrintf ("Encrypted data :\r\n"); HexPrint (HV_SLOT_SIZE, &DecryptedHiddenVolumeSlotsData_au8[HV_SALT_SIZE + SlotNr_u8 * HV_SLOT_SIZE]); CI_LocalPrintf ("\r\n"); #endif // Encrypt all slots data (max 256 byte per encryption) AES_KeyEncryption (HV_SLOT_COUNT * HV_SLOT_SIZE, &DecryptedHiddenVolumeSlotsData_au8[HV_SALT_SIZE], DecryptedHiddenVolumeSlotsKey_au8, AES_PMODE_CIPHER, SlotNr_u8); // Write ram data to flash flashc_memcpy ((u8 *) (HV_SALT_START_ADDRESS + HV_SALT_SIZE), &DecryptedHiddenVolumeSlotsData_au8[HV_SALT_SIZE], HV_SLOT_SIZE * HV_SLOT_COUNT, TRUE); return (TRUE); }
u8 HV_InitAllSlotData (void) { // u8 RandomCharArray_au8[16]; u32 i; // Create salt for (i = 0; i < 2; i++) { // Get a random number from smart card if (FALSE == GetRandomNumber_u32 (16, &DecryptedHiddenVolumeSlotsData_au8[i * 16])) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return (FALSE); } } // Fill hidden volume flash page with random chars for (i = 0; i < 16; i++) { // Get a random number from smart card if (FALSE == GetRandomNumber_u32 (16, &DecryptedHiddenVolumeSlotsData_au8[HV_SALT_SIZE + i * 16])) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return (FALSE); } } // Write magic number to flash DecryptedHiddenVolumeMagicNumber_u32 = HV_MAGIC_NUMBER_INIT; flashc_memcpy ((u8 *) HV_MAGIC_NUMBER_ADDRESS, &DecryptedHiddenVolumeMagicNumber_u32, HV_MAGIC_NUMBER_SIZE, TRUE); // Write ram data to flash flashc_memcpy ((u8 *) HV_SALT_START_ADDRESS, DecryptedHiddenVolumeSlotsData_au8, HV_SALT_SIZE + HV_SLOT_SIZE * HV_SLOT_COUNT, TRUE); CI_LocalPrintf ("Init hidden volume slot data\r\n"); CI_LocalPrintf ("Salt\r\n"); CI_LocalPrintf ("Encrypted data :\r\n"); HexPrint (HV_SALT_SIZE, DecryptedHiddenVolumeSlotsData_au8); CI_LocalPrintf ("\r\n\r\n"); for (i = 0; i < HV_SLOT_COUNT; i++) { CI_LocalPrintf ("Slot %d\r\n", i); CI_LocalPrintf ("Encrypted data :\r\n"); HexPrint (HV_SLOT_SIZE, DecryptedHiddenVolumeSlotsData_au8 + HV_SALT_SIZE + i * HV_SLOT_SIZE); CI_LocalPrintf ("\r\n\r\n"); } return (TRUE); }
u8 InitRamdomBaseForHiddenKey (void) { u8 BaseKey_au8[AES_KEYSIZE_256_BIT]; LA_SC_StartSmartcard (); CI_TickLocalPrintf ("InitRamdomBaseForHiddenKey\r\n"); // Get a random number for the base key if (FALSE == GetRandomNumber_u32 (AES_KEYSIZE_256_BIT / 2, BaseKey_au8)) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return (FALSE); } // Get a random number for the storage key if (FALSE == GetRandomNumber_u32 (AES_KEYSIZE_256_BIT / 2, &BaseKey_au8[AES_KEYSIZE_256_BIT / 2])) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return (FALSE); } CI_LocalPrintf ("Base key : "); HexPrint (AES_KEYSIZE_256_BIT, BaseKey_au8); CI_LocalPrintf ("\r\n"); // Save base key WriteHiddenVolumeSlotKey (BaseKey_au8); // Invalidate hidden volume data DecryptedHiddenVolumeSlotsActive_u8 = FALSE; return (TRUE); }
u8 GetHiddenVolumeDataKeyFromUserpassword (u8 * Userpassword_pu8, u8 * DecryptedHiddenVolumeKey_pu8) { u32 i; u8 HiddenVolumeSlotKey_u8[AES_KEYSIZE_256_BIT]; HiddenVolumeKeySlot_tst SlotData_st; // Are the hidden volume slots decrypted ? if (TRUE != DecryptedHiddenVolumeSlotsActive_u8) { CI_LocalPrintf ("Slot data not encrypted\r\n"); return (HIDDEN_VOLUME_OUTPUT_STATUS_NO_USER_PASSWORD_UNLOCK); // No } GetHiddenVolumeSlotKey (HiddenVolumeSlotKey_u8, Userpassword_pu8, strlen ((char *) Userpassword_pu8), DecryptedHiddenVolumeSlotsData_au8, HV_SALT_SIZE); CI_LocalPrintf ("Hidden volume slot key : "); HexPrint (AES_KEYSIZE_256_BIT, HiddenVolumeSlotKey_u8); CI_LocalPrintf ("\r\n"); // Test HiddenVolumeKey for each slot for (i = 0; i < HV_SLOT_COUNT; i++) { if (TRUE == HV_ReadSlot_u8 (i, &SlotData_st, HiddenVolumeSlotKey_u8)) { memcpy (DecryptedHiddenVolumeKey_pu8, SlotData_st.AesKey_au8, AES_KEYSIZE_256_BIT); SetHiddenVolumeSizes_u32 (SlotData_st.StartBlock_u32, SlotData_st.EndBlock_u32); CI_LocalPrintf ("Hidden volume key found - slot %d\r\n", i); CI_LocalPrintf ("Volume size %d MB\r\n", (SlotData_st.EndBlock_u32 - SlotData_st.StartBlock_u32) / 2048); CI_LocalPrintf ("StartBlock %9d - %5d MB - %03d %%\r\n", SlotData_st.StartBlock_u32, SlotData_st.StartBlock_u32 / 2048, (u32) ((u64) SlotData_st.StartBlock_u32 * (u64) 100 / (u64) gSdEndOfCard_u32)); CI_LocalPrintf ("EndBlock %9d - %5d MB - %03d %%\r\n", SlotData_st.EndBlock_u32, SlotData_st.EndBlock_u32 / 2048, (u32) ((u64) (SlotData_st.EndBlock_u32 + 1) * (u64) 100 / (u64) gSdEndOfCard_u32)); return (HIDDEN_VOLUME_OUTPUT_STATUS_OK); } } CI_LocalPrintf ("Can't find slot from password\r\n"); return (HIDDEN_VOLUME_OUTPUT_STATUS_WRONG_PASSWORD); /* u32 i,n,i1; u8 pointer_u8; u8 Slot_u8;* // shake it a little bit pointer_u8 = 0; for (i=0;i<1000;i++) { srand (i + AESKey_pu8[pointer_u8]*119); for (i1=0;i1<n;i1++) { AESKey_pu8[pointer_u8] = (u8)((u16)AESKey_pu8[pointer_u8] + (u16)Userpassword_pu8[i1] + (u16)(rand () % 256)); pointer_u8 += (u8)((u16)AESKey_pu8[pointer_u8] + (u16)Userpassword_pu8[i1] + (u16)(rand () % 256)); pointer_u8 = pointer_u8 % AES_KEYSIZE_256_BIT; } } */ }
u8 HV_PrintSlotData_u8 (u8 SlotNr_u8, HiddenVolumeKeySlot_tst * SlotData_st) { #ifdef LOCAL_DEBUG CI_LocalPrintf ("Hidden volume slot %d\r\n", SlotNr_u8); // CI_LocalPrintf ("MagicNumber 0x%08x\r\n",SlotData_st->MagicNumber_u32); CI_LocalPrintf ("StartBlock %9d - %5d MB - %03d %%\r\n", SlotData_st->StartBlock_u32, SlotData_st->StartBlock_u32 / 2048, (u32) ((u64) SlotData_st->StartBlock_u32 * (u64) 100 / (u64) gSdEndOfCard_u32)); CI_LocalPrintf ("EndBlock %9d - %5d MB - %03d %%\r\n", SlotData_st->EndBlock_u32, SlotData_st->EndBlock_u32 / 2048, (u32) ((u64) (SlotData_st->EndBlock_u32 + 1) * (u64) 100 / (u64) gSdEndOfCard_u32)); CI_LocalPrintf ("AesKey "); HexPrint (32, SlotData_st->AesKey_au8); CI_LocalPrintf ("\r\n"); CI_LocalPrintf ("Crc_u32 0x%08x\r\n", SlotData_st->Crc_u32); #endif return (TRUE); }
void IBN_DFU_Tests (unsigned char nParamsGet_u8,unsigned char CMD_u8,unsigned int Param_u32,unsigned char *String_pu8) { u8 DFU_String_au8[4]; if (0 == nParamsGet_u8) { CI_LocalPrintf ("DFU test functions\r\n"); CI_LocalPrintf ("\r\n"); CI_LocalPrintf ("0 Show ISP Config 1 word\r\n"); CI_LocalPrintf ("1 Enable DFU at next start\r\n"); CI_LocalPrintf ("2 Disable DFU at next start\r\n"); CI_LocalPrintf ("3 Show security bit\r\n"); CI_LocalPrintf ("4 Set security bit\r\n"); CI_LocalPrintf ("5 Show bootloader protected size\r\n"); CI_LocalPrintf ("6 Set bootloader protected size = 0x2000\r\n"); CI_LocalPrintf ("7 Reset system\r\n"); CI_LocalPrintf ("\r\n"); return; } switch (CMD_u8) { case 0: memcpy (DFU_String_au8,(void*)TOOL_DFU_ISP_CONFIG_ADDR_1,4); CI_LocalPrintf ("ISP Config 1 word : "); HexPrint (4,DFU_String_au8); CI_LocalPrintf ("\r\n"); break; case 1 : CI_LocalPrintf ("Enable DFU\r\n"); DFU_EnableFirmwareUpdate (); break; case 2 : CI_LocalPrintf ("Disable DFU\r\n"); DFU_DisableFirmwareUpdate (); break; case 3 : CI_LocalPrintf ("Security bit : %d\r\n",flashc_is_security_bit_active ()); break; case 4 : CI_LocalPrintf ("Activate security bit\r\n"); flashc_activate_security_bit (); break; case 5 : CI_LocalPrintf ("Bootloader protected : 0x%04x\r\n",flashc_get_bootloader_protected_size ()); break; case 6 : CI_LocalPrintf ("Set bootloader protected 0x2000\r\n"); flashc_set_bootloader_protected_size (0x2000); break; case 7 : DFU_ResetCPU (); break; } }
u8 PWS_EraseSlot (u8 Slot_u8) { u8* WritePointer_pu8; u8* AesKeyPointer_pu8; void* p; #if (defined __GNUC__) && (defined __AVR32__) __attribute__ ((__aligned__ (4))) #elif (defined __ICCAVR32__) #pragma data_alignment = 4 #endif typePasswordSafeSlot_st Slot_st; CI_LocalPrintf ("PWS_EraseSlot: Slot %d\r\n", Slot_u8); if (PWS_SLOT_COUNT <= Slot_u8) { CI_LocalPrintf ("PWS_EraseSlot: Wrong slot nr %d\r\n", Slot_u8); return (FALSE); } // Check for unlock if (FALSE == PWS_GetDecryptedPasswordSafeKey (&AesKeyPointer_pu8)) { CI_LocalPrintf ("PWS_EraseSlot: user password not entered\r\n"); return (FALSE); } // //LED_GreenOn (); // Clear data in slot memset ((char *) &Slot_st, 0, PWS_SLOT_LENGTH); Slot_st.SlotActiv_u8 = PWS_SLOT_INACTIV_TOKEN; #ifdef ENABLE_IBN_PWS_TESTS_ENCRYPTION CI_LocalPrintf ("PWS_EraseSlot decrypted : "); HexPrint (PWS_SLOT_LENGTH, &Slot_st); CI_LocalPrintf ("\n\r"); #endif // Encrypt data (max 256 byte per encryption) unsigned char Slot_st_encrypted[PWS_SLOT_LENGTH]; aes_context aes_ctx; aes_setkey_enc (&aes_ctx, AesKeyPointer_pu8, 256); int i; for (i = 0; i < PWS_SLOT_LENGTH; i += 16) { aes_crypt_ecb (&aes_ctx, AES_ENCRYPT, &(((unsigned char *) (&Slot_st))[i]), &(Slot_st_encrypted[i])); } memcpy ((char *) &Slot_st, Slot_st_encrypted, PWS_SLOT_LENGTH); #ifdef ENABLE_IBN_PWS_TESTS_ENCRYPTION CI_LocalPrintf ("PWS_EraseSlot encrypted : "); HexPrint (PWS_SLOT_LENGTH, Slot_st_encrypted); CI_LocalPrintf ("\n\r"); #endif // Get write address WritePointer_pu8 = (u8 *) (PWS_FLASH_START_ADDRESS + (PWS_SLOT_LENGTH * Slot_u8)); // Write to flash uint8_t page_buffer[FLASH_PAGE_SIZE]; uint8_t* page = (uint8_t *) PWS_FLASH_START_ADDRESS; memcpy (page_buffer, page, FLASH_PAGE_SIZE); memcpy (page_buffer + (PWS_SLOT_LENGTH * Slot_u8), Slot_st_encrypted, PWS_SLOT_LENGTH); p = (void *) Slot_st_encrypted; FLASH_Unlock (); FLASH_ErasePage (PWS_FLASH_START_ADDRESS); write_data_to_flash (page_buffer, FLASH_PAGE_SIZE, PWS_FLASH_START_ADDRESS); FLASH_Lock (); // LED_GreenOff (); return (TRUE); }
u8 PWS_WriteSlot (u8 Slot_u8, typePasswordSafeSlot_st * Slot_st) { u8* WritePointer_pu8; u8* AesKeyPointer_pu8; void* p; CI_LocalPrintf ("PWS_WriteSlot: Slot %d. Name -%s- Loginname -%s- PW -%s-\r\n", Slot_u8, Slot_st->SlotName_au8, Slot_st->SlotLoginName_au8, Slot_st->SlotPassword_au8); if (PWS_SLOT_COUNT <= Slot_u8) { CI_LocalPrintf ("PWS_WriteSlot: Wrong slot nr %d\r\n", Slot_u8); return (FALSE); } if (FALSE == PWS_GetDecryptedPasswordSafeKey (&AesKeyPointer_pu8)) { CI_LocalPrintf ("PWS_WriteSlot: Key not decrypted\r\n"); return (FALSE); } // LED_GreenOn (); // Activate data in slot Slot_st->SlotActiv_u8 = PWS_SLOT_ACTIV_TOKEN; #ifdef ENABLE_IBN_PWS_TESTS_ENCRYPTION CI_LocalPrintf ("PWS_WriteSlot decrypted : "); HexPrint (PWS_SLOT_LENGTH, &Slot_st); CI_LocalPrintf ("\n\r"); #endif // Encrypt data (max 256 byte per encryption) unsigned char Slot_st_encrypted[PWS_SLOT_LENGTH]; aes_context aes_ctx; aes_setkey_enc (&aes_ctx, AesKeyPointer_pu8, 256); int i; for (i = 0; i < PWS_SLOT_LENGTH; i += 16) { aes_crypt_ecb (&aes_ctx, AES_ENCRYPT, &(((unsigned char *) (Slot_st))[i]), &(Slot_st_encrypted[i])); } memcpy (Slot_st, Slot_st_encrypted, PWS_SLOT_LENGTH); #ifdef ENABLE_IBN_PWS_TESTS_ENCRYPTION CI_LocalPrintf ("PWS_WriteSlot encrypted : "); HexPrint (PWS_SLOT_LENGTH, Slot_st_encrypted); CI_LocalPrintf ("\n\r"); #endif // Get write address WritePointer_pu8 = (u8 *) (PWS_FLASH_START_ADDRESS + (PWS_SLOT_LENGTH * Slot_u8)); // Write to flash uint8_t page_buffer[FLASH_PAGE_SIZE]; uint8_t* page = (uint8_t *) PWS_FLASH_START_ADDRESS; memcpy (page_buffer, page, FLASH_PAGE_SIZE); memcpy (page_buffer + (PWS_SLOT_LENGTH * Slot_u8), Slot_st_encrypted, PWS_SLOT_LENGTH); p = (void *) Slot_st_encrypted; FLASH_Unlock (); FLASH_ErasePage (PWS_FLASH_START_ADDRESS); write_data_to_flash (page_buffer, FLASH_PAGE_SIZE, PWS_FLASH_START_ADDRESS); FLASH_Lock (); // LED_GreenOff (); return (TRUE); }
void IBN_OTP_Tests (unsigned char nParamsGet_u8, unsigned char CMD_u8, unsigned int Param_u32, unsigned char* String_pu8) { u8 DFU_String_au8[4]; u32 Ret_u32; u32 i; #ifdef TIME_MEASURING_ENABLE u32 Runtime_u32; #endif u8* Data_pu8; u8 slot_no; u8 is_programmed; u32 result; if (0 == nParamsGet_u8) { CI_LocalPrintf ("OTP test functions\r\n"); CI_LocalPrintf ("\r\n"); CI_LocalPrintf ("0 ??\r\n"); CI_LocalPrintf ("1 Send char\r\n"); CI_LocalPrintf ("2 x CRC32 Check x=String\r\n"); CI_LocalPrintf ("3 Show hotp config [slot nr]\r\n"); CI_LocalPrintf ("4 Get HOTP [slot]\r\n"); CI_LocalPrintf ("5 Show HOTP counter page [slot]\r\n"); CI_LocalPrintf ("6 Show TOTP config [slot nr]\r\n"); CI_LocalPrintf ("7 Get TOTP time\r\n"); CI_LocalPrintf ("8 Set TOTP time\r\n"); CI_LocalPrintf ("\r\n"); return; } switch (CMD_u8) { case 0: CI_LocalPrintf ("ISP Config 1 word : "); check_backups (); HexPrint (4, DFU_String_au8); CI_LocalPrintf ("\r\n"); break; case 1: sendChar ('a'); sendChar ('b'); sendChar ('c'); break; case 2: // String_pu8 = "123456789"; CI_LocalPrintf ("CRC32 check : -%s- = ", String_pu8); #ifdef TIME_MEASURING_ENABLE TIME_MEASURING_Start (TIME_MEASURING_TIME_15); #endif CRC_InitCRC32 (); CRC_CalcBlockCRC32 (String_pu8, strlen ((char *) String_pu8)); Ret_u32 = CRC_GetCRC32 (); #ifdef TIME_MEASURING_ENABLE Runtime_u32 = TIME_MEASURING_Stop (TIME_MEASURING_TIME_15); #endif CI_LocalPrintf ("0x%08x\r\n", Ret_u32); #ifdef TIME_MEASURING_ENABLE CI_LocalPrintf ("CRC32 Runtime %ld usec\n\r", Runtime_u32 / TIME_MEASURING_TICKS_IN_USEC); #endif break; case 3: // Print hopt slot header /* slot structure: 1b 0x01 if slot is used (programmed) 15b slot name 20b secret 1b configuration flags: MSB [x|x|x|x|x|send token id|send enter after code?|no. of digits 6/8] LSB 12b token id 1b keyboard layout */ Data_pu8 = get_hotp_slot_addr (Param_u32); if (NULL == Data_pu8) { CI_LocalPrintf ("Wrong hopt slot %d\n\r", Param_u32); return; } if (0x01 == Data_pu8[0]) { CI_LocalPrintf ("slot %d is used\n\r", Param_u32); } else { CI_LocalPrintf ("slot %d is not used\n\r", Param_u32); } CI_LocalPrintf ("slot name -%.15.15s-\n\r", &Data_pu8[1]); CI_LocalPrintf (" : "); HexPrint (15, &Data_pu8[1]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Secret : "); HexPrint (20, &Data_pu8[16]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Config : "); HexPrint (1, &Data_pu8[36]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Token : "); HexPrint (12, &Data_pu8[37]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Keyboard: "); HexPrint (1, &Data_pu8[39]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("slot name -%.15.15s-\n\r", &Data_pu8[1]); break; case 4: // Get hopt slot slot_no = Param_u32; if (slot_no < NUMBER_OF_HOTP_SLOTS) // HOTP slot { is_programmed = *((u8 *) (hotp_slots[slot_no])); if (is_programmed == 0x01) { result = get_code_from_hotp_slot (slot_no); change_endian_u32 (result); CI_LocalPrintf ("HOPT %ld\n\r", result); } else { CI_LocalPrintf ("Slot %d not programmed\n\r", slot_no); } } else { CI_LocalPrintf ("Slot %d not a hopt slot\n\r", slot_no); } break; case 5: // Show hopt counter slot slot_no = Param_u32; if (slot_no < NUMBER_OF_HOTP_SLOTS) // HOTP slot { is_programmed = *((u8 *) (hotp_slots[slot_no])); Data_pu8 = (u8 *) hotp_slot_counters[slot_no]; CI_LocalPrintf ("Slot %d\n\r", slot_no); CI_LocalPrintf ("Counter %lld\n\r", get_counter_value ((u32) Data_pu8)); CI_LocalPrintf ("Addr 0x%08x - Page %d\n\r", Data_pu8, ((u32) Data_pu8 - FLASH_START) / FLASH_PAGE_SIZE); CI_LocalPrintf ("Programmed flag = %d (1 = true)\n\r", is_programmed); for (i = 0; i < 16; i++) { CI_LocalPrintf ("0x%03x ", i * 32); HexPrint (32, &Data_pu8[i * 32]); CI_LocalPrintf ("\n\r"); } } break; case 6: // Print topt slot header /* slot structure: 1b 0x01 if slot is used (programmed) 15b slot name 20b secret 1b configuration flags: MSB [x|x|x|x|x|send token id|send enter after code?|no. of digits 6/8] LSB 12b token id 1b keyboard layout */ Data_pu8 = get_totp_slot_addr (Param_u32); if (NULL == Data_pu8) { CI_LocalPrintf ("Wrong topt slot %d\n\r", Param_u32); return; } if (0x01 == Data_pu8[0]) { CI_LocalPrintf ("slot %d is used\n\r", Param_u32); } else { CI_LocalPrintf ("slot %d is not used\n\r", Param_u32); } CI_LocalPrintf ("slot name -%.15.15s-\n\r", &Data_pu8[1]); CI_LocalPrintf (" : "); HexPrint (15, &Data_pu8[1]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Secret : "); HexPrint (20, &Data_pu8[16]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Config : "); HexPrint (1, &Data_pu8[36]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Token : "); HexPrint (12, &Data_pu8[37]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("Keyboard: "); HexPrint (1, &Data_pu8[39]); CI_LocalPrintf ("\n\r"); CI_LocalPrintf ("slot name -%.15.15s-\n\r", &Data_pu8[1]); break; case 7: // Show topt time result = get_flash_time_value (); CI_LocalPrintf ("Flash time : 0x%08x - %ld\n\r", result, result); break; case 8: // Set topt time CI_LocalPrintf ("Set flash time : to 0x%08x - %ld\n\r", 100, 100); set_time_value (100); result = get_flash_time_value (); CI_LocalPrintf ("Flash time : 0x%08x - %ld\n\r", result, result); break; case 11: // parse_report (NULL,NULL); break; } }
void IBN_HV_Tests (unsigned char nParamsGet_u8, unsigned char CMD_u8, unsigned int Param_u32, unsigned char* String_pu8) { HiddenVolumeKeySlot_tst SlotData_st; u8 HiddenVolumeSlotKey_u8[32]; u8 DummyKey_au8[32]; u8 i; if (0 == nParamsGet_u8) { CI_LocalPrintf ("Hidden volume test functions\r\n"); CI_LocalPrintf ("\r\n"); // CI_LocalPrintf ("0 nr Init slot [nr]\r\n"); CI_LocalPrintf ("1 nr Read slot [nr]\r\n"); // CI_LocalPrintf ("2 Test key generation\r\n"); #ifdef TEST_PBKDF2 CI_LocalPrintf ("3 PBKDF2 test\r\n"); #endif CI_LocalPrintf ("4 Get hidden volume slot key\r\n"); CI_LocalPrintf ("5 [pw] Get AES key. pw = password\r\n"); CI_LocalPrintf ("6 Init hidden slots\r\n"); CI_LocalPrintf ("7 Hidden slots status\r\n"); CI_LocalPrintf ("8 nr pw Write slot [nr] [password]\r\n"); CI_LocalPrintf ("\r\n"); return; } switch (CMD_u8) { case 0: break; case 1: CI_LocalPrintf ("Read slot : %d\r\n", Param_u32); if (FALSE == DecryptedHiddenVolumeSlotsActive_u8) { CI_LocalPrintf ("\r\nHidden slots key not decrypted\r\n"); break; } if (NULL == String_pu8) { String_pu8 = "aaaa"; CI_LocalPrintf ("No password set. Set it to -%s-\r\n", String_pu8); } CI_LocalPrintf ("Check for password : %s\r\n", String_pu8); CI_LocalPrintf ("Decrypted slots key : "); HexPrint (AES_KEYSIZE_256_BIT, DecryptedHiddenVolumeSlotsKey_au8); CI_LocalPrintf ("\r\n"); GetHiddenVolumeSlotKey (HiddenVolumeSlotKey_u8, String_pu8, strlen ((char *) String_pu8), DecryptedHiddenVolumeSlotsData_au8, HV_SALT_SIZE); CI_LocalPrintf ("Hidden volume slot key : "); HexPrint (AES_KEYSIZE_256_BIT, HiddenVolumeSlotKey_u8); CI_LocalPrintf ("\r\n"); HV_ReadSlot_u8 (Param_u32, &SlotData_st, (u8 *) HiddenVolumeSlotKey_u8); HV_PrintSlotData_u8 (Param_u32, &SlotData_st); break; case 2: break; #ifdef TEST_PBKDF2 case 3: pbkdf2_test (); break; #endif case 4: DecryptedHiddenVolumeSlotsData (); break; case 5: CI_LocalPrintf ("Get key for password : %s\r\n", String_pu8); GetHiddenVolumeDataKeyFromUserpassword (String_pu8, DummyKey_au8); break; case 6: CI_LocalPrintf ("Init hidden slots\r\n"); InitHiddenSlots (); break; case 7: CI_LocalPrintf ("Hidden slots status\r\n"); if (NULL == String_pu8) { String_pu8 = "aaaa"; CI_LocalPrintf ("No password set. Set it to -%s-\r\n", String_pu8); } CI_LocalPrintf ("Check for password : %s\r\n", String_pu8); if (FALSE == DecryptedHiddenVolumeSlotsActive_u8) { CI_LocalPrintf ("\r\nHidden slots key not decrypted\r\n"); break; } CI_LocalPrintf ("Decrypted slots key : "); HexPrint (AES_KEYSIZE_256_BIT, DecryptedHiddenVolumeSlotsKey_au8); CI_LocalPrintf ("\r\n"); GetHiddenVolumeSlotKey (HiddenVolumeSlotKey_u8, String_pu8, strlen ((char *) String_pu8), DecryptedHiddenVolumeSlotsData_au8, HV_SALT_SIZE); CI_LocalPrintf ("Hidden volume slot key : "); HexPrint (AES_KEYSIZE_256_BIT, HiddenVolumeSlotKey_u8); CI_LocalPrintf ("\r\n"); for (i = 0; i < HV_SLOT_COUNT; i++) { CI_LocalPrintf ("Slot %d\r\n", i); if (TRUE == HV_ReadSlot_u8 (i, &SlotData_st, HiddenVolumeSlotKey_u8)) { HV_PrintSlotData_u8 (i, &SlotData_st); } else { CI_LocalPrintf ("*** Invalid data ***\r\n"); } } break; case 8: CI_LocalPrintf ("Write slots status\r\n"); if (FALSE == DecryptedHiddenVolumeSlotsActive_u8) { CI_LocalPrintf ("\r\nHidden slots key not decrypted\r\n"); break; } if (NULL == String_pu8) { String_pu8 = "aaaa"; CI_LocalPrintf ("No password set. Set it to -%s-\r\n", String_pu8); } CI_LocalPrintf ("Check for password : %s\r\n", String_pu8); CI_LocalPrintf ("Decrypted slots key : "); HexPrint (AES_KEYSIZE_256_BIT, DecryptedHiddenVolumeSlotsKey_au8); CI_LocalPrintf ("\r\n"); GetHiddenVolumeSlotKey (HiddenVolumeSlotKey_u8, String_pu8, strlen ((char *) String_pu8), DecryptedHiddenVolumeSlotsData_au8, HV_SALT_SIZE); CI_LocalPrintf ("Hidden volume slot key : "); HexPrint (AES_KEYSIZE_256_BIT, HiddenVolumeSlotKey_u8); CI_LocalPrintf ("\r\n"); SlotData_st.StartBlock_u32 = 1000000; SlotData_st.EndBlock_u32 = 2000000; // Get a random number for the data key if (FALSE == GetRandomNumber_u32 (AES_KEYSIZE_256_BIT / 2, SlotData_st.AesKey_au8)) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return; } // Get a random number for the data key if (FALSE == GetRandomNumber_u32 (AES_KEYSIZE_256_BIT / 2, &SlotData_st.AesKey_au8[AES_KEYSIZE_256_BIT / 2])) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return; } HV_WriteSlot_u8 (Param_u32, &SlotData_st, HiddenVolumeSlotKey_u8); break; } }
u8 SetupUpHiddenVolumeSlot (HiddenVolumeSetup_tst * HV_Setup_st) { u8 HiddenVolumeSlotKey_u8[AES_KEYSIZE_256_BIT]; HiddenVolumeKeySlot_tst SlotData_st; HV_Setup_st->HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSOWORD_SIZE] = 0; CI_LocalPrintf ("SetupUpHiddenVolumeSlot %d\r\n", HV_Setup_st->SlotNr_u8); CI_LocalPrintf ("Start block at %d %% of sd size\r\n", HV_Setup_st->StartBlockPercent_u8); CI_LocalPrintf ("End block at %d %% of sd size\r\n", HV_Setup_st->EndBlockPercent_u8); CI_LocalPrintf ("Password : -%s-\r\n", HV_Setup_st->HiddenVolumePassword_au8); // Is the hidden volume system initialised ? if (FALSE == HV_CheckFlashPageIsInitiated ()) { CI_LocalPrintf ("Hidden volume flash page isn't initiated\r\n"); InitHiddenSlots (); } // Are the hidden volume slots decrypted ? if (TRUE != DecryptedHiddenVolumeSlotsActive_u8) { if (FALSE == DecryptedHiddenVolumeSlotsData ()) // Decrypt new keys { CI_LocalPrintf ("Slot data not encrypted - used smartcard user password\r\n"); return (HIDDEN_VOLUME_OUTPUT_STATUS_NO_USER_PASSWORD_UNLOCK); } } if (HV_SLOT_COUNT <= HV_Setup_st->SlotNr_u8) { CI_LocalPrintf ("Wrong slot nr\r\n"); return (HIDDEN_VOLUME_OUTPUT_STATUS_WRONG_PASSWORD); } CI_LocalPrintf ("Decrypted slots key : "); HexPrint (AES_KEYSIZE_256_BIT, DecryptedHiddenVolumeSlotsKey_au8); CI_LocalPrintf ("\r\n"); // Get AES key for slot GetHiddenVolumeSlotKey (HiddenVolumeSlotKey_u8, HV_Setup_st->HiddenVolumePassword_au8, strlen ((char *) HV_Setup_st->HiddenVolumePassword_au8), DecryptedHiddenVolumeSlotsData_au8, HV_SALT_SIZE); CI_LocalPrintf ("Hidden volume slot key : "); HexPrint (AES_KEYSIZE_256_BIT, HiddenVolumeSlotKey_u8); CI_LocalPrintf ("\r\n"); SlotData_st.StartBlock_u32 = (u32) ((u64) gSdEndOfCard_u32 * (u64) HV_Setup_st->StartBlockPercent_u8 / (u64) 100) + 1; SlotData_st.EndBlock_u32 = (u32) ((u64) gSdEndOfCard_u32 * (u64) HV_Setup_st->EndBlockPercent_u8 / (u64) 100) - 1; // Get a random number for the data key if (FALSE == GetRandomNumber_u32 (AES_KEYSIZE_256_BIT / 2, SlotData_st.AesKey_au8)) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return (HIDDEN_VOLUME_OUTPUT_STATUS_SMARTCARD_ERROR); } // Get a random number for the data key if (FALSE == GetRandomNumber_u32 (AES_KEYSIZE_256_BIT / 2, &SlotData_st.AesKey_au8[AES_KEYSIZE_256_BIT / 2])) { CI_LocalPrintf ("GetRandomNumber fails\n\r"); return (HIDDEN_VOLUME_OUTPUT_STATUS_SMARTCARD_ERROR); } HV_PrintSlotData_u8 (HV_Setup_st->SlotNr_u8, &SlotData_st); HV_WriteSlot_u8 (HV_Setup_st->SlotNr_u8, &SlotData_st, HiddenVolumeSlotKey_u8); return (HIDDEN_VOLUME_OUTPUT_STATUS_OK); }
u8 HV_ReadSlot_u8 (u8 SlotNr_u8, HiddenVolumeKeySlot_tst * SlotData_st, u8 * SlotKey_pu8) { u32 Crc32_u32; #if (defined __GNUC__) && (defined __AVR32__) __attribute__ ((__aligned__ (4))) #elif (defined __ICCAVR32__) #pragma data_alignment = 4 #endif u8 Buffer_au8[HV_SLOT_SIZE]; if (FALSE == DecryptedHiddenVolumeSlotsActive_u8) { return (FALSE); // Slot key is not in ram } #ifdef DEBUG_KEYS CI_LocalPrintf ("HV_ReadSlot_u8 %d\r\n", SlotNr_u8); CI_LocalPrintf ("Slot key :\r\n"); HexPrint (32, SlotKey_pu8); CI_LocalPrintf ("\r\n"); #endif // Read all slots data from flash memcpy (&DecryptedHiddenVolumeSlotsData_au8[HV_SALT_SIZE], (u8 *) (HV_SALT_START_ADDRESS + HV_SALT_SIZE), HV_SLOT_SIZE * HV_SLOT_COUNT); // Decrypted data with slots key AES_KeyEncryption (HV_SLOT_COUNT * HV_SLOT_SIZE, &DecryptedHiddenVolumeSlotsData_au8[HV_SALT_SIZE], DecryptedHiddenVolumeSlotsKey_au8, AES_PMODE_DECIPHER, SlotNr_u8); #ifdef DEBUG_KEYS CI_LocalPrintf ("Encrypted data :\r\n"); HexPrint (HV_SLOT_SIZE, DecryptedHiddenVolumeSlotsData_au8 + HV_SALT_SIZE + SlotNr_u8 * HV_SLOT_SIZE); CI_LocalPrintf ("\r\n"); #endif // Read encrypted slot data from ram memcpy ((u8 *) Buffer_au8, (u8 *) (DecryptedHiddenVolumeSlotsData_au8 + HV_SALT_SIZE + SlotNr_u8 * HV_SLOT_SIZE), HV_SLOT_SIZE); // Decrypt slot data AES_KeyEncryption (HV_SLOT_SIZE, (u8 *) Buffer_au8, SlotKey_pu8, AES_PMODE_DECIPHER, SlotNr_u8); memcpy ((u8 *) SlotData_st, Buffer_au8, sizeof (HiddenVolumeKeySlot_tst)); #ifdef DEBUG_KEYS CI_LocalPrintf ("Decrypted data :\r\n"); HexPrint (sizeof (HiddenVolumeKeySlot_tst), SlotData_st); CI_LocalPrintf ("\r\n"); #endif /* // Check magic number if (HV_MAGIC_NUMBER_SLOT_ENTRY != SlotData_st->MagicNumber_u32) { return (FALSE); } */ // Check CRC Crc32_u32 = generateCRC_len ((u8 *) SlotData_st, (sizeof (HiddenVolumeKeySlot_tst) / 4) - 1); if (Crc32_u32 != SlotData_st->Crc_u32) { return (FALSE); } return (TRUE); }