/**************************************************************************//** \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; }
/**************************************************************************//** \brief Returns pointer to first element in command queue. \return pointer to AppCommand_t if queue is not empty, NULL otherwise. ******************************************************************************/ static AppCommand_t *appGetCommandToProcess(void) { QueueElement_t *queueElement = getQueueElem(&appBusyCmdQueue); if (queueElement) { return &(GET_STRUCT_BY_FIELD_POINTER(AppCmdQueueElement_t, next, queueElement))->command; } return NULL; }
/****************************************************************************** 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(); }