/**************************************************************************//**
  \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;
}
Ejemplo n.º 3
0
/******************************************************************************
  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();
}