/**************************************************************************//** \brief Handles application command from appCmdQueue. \param None. \return None. ******************************************************************************/ void appCmdHandler(void) { AppCommand_t *currentCommand = appGetCommandToProcess(); if (currentCommand) { bool deleteCmd = true; AppCommandDescriptor_t cmdDesc; if (appGetCmdDescriptor(&cmdDesc, currentCommand->dongleCommandId)) { deleteCmd = cmdDesc.serviceVector(currentCommand); } if (deleteCmd) { putQueueElem(&appFreeCmdQueue, deleteHeadQueueElem(&appBusyCmdQueue)); } else { putQueueElem(&appBusyCmdQueue, deleteHeadQueueElem(&appBusyCmdQueue)); } appPostCmdHandlerTask(); } }
/**************************************************************************//** \brief Inserts new element into the command queue. \param[in,out] pCommandPtr - pointer to pointer to AppCommand_t. On the output if function returns true *pCommandPtr will refer to allocated cell. \return true if insertion was successful, false otherwise. ******************************************************************************/ bool appCreateCommand(AppCommand_t **pCommandPtr) { AppCmdQueueElement_t *appCmdQueueElement = NULL; QueueElement_t *freeElement = NULL; bool result = false; assert(pCommandPtr, CMDQUEUEINSERTASSERT_0); freeElement = getQueueElem(&appFreeCmdQueue); if (freeElement) { putQueueElem(&appBusyCmdQueue, deleteHeadQueueElem(&appFreeCmdQueue)); appCmdQueueElement = GET_STRUCT_BY_FIELD_POINTER(AppCmdQueueElement_t, next, freeElement); if (*pCommandPtr) { memcpy(&appCmdQueueElement->command, *pCommandPtr, sizeof(AppCommand_t)); } *pCommandPtr = &appCmdQueueElement->command; result = true; } appPostCmdHandlerTask(); return result; }
/****************************************************************************** Security Module task handler. Parameters: none Returns: none ******************************************************************************/ void halSmRequestHandler(void) { uint8_t i, j; uint8_t blockOffset = 0; HAL_SmEncryptReq_t *request; request = getQueueElem(&halSmRequestQueue); switch (request->command) { case SM_SET_KEY_COMMAND: { for (i = 0; i < HAL_SM_SECURITY_KEY_SIZE; i++) AES_KEY = request->text[i]; } break; case SM_ECB_DECRYPT_COMMAND: { // Derive decryption key by performing one dummy encryption AES_CTRL = (0 << AES_CTRL_DIR) | (0 << AES_CTRL_MODE); // ECB encryption // Load data to process for (j = 0; j < HAL_SM_SECURITY_BLOCK_SIZE; j++) AES_STATE = 0; // Dummy // Start processing AES_CTRL |= (1 << AES_CTRL_REQUEST); // Wait for operation to complete while (0 == (AES_STATUS & (1 << AES_STATUS_RY))); { // read decryption key and set it back uint8_t key[HAL_SM_SECURITY_KEY_SIZE]; for (i = 0; i < HAL_SM_SECURITY_KEY_SIZE; i++) key[i] = AES_KEY; for (i = 0; i < HAL_SM_SECURITY_KEY_SIZE; i++) AES_KEY = key[i]; } }; // fall through for further processing case SM_ECB_ENCRYPT_COMMAND: { for (i = 0; i < request->blockCount; i++) { if (SM_ECB_ENCRYPT_COMMAND == request->command) AES_CTRL = (0 << AES_CTRL_DIR) | (0 << AES_CTRL_MODE); // ECB encryption else AES_CTRL = (1 << AES_CTRL_DIR) | (0 << AES_CTRL_MODE); // ECB decryption // Load data to process for (j = 0; j < HAL_SM_SECURITY_BLOCK_SIZE; j++) AES_STATE = request->text[blockOffset + j]; // Start processing AES_CTRL |= (1 << AES_CTRL_REQUEST); // Wait for operation to complete while (0 == (AES_STATUS & (1 << AES_STATUS_RY))); // Store resulting data for (j = 0; j < HAL_SM_SECURITY_BLOCK_SIZE; j++) request->text[blockOffset + j] = AES_STATE; // Process the next block blockOffset += HAL_SM_SECURITY_BLOCK_SIZE; } } break; default: { assert(false, SECURITY_MODULE_INVALID_COMMAND); } break; } deleteHeadQueueElem(&halSmRequestQueue); if (getQueueElem(&halSmRequestQueue)) halPostTask3(HAL_SM_REQ); request->HAL_SmEncryptConf(); }