u32 BuildPasswordSafeKey_u32 (void)
{
u8 Key_au8[AES_KEYSIZE_256_BIT];

    CI_TickLocalPrintf ("BuildPasswordSafeKey_u32\r\n");
    RestartSmartcard ();
    // LA_RestartSmartcard_u8 ();

    // Get a random number for the master key
    if (FALSE == getRandomNumber (AES_KEYSIZE_256_BIT / 2, Key_au8))
    {
        CI_LocalPrintf ("GetRandomNumber fails 1\n\r");
        return (FALSE);
    }

    // Get a random number for the master key
    if (FALSE == getRandomNumber (AES_KEYSIZE_256_BIT / 2, &Key_au8[AES_KEYSIZE_256_BIT / 2]))
    {
        CI_LocalPrintf ("GetRandomNumber fails 2\n\r");
        return (FALSE);
    }

    WritePasswordSafeKey (Key_au8);

    // Old Key is invalid
    DecryptedPasswordSafeKey_u8 = FALSE;

    return (TRUE);
}
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 PWS_EnableAccess (u8 * password)
{
unsigned short ret;

    CI_LocalPrintf ("PWS_EnableAccess: ");

    ret = CcidVerifyPin (2, (unsigned char *) password);    // 2 = user pw
    if (APDU_ANSWER_COMMAND_CORRECT != ret)
    {
        CI_LocalPrintf (" *** FAIL ***\r\n");
        return CMD_STATUS_WRONG_PASSWORD;
    }

    ret = PWS_DecryptedPasswordSafeKey ();

    if (TRUE != ret)
    {
        CI_LocalPrintf (" *** FAIL ***. Can't decrypt key\r\n");
        return CMD_STATUS_AES_DEC_FAILED;
    }

    CI_LocalPrintf ("OK\r\n");

    return CMD_STATUS_OK;
}
void TIME_MEASURING_INT_show_interrupt_table (void)
{
    unsigned int int_grp, int_req, IntNamePointer;

    IntNamePointer = 0;

    // For all interrupt groups,
    CI_LocalPrintf ("Grp Nr   Addr\n\r");
    for (int_grp = 0; int_grp < AVR32_INTC_NUM_INT_GRPS; int_grp++)
    {
        // For all interrupt request lines of each group,
        for (int_req = 0; int_req < _int_handler_table[int_grp].num_irqs; int_req++)
        {
            if (&_unhandled_interrupt == _int_handler_table[int_grp]._int_line_handler_table[int_req])
            {
                CI_LocalPrintf ("%3d %3d %4d %-15s : %9d UNHANDLED\n\r", IntNamePointer, int_grp, int_req, INT_NameTable[IntNamePointer],
                                TIME_MEASURING_INT_IntCount[IntNamePointer]);
            }
            else
            {
                CI_LocalPrintf ("%3d %3d %4d %-15s : %9d 0x%08x\n\r", IntNamePointer, int_grp, int_req, INT_NameTable[IntNamePointer],
                                TIME_MEASURING_INT_IntCount[IntNamePointer], _int_handler_table[int_grp]._int_line_handler_table[int_req]);
            }
            IntNamePointer++;
            DelayMs (50);
        }
    }
    CI_LocalPrintf ("             %-15s : %9d\n\r", INT_NameTable[IntNamePointer], TIME_MEASURING_INT_IntCount[IntNamePointer]);
}
void TIME_MEASURING_INT_Infos (unsigned char nParamsGet_u8, unsigned char CMD_u8, unsigned int Param_u32, unsigned char* String_pu8)
{
    if (0 == nParamsGet_u8)
    {
        CI_LocalPrintf ("Interrupt infos\r\n");
        CI_LocalPrintf ("\r\n");
        CI_LocalPrintf ("0          Show Interrupttable\r\n");
        CI_LocalPrintf ("\r\n");
        return;
    }
    switch (CMD_u8)
    {
        case 0:
            TIME_MEASURING_INT_show_interrupt_table ();
            break;

        case 1:
            TIME_MEASURING_INT_show_interrupt_count ();
            break;

        case 5:
            if (0 == Param_u32)
            {
            }
            else
            {
            }
            break;

    }
}
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 PWM_PrintMatrix (void)
{
    u32 x, y;

    CI_LocalPrintf ("\r\n");

    for (y = 0; y < 10; y++)
    {
        for (x = 0; x < 10; x++)
        {
            if (-1 != PWM_PasswordMatrix_as8[x][y])
            {
                CI_LocalPrintf ("%2d", PWM_PasswordMatrix_as8[x][y]);
            }
            else
            {
                CI_LocalPrintf (" .");
            }
        }
        CI_LocalPrintf ("\r\n");
    }
    CI_LocalPrintf ("\r\n");

    DelayMs (100);

    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 PWS_ReadSlot (u8 Slot_u8, typePasswordSafeSlot_st * Slot_st)
{
u8* ReadPointer_pu8;

u8* AesKeyPointer_pu8;

    if (PWS_SLOT_COUNT <= Slot_u8)
    {
        CI_LocalPrintf ("PWS_ReadSlot: Wrong slot nr %d\r\n", Slot_u8);
        return (FALSE);
    }

    if (FALSE == PWS_GetDecryptedPasswordSafeKey (&AesKeyPointer_pu8))
    {
        CI_LocalPrintf ("PWS_ReadSlot: key not decrypted\r\n");
        return (FALSE); // Aes key is not decrypted
    }

    // LED_GreenOn ();

    // Get read address
    ReadPointer_pu8 = (u8 *) (PWS_FLASH_START_ADDRESS + (PWS_SLOT_LENGTH * Slot_u8));
    memcpy (Slot_st, ReadPointer_pu8, PWS_SLOT_LENGTH);

    /*
       #ifdef ENABLE_IBN_PWS_TESTS_ENCRYPTION CI_LocalPrintf ("PWS_ReadSlot encrypted : "); HexPrint (PWS_SLOT_LENGTH, Slot_st); CI_LocalPrintf
       ("\n\r"); #endif */

    // Decrypt data (max 256 byte per encryption)
unsigned char Slot_st_decrypted[PWS_SLOT_LENGTH];

aes_context aes_ctx;

    aes_setkey_dec (&aes_ctx, AesKeyPointer_pu8, 256);
    // TODO: Create aes_crypt_ecb with length as parameter and break the
    // input internally
int i;

    for (i = 0; i < PWS_SLOT_LENGTH; i += 16)
    {
        aes_crypt_ecb (&aes_ctx, AES_DECRYPT, &(((unsigned char *) (Slot_st))[i]), &(Slot_st_decrypted[i]));
    }

    memcpy ((unsigned char *) (Slot_st), Slot_st_decrypted, PWS_SLOT_LENGTH);

    /*
       #ifdef ENABLE_IBN_PWS_TESTS_ENCRYPTION CI_LocalPrintf ("PWS_ReadSlot decrypted : "); HexPrint (PWS_SLOT_LENGTH, Slot_st_decrypted);
       CI_LocalPrintf ("\n\r"); #endif */
    // LED_GreenOff ();

    return (TRUE);
}
void IBN_ListTaskWithinSingleList (xList *pxList, char *pcStatus )
{
	volatile tskTCB *pxNextTCB, *pxFirstTCB;
	u16 usStackRemaining;

	u64 ullTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
	u64 ullStatsAsPercentage;

	/* Write the details of all the TCB's in pxList into the buffer. */
	listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
	do
	{
		listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );

		usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack );
		ullStatsAsPercentage = (u64)0;
		if ((u64)0 != ullTotalRunTime)
		{
			ullStatsAsPercentage  =  (u64)10000 * (u64)(pxNextTCB->ullRunTimeCounter);
			ullStatsAsPercentage /=  ullTotalRunTime;
		}

		CI_LocalPrintf("%-21.21s ", pxNextTCB->pcTaskName);
		CI_LocalPrintf("%s   ", pcStatus);
		CI_LocalPrintf("%u  ", ( unsigned int ) pxNextTCB->uxPriority);
		CI_LocalPrintf("%5u ", usStackRemaining);
		CI_LocalPrintf("%10u ", (u32)(pxNextTCB->ullRunTimeCounter / 60ULL));
		CI_LocalPrintf("%s ", TIME_MEASURING_ShortText (pxNextTCB->ullRunTimeCounter / 60ULL));

		CI_LocalPrintf("%6.2f %% ",(float)ullStatsAsPercentage/100.0);
		CI_LocalPrintf("%7u \r\n", pxNextTCB->ulRunCounter);

//		CI_LocalPrintf( ( char * ) "%-21.21s %s   %u  %5u %9u %6.2f %%\r\n", pxNextTCB->pcTaskName, pcStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining,pxNextTCB->ullRunTimeCounter/60,(float)ullStatsAsPercentage/100.0);
	} while( pxNextTCB != pxFirstTCB );
}
void IBN_Taskdata (u8 i)
{
	u64 ullTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
  u64 ullStatsAsPercentage;
	u16 usStackRemaining;

	usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) IBN_Tasklist_st[i]->pxStack ) * sizeof (portSTACK_TYPE);
	ullStatsAsPercentage       = (u64)0;

	if ((u64)0 != ullTotalRunTime)
	{
		ullStatsAsPercentage  =  (u64)10000 * (u64)(IBN_Tasklist_st[i]->ullRunTimeCounter);
		ullStatsAsPercentage /=  ullTotalRunTime;

	}

	CI_LocalPrintf( ( char * ) "%-21.21s ", IBN_Tasklist_st[i]->pcTaskName);
	CI_LocalPrintf( ( char * ) "%s   ", IBN_TaskStates[IBN_TasklistState_u8[i]]);
	CI_LocalPrintf( ( char * ) "%u  ", ( unsigned int ) IBN_Tasklist_st[i]->uxPriority);
	CI_LocalPrintf( ( char * ) "%5u ", usStackRemaining);
//	CI_LocalPrintf( ( char * ) "%10u ", (u32)(IBN_Tasklist_st[i]->ullRunTimeCounter / 60ULL));
	CI_LocalPrintf("%s ", TIME_MEASURING_ShortText (IBN_Tasklist_st[i]->ullRunTimeCounter / 60ULL));

  CI_LocalPrintf( ( char * ) "%6.2f %% ",(float)ullStatsAsPercentage/100.0);
  CI_LocalPrintf( ( char * ) "%6.2f %% ",(float)IBN_Tasklist_st[i]->ullRunTimeCounterLastMinute/(10000.0*60.0*60.0)*(float)(configTICK_RATE_HZ)/1000.0);
	CI_LocalPrintf( ( char * ) "%8u \r\n", IBN_Tasklist_st[i]->ulRunCounter);
}
u8 PWS_GetAllSlotStatus (u8 * StatusArray_pu8)
{
u32 i;

u8* AesKeyPointer_pu8;

#if (defined __GNUC__) && (defined __AVR32__)
    __attribute__ ((__aligned__ (4)))
#elif (defined __ICCAVR32__)
#pragma data_alignment = 4
#endif
typePasswordSafeSlot_st Slot_st;

    // Clear the output array
    memset (StatusArray_pu8, 0, PWS_SLOT_COUNT);

    // Check for user password enable
    if (FALSE == PWS_GetDecryptedPasswordSafeKey (&AesKeyPointer_pu8))
    {
        CI_LocalPrintf ("PWS_ReadSlot: key not decrypted\r\n");
        return (FALSE); // Aes key is not decrypted
    }

    for (i = 0; i < PWS_SLOT_COUNT; i++)
    {
        if (TRUE == PWS_ReadSlot (i, &Slot_st))
        {
            if (PWS_SLOT_ACTIV_TOKEN == Slot_st.SlotActiv_u8)
            {
                StatusArray_pu8[i] = TRUE;
            }
        }
    }

    CI_LocalPrintf ("PWS_ReadSlot: Slot status : ");
    for (i = 0; i < PWS_SLOT_COUNT; i++)
    {
        if (TRUE == StatusArray_pu8[i])
        {
            CI_LocalPrintf ("1");
        }
        else
        {
            CI_LocalPrintf ("0");
        }
    }
    CI_LocalPrintf ("\r\n");

    return (TRUE);
}
void TIME_MEASURING_PrintIntLine (u8 Entry_u8)
{
    CI_LocalPrintf ("%-17s %9ld   ", TIME_MEASURING_IntTimerNames_u8[Entry_u8], INT_TIME_MEASURING_st[Entry_u8].Events_u32);

    if (0xFFFFFFFF != INT_TIME_MEASURING_st[Entry_u8].LastRuntimeMin_u32)
    {
        CI_LocalPrintf ("%9ld ", INT_TIME_MEASURING_st[Entry_u8].LastRuntimeMin_u32 / TIME_MEASURING_TICKS_IN_USEC);
    }
    else
    {
        CI_LocalPrintf ("          ");
    }
    CI_LocalPrintf ("%9ld  ", INT_TIME_MEASURING_st[Entry_u8].LastRuntimeMax_u32 / TIME_MEASURING_TICKS_IN_USEC);

    if (0xFFFFFFFF != INT_TIME_MEASURING_st[Entry_u8].LastStoptimeMin_u32)
    {
        CI_LocalPrintf ("%9ld ", INT_TIME_MEASURING_st[Entry_u8].LastStoptimeMin_u32 / TIME_MEASURING_TICKS_IN_USEC);
    }
    else
    {
        CI_LocalPrintf ("          ");
    }
    CI_LocalPrintf ("%10ld ", INT_TIME_MEASURING_st[Entry_u8].LastStoptimeMax_u32 / TIME_MEASURING_TICKS_IN_USEC);

    if (1 >= NoTimereset_u8)
    {
        // CI_LocalPrintf ("%5.3f%%\n\r",(float)(INT_TIME_MEASURING_st[Entry_u8].SumRuntime_u64/TIME_MEASURING_TICKS_IN_USEC)/(float)OS_Time/10);
    }
    else
    {
        CI_LocalPrintf ("\n\r");
    }
}
u8 PWS_InitKey (void)
{
u32 Ret_u32;

    CI_LocalPrintf ("PWS_InitKey\r\n");

    Ret_u32 = PWS_DecryptedPasswordSafeKey ();
    if (TRUE != Ret_u32)
    {
        CI_LocalPrintf ("PWS_InitKey: *** FAIL ***\r\n");
        return (FALSE);
    }

    return (TRUE);
}
void TIME_MEASURING_PrintInt (void)
{
    u8 i;

    CI_LocalPrintf ("Interrupt Runtime-Analyse\n\r");
    CI_LocalPrintf ("   Interrupt                      Runtime              Stoptime\n\r");
    CI_LocalPrintf (" Nr   Name           Anzahl  Min (usec) Max(usec) Min (usec)  Max(usec)\n\r");

    for (i = 0; i < INT_TIME_MEASURING_MAX_ZEITSCHEIBEN; i++)
    {
        if (0 != INT_TIME_MEASURING_st[i].Events_u32)
        {
            TIME_MEASURING_PrintIntLine (i);
        }
    }
}
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);
}
void TIME_MEASURING_Print (u8 Value_u8)
{
    switch (Value_u8)
    {
        case 1:
            TIME_MEASURING_Init (); // Clear counters
            return;
        case 2:
#ifdef TIME_MEASURING_INT_ENABLE
            TIME_MEASURING_PrintInt ();
#else
            CI_LocalPrintf ("Interruptzeitmessung nicht aktiv\n\r");
#endif
            return;

    }

    CI_LocalPrintf ("Runtime-Analyse\n\r");
    CI_LocalPrintf ("                             Runtime              Stoptime\n\r");
    CI_LocalPrintf ("Counter        Anzahl  Min (usec) Max(usec) Min (usec) Max(usec)\n\r");
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIMER_IDF_10MS);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIMER_IW_10MS);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_3);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_4);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_5);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIMER_KEY_10MS);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_SD_ACCESS);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_8);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_9);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_10);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_CCID_USB_GET);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_CCID_USB_SEND);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_MSD_AES_READ);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_MSD_AES_WRITE);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_15);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_16);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_17);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_18);
    TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_FOR_ALL);
    // TIME_MEASURING_PrintLine (TIME_MEASURING_TIME_20 ); // CMD Laufzeit
}
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; } }

     */

}
void IBN_HTML_Tests (unsigned char nParamsGet_u8,unsigned char CMD_u8,unsigned int Param_u32,unsigned char *String_pu8)
{
#ifdef HTML_ENABLE_HTML_INTERFACE
  if (0 == nParamsGet_u8)
  {
    CI_LocalPrintf ("HTML test functions\r\n");
    CI_LocalPrintf ("\r\n");
    CI_LocalPrintf ("0   Write start file\r\n");
    CI_LocalPrintf ("\r\n");
    return;
  }
  switch (CMD_u8)
  {
    case 0 :
      HTML_GenerateStartPage ();
      break;
  }
#else
  CI_LocalPrintf ("HTML interface not active\r\n");
#endif
}
u8 PWM_SwapNumber (u8 SwapPosX_u8, u8 BaseLineY_u8)
{
u8 SwapNumber_u8;
u8 PosY_u8;
u8 SwapX2ndPos_u8;
u8 Save_u8;

    SwapNumber_u8 = PWM_PasswordMatrix_as8[SwapPosX_u8][BaseLineY_u8];

    for (PosY_u8 = 0; PosY_u8 < 10; PosY_u8++)
    {
        // If the y pos the baseline the goto next y pos
        if (PosY_u8 == BaseLineY_u8)
        {
            continue;
        }

        // Is the place used, goto next y pos
        if (PWM_PasswordMatrix_as8[SwapPosX_u8][PosY_u8] != -1)
        {
            continue;
        }

        // We found a pos to swap
        // Find the x pos to swap
        for (SwapX2ndPos_u8 = 0; SwapX2ndPos_u8 < 10; SwapX2ndPos_u8++)
        {
            // Is the place not used, goto next y pos
            if (PWM_PasswordMatrix_as8[SwapX2ndPos_u8][PosY_u8] != SwapNumber_u8)
            {
                continue;
            }
            // Now check the BaseLineY_u8 for an unused place
            if (-1 == PWM_PasswordMatrix_as8[SwapX2ndPos_u8][BaseLineY_u8])
            {
#ifdef DEBUG_MP_IO_LEVEL_2
                CI_LocalPrintf ("\r\nSwap X1 %d  Y1 %d - X2 %d Y2 %d\r\n", SwapPosX_u8, BaseLineY_u8, SwapX2ndPos_u8, PosY_u8);
#endif
                // Now we can swap
                // Swap the baseline
                PWM_PasswordMatrix_as8[SwapX2ndPos_u8][BaseLineY_u8] = SwapNumber_u8;
                PWM_PasswordMatrix_as8[SwapPosX_u8][BaseLineY_u8] = -1;

                // Swap the PosY_u8 line
                Save_u8 = PWM_PasswordMatrix_as8[SwapX2ndPos_u8][PosY_u8];
                PWM_PasswordMatrix_as8[SwapX2ndPos_u8][PosY_u8] = PWM_PasswordMatrix_as8[SwapPosX_u8][PosY_u8];
                PWM_PasswordMatrix_as8[SwapPosX_u8][PosY_u8] = Save_u8;
                return (TRUE);
            }
        }
    }
    return (FALSE);
}
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);
}
static void USB_CCID_GetDataFromUSB (void)
{
    int i;
    int USB_Datalen_s32;

    // Bool cbw_error;

    Usb_reset_endpoint_fifo_access (EP_CCID_OUT);

    // Get all data from USB
    USB_CCID_data_st.CCID_datalen = 0;

    while (Is_usb_out_received (EP_CCID_OUT))
    {
        Usb_reset_endpoint_fifo_access (EP_CCID_OUT);

        USB_Datalen_s32 = Usb_byte_count (EP_CCID_OUT);
        USB_Log_st.CCID_WriteCalls_u32++;
        USB_Log_st.CCID_BytesWrite_u32 += USB_Datalen_s32;

        // CI_TickLocalPrintf ("Get CCID USB block %3d byte - %3d\n",USB_Datalen_s32,USB_CCID_data_st.CCID_datalen);

        if (CCID_MAX_XFER_LENGTH <= USB_Datalen_s32 + USB_CCID_data_st.CCID_datalen)    // Check for oversize
        {
            CI_LocalPrintf ("*** CCID buffer to small %d ***\n", CCID_MAX_XFER_LENGTH);
            Usb_ack_out_received_free (EP_CCID_OUT);
            return;
        }

        for (i = 0; i < USB_Datalen_s32; i++)
        {
            USB_CCID_data_st.USB_data[USB_CCID_data_st.CCID_datalen] = Usb_read_endpoint_data (EP_CCID_OUT, 8);
            USB_CCID_data_st.CCID_datalen++;
        }

        Usb_ack_out_received_free (EP_CCID_OUT);
        DelayMs (1);
    }

    LED_RedOn ();

//    USB_CCID_Datalen_s32 = USB_CCID_data_st.CCID_datalen;

    USB_to_CRD_DispatchUSBMessage_v (&USB_CCID_data_st);

//    memset (USB_CCID_data_st.USB_data,0,USB_Datalen_s32);
    LED_RedOff ();

    // Usb_ack_out_received_free(EP_CCID_OUT);

}
void flashc_issue_command (unsigned int command, int page_number)
{
    u_avr32_flashc_fcmd_t u_avr32_flashc_fcmd;
    flashc_wait_until_ready ();
    u_avr32_flashc_fcmd.fcmd = AVR32_FLASHC.fcmd;
    u_avr32_flashc_fcmd.FCMD.cmd = command;
    if (page_number >= 0)
        u_avr32_flashc_fcmd.FCMD.pagen = page_number;
    u_avr32_flashc_fcmd.FCMD.key = AVR32_FLASHC_FCMD_KEY_KEY;
    AVR32_FLASHC.fcmd = u_avr32_flashc_fcmd.fcmd;
    flashc_error_status = flashc_get_error_status ();
    flashc_wait_until_ready ();
#ifdef DEBUG_FLASHC
    {
    unsigned char text[20];
        CI_LocalPrintf ("Flash page :");
        itoa ((unsigned int) u_avr32_flashc_fcmd.FCMD.pagen, text);
        CI_LocalPrintf (text);
        CI_LocalPrintf ("\n\r");
    }
#endif

}
void TIME_MEASURING_PrintRuntimeSlots (u8 Entry_u8)
{
u8 i;

    if (TIME_MEASURING_MAX_ZEITSCHEIBEN <= Entry_u8)
    {
        CI_LocalPrintf ("ERROR: Entry %d not found. Max slot is %d\n\r", Entry_u8, TIME_MEASURING_MAX_TIME_SLICES - 1);
        return;
    }

    CI_LocalPrintf ("Runtimeslot %s\n\r\n\r", TIME_MEASURING_TimerNames_u8[Entry_u8]);

    CI_LocalPrintf ("Runtime (usec)          Count\n\r");
    for (i = 0; i < TIME_MEASURING_MAX_TIME_SLICES - 1; i++)
    {
        CI_LocalPrintf (" %5ld - %5ld : %9ld\n\r", TIME_MEASURING_RuntimeSlice_in_ticks_u32 * i / TIME_MEASURING_TICKS_IN_USEC,
                        TIME_MEASURING_RuntimeSlice_in_ticks_u32 * (i + 1) / TIME_MEASURING_TICKS_IN_USEC,
                        TIME_MEASURING_st[Entry_u8].RuntimeSliceCount_u32[i]);
    }
    CI_LocalPrintf ("       > %5ld : %9ld\n\r",
                    TIME_MEASURING_RuntimeSlice_in_ticks_u32 * (TIME_MEASURING_MAX_TIME_SLICES - 1) / TIME_MEASURING_TICKS_IN_USEC,
                    TIME_MEASURING_st[Entry_u8].RuntimeSliceCount_u32[TIME_MEASURING_MAX_TIME_SLICES - 1]);
}
u8 ClearStickKeysNotInitatedToFlash (void)
{
  // If configuration not found then init it
  if (FALSE == ReadStickConfigurationFromUserPage ())
  {
    InitStickConfigurationToUserPage_u8 ();
  }

  CI_LocalPrintf ("Clear: Stick keys not initiated\r\n");

  StickConfiguration_st.StickKeysNotInitiated_u8 = FALSE;

  WriteStickConfigurationToUserPage ();

  return (TRUE);
}
u8 SetSdCardNotFilledWithRandomCharsToFlash (void)
{
  // If configuration not found then init it
  if (FALSE == ReadStickConfigurationFromUserPage ())
  {
    InitStickConfigurationToUserPage_u8 ();
  }

  CI_LocalPrintf ("Set new SD card *** not *** filled with random chars\r\n");

  StickConfiguration_st.SDFillWithRandomChars_u8 &= 0xFE;     // Clear the "card with random chars filled"  bit

  WriteStickConfigurationToUserPage ();

  return (TRUE);
}
u8 SetSdCardFilledWithRandomCharsToFlash (void)
{
  // If configuration not found then init it
  if (FALSE == ReadStickConfigurationFromUserPage ())
  {
    InitStickConfigurationToUserPage_u8 ();
  }

  CI_LocalPrintf ("Set new SD card filled with random chars\r\n");

  StickConfiguration_st.SDFillWithRandomChars_u8 |= 0x01;     // Set the "SD card filled with randoms"  bit

  WriteStickConfigurationToUserPage ();

  return (TRUE);
}
u8 ClearNewSdCardFoundToFlash (void)
{
  // If configuration not found then init it
  if (FALSE == ReadStickConfigurationFromUserPage ())
  {
    InitStickConfigurationToUserPage_u8 ();
  }

  CI_LocalPrintf ("Clear new SD card found\r\n");

  StickConfiguration_st.NewSDCardFound_u8 &= 0xFE;     // Clear the "new SD card found"  bit

  WriteStickConfigurationToUserPage ();

  return (TRUE);
}
void IBN_LogADInput (u8 nParamsGet_u8,u8 CMD_u8,u32 Param_u32)
{
#ifdef AD_LOGGING_ACTIV
	if (0 == nParamsGet_u8)
	{
		CI_LocalPrintf ("AD Test\r\n");
		CI_LocalPrintf ("\r\n");
		CI_LocalPrintf ("0   Print AD data\r\n");
    CI_LocalPrintf ("1   Start SD log\r\n");
    CI_LocalPrintf ("2   Stop SD log\r\n");
    CI_LocalPrintf ("3   Init SD log\r\n");
    CI_LocalPrintf ("4   Print summary\r\n");
		CI_LocalPrintf ("\r\n");
		return;
	}
	switch (CMD_u8)
	{
		case 0 :
			AD_Readdata ();
			break;
		case 1 :
		  AD_LOG_Start ();
			break;
		case 2 :
		  AD_LOG_Stop ();
			break;
		case 3 :
			AD_LOG_init();
			break;
		case 4:
		  AD_PrintSummary ();
		  break;
    case 5 :
      AD_FileIO_ReadLocalTime_u32 ();
      break;
	}
#else
  CI_LocalPrintf ("AD Log not active\r\n");
#endif // #ifdef AD_LOGGING_ACTIV
}
u8 InitHiddenSlots (void)
{
    CI_LocalPrintf ("InitHiddenSlots: Overwriting all keys\r\n");

    if (FALSE == InitRamdomBaseForHiddenKey ())
    {
        return (FALSE);
    }

    if (FALSE == HV_InitAllSlotData ())
    {
        return (FALSE);
    }

    return (TRUE);
}