/******************************************************************************* * Function Name: CR_Encrypt ******************************************************************************** * * Summary: * Encrypts the specified data with the specified key. Prefix * CR stands for en/decryption to show that it is part of encryption module. * * Parameters: * uint8 * plain: Pointer to an array of bytes to be encrypted. Size of * the array should be equal to the value of 'length' * parameter. * uint16 length: Length of the data to be encrypted, in Bytes. * uint8 * key: Pointer to an array of bytes holding the key. The array * length to be allocated by the application should be 16 * bytes. * uint8 * nonce Pointer to an array of bytes. The array length to be * allocated by the application is 13 Bytes. * uint8 * encrypted: Pointer to an array of size 'length' where the encrypted * data is stored. * uint8 * out_mic: Pointer to an array of bytes (4 Bytes) to store the * Message Integrity Check (MIC) value generated during * encryption. * * Return: * CYBLE_API_RESULT_T: Return value indicates if the function succeeded or * failed. Following are the possible error codes. * CYBLE_ERROR_OK On successful operation. * CYBLE_ERROR_INVALID_PARAMETER One of the inputs is a null pointer or * the 'length' value is invalid *******************************************************************************/ CYBLE_API_RESULT_T CR_Encrypt( uint8 * plain, uint16 length, uint8 * key, uint8 * nonce, uint8 * encrypted, uint8 * out_mic) { CYBLE_API_RESULT_T retval = CYBLE_ERROR_OK; uint16 blockLeft; uint16 blockLength = 0; uint16 offset = 0; uint8 inBuf[EBCRYPTION_BLOCK_LENGTH]; uint8 outBuf[EBCRYPTION_BLOCK_LENGTH]; /*Input parameters check*/ if ((plain == NULL) || (key == NULL) || (nonce == NULL) || \ (encrypted == NULL) || out_mic == NULL) { return (CYBLE_ERROR_INVALID_PARAMETER); } #if (CYDEV_BOOTLOADER_ENABLE == 1) if (!encryptionEnabled) { memcpy(encrypted,plain,length); DBG_PRINT_TEXT("Encryption skipped"); return (CYBLE_ERROR_OK); } #endif /*(CYDEV_BOOTLOADER_ENABLE == 1)*/ /* Split plain text in to acceptable number of blocks */ for(offset=0;offset<length;offset+=EBCRYPTION_BLOCK_LENGTH) { blockLeft = length - offset; blockLength = blockLeft < EBCRYPTION_BLOCK_LENGTH ? blockLeft : EBCRYPTION_BLOCK_LENGTH; memcpy(inBuf, plain+offset, blockLength); retval = CyBle_AesCcmEncrypt(key, nonce, inBuf, blockLength, outBuf, out_mic); /*Do not store MIC and check MIC authorization, due to memory consumption*/ if (retval == CYBLE_ERROR_OK || retval == CYBLE_ERROR_MIC_AUTH_FAILED) { memcpy(encrypted+offset, outBuf, blockLength); } } return (retval); }
/******************************************************************************* * Function Name: CR_Decrypt ******************************************************************************** * * Summary: * Decrypts the specified data with the specified key. Prefix * CR stands for en/decryption to show that it is part of encryption module. * * Parameters: * uint8 * encrypted: Pointer to an array of bytes to be decrypted. Size of * the array should be equal to the value of 'length' * parameter. * uint16 length: Length of the data to be encrypted, in Bytes. * uint8 * key: Pointer to an array of bytes holding the key. The array * length to be allocated by the application should be 16 * bytes. * uint8 * nonce Pointer to an array of bytes. The array length to be * allocated by the application is 13 Bytes. * uint8 * decrypted: Pointer to an array of size 'length' where the decrypted * data is stored. * uint8 * out_mic: Pointer to an array of bytes (4 Bytes) to check the MIC * value generated during encryption. * * Return: * CYBLE_API_RESULT_T: Return value indicates if the function succeeded or * failed. Following are the possible error codes. * CYBLE_ERROR_OK On successful operation. * CYBLE_ERROR_INVALID_PARAMETER One of the inputs is a null * pointer or the 'length' value is invalid * CYBLE_ERROR_MIC_AUTH_FAILED Data decryption has been done * successfully but MIC based authorization check has failed. This * error can be ignored if MIC based authorization was not intended. * *******************************************************************************/ CYBLE_API_RESULT_T CR_Decrypt(uint8 * encrypted, uint16 length, uint8 * key, uint8 * nonce, uint8 * decrypted , uint8 * out_mic) { CYBLE_API_RESULT_T retval = CYBLE_ERROR_OK; uint16 blockLeft; uint16 blockLength = 0; uint16 offset = 0; uint8 inBuf[EBCRYPTION_BLOCK_LENGTH]; uint8 outBuf[EBCRYPTION_BLOCK_LENGTH]; /*Input parameters check*/ if ((encrypted == NULL) || (key == NULL) || (nonce == NULL) || \ (decrypted == NULL) || out_mic == NULL) { return (CYBLE_ERROR_INVALID_PARAMETER); } #if (CYDEV_BOOTLOADER_ENABLE == 1) if (!encryptionEnabled) { DBG_PRINT_TEXT("\r\nDecryption skipped\r\n"); memcpy(decrypted,encrypted,length); return (CYBLE_ERROR_OK); } #endif /*(CYDEV_BOOTLOADER_ENABLE == 1)*/ /* Split plain text in to acceptable number of blocks */ for(offset=0;offset<length;offset+=EBCRYPTION_BLOCK_LENGTH) { blockLeft = length - offset; blockLength = blockLeft < EBCRYPTION_BLOCK_LENGTH ? blockLeft : EBCRYPTION_BLOCK_LENGTH; memcpy(inBuf, encrypted+offset, blockLength); retval = CyBle_AesCcmDecrypt(key, nonce, inBuf, blockLength, outBuf, out_mic); if (retval != CYBLE_ERROR_INVALID_PARAMETER) { memcpy(decrypted+offset, outBuf, blockLength);; } } return (retval); }
int main() { const char8 serialNumber[] = SERIAL_NUMBER; CYBLE_LP_MODE_T lpMode; CYBLE_BLESS_STATE_T blessState; packetRXFlag = 0u; DBG_PRINT_TEXT("\r\n"); DBG_PRINT_TEXT("\r\n"); DBG_PRINT_TEXT("===============================================================================\r\n"); DBG_PRINT_TEXT("= BLE_External_Memory_Bootloadable Application Started \r\n"); DBG_PRINT_TEXT("= Version: 1.0 \r\n"); #if (LED_ADV_COLOR == LED_GREEN) DBG_PRINT_TEXT("= Code: LED_GREEN \r\n"); #else DBG_PRINT_TEXT("= Code: LED_BLUE \r\n"); #endif /*LED_ADV_COLOR == LED_GREEN*/ DBG_PRINTF ("= Compile Date and Time : %s %s \r\n", __DATE__,__TIME__); #if (ENCRYPTION_ENABLED == YES) DBG_PRINT_TEXT("= ENCRYPTION OPTION : ENABLED \r\n"); #else DBG_PRINT_TEXT("= ENCRYPTION OPTION : DISABLED \r\n"); #endif /*LED_ADV_COLOR == LED_GREEN*/ #if (CI_PACKET_CHECKSUM_CRC == YES) DBG_PRINT_TEXT("= PACKET CHECKSUM TYPE: CRC-16-CCITT \r\n"); #else DBG_PRINT_TEXT("= PACKET CHECKSUM TYPE: BASIC SUMMATION \r\n"); #endif /*LED_ADV_COLOR == LED_GREEN*/ DBG_PRINT_TEXT("===============================================================================\r\n"); DBG_PRINT_TEXT("\r\n"); DBG_PRINT_TEXT("\r\n"); CyGlobalIntEnable; Bootloading_LED_Write(LED_OFF); Advertising_LED_1_Write(LED_OFF); Advertising_LED_2_Write(LED_OFF); CyBle_Start(AppCallBack); /*Initialization of encryption in BLE stack*/ #if (ENCRYPTION_ENABLED == YES) CR_Initialization(); #endif /*(ENCRYPTION_ENABLED == YES)*/ /* Set Serial Number string not initialised in GUI */ CyBle_DissSetCharacteristicValue(CYBLE_DIS_SERIAL_NUMBER, sizeof(serialNumber), (uint8 *)serialNumber); /* Disable bootloader service */ CyBle_GattsDisableAttribute(cyBle_customs[0].customServiceHandle); /* Force client to rediscover services in range of bootloader service */ WriteAttrServChanged(); WDT_Start(); while(1u == 1u) { if(CyBle_GetState() != CYBLE_STATE_INITIALIZING) { /* Enter DeepSleep mode between connection intervals */ lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); CyGlobalIntDisable; blessState = CyBle_GetBleSsState(); if(lpMode == CYBLE_BLESS_DEEPSLEEP) { if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) { CySysPmDeepSleep(); } } else { if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) { CySysPmSleep(); } } CyGlobalIntEnable; } CyBle_ProcessEvents(); /* If key press event was detected - debounce it and switch to bootloader emulator mode */ if (Bootloader_Service_Activation_Read() == 0u) { CyDelay(100u); if (Bootloader_Service_Activation_Read() == 0u) { DBG_PRINTF("Bootloader service activated!\r\n"); CyBle_GattsEnableAttribute(cyBle_customs[0u].customServiceHandle); LED_WRITE_MACRO(LED_OFF); bootloadingMode = 1u; /* Force client to rediscover services in range of bootloader service */ WriteAttrServChanged(); BootloaderEmulator_Start(); } } } }