blob: e394de0416b00d0ed9df9314f39e3be2f095d9fb [file] [log] [blame]
/****************************************************************************
* arch/arm/src/lpc43xx/lpc43_aes.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/crypto/crypto.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "chip.h"
#include <hardware/lpc43_aes.h>
#define AES_BLOCK_SIZE 16
/****************************************************************************
* Private Data
****************************************************************************/
static struct lpc43_aes_s *g_aes;
/****************************************************************************
* Private Functions
****************************************************************************/
static int aes_init(const void *iv,
const void *key, uint32_t keysize,
int mode, int encrypt)
{
unsigned int cmd = 0;
unsigned int ret = 0;
if (g_aes == NULL)
{
return -ENOSYS;
}
/* The LPC43 aes engine can load two keys from otp and one random
* generated key. This behavior doesn't fit current api. So if
* key == NULL, we will usr keysize as identifier of the special key.
*/
if (keysize != 16 && key)
{
return -EINVAL;
}
if (mode != AES_MODE_ECB && mode != AES_MODE_CBC)
{
return -EINVAL;
}
if (encrypt == CYPHER_ENCRYPT)
{
cmd = mode == AES_MODE_ECB ?
AES_API_CMD_ENCODE_ECB : AES_API_CMD_ENCODE_CBC;
}
else
{
cmd = mode == AES_MODE_ECB ?
AES_API_CMD_DECODE_ECB : AES_API_CMD_DECODE_CBC;
}
g_aes->aes_init();
if (key != NULL)
{
g_aes->aes_load_key_sw(key);
}
else
{
switch (keysize)
{
case 0:
g_aes->aes_load_key1();
break;
case 1:
g_aes->aes_load_key2();
break;
case 2:
g_aes->aes_load_key_rng();
break;
}
}
g_aes->aes_load_iv_sw((const unsigned char *)iv);
ret = g_aes->aes_set_mode(cmd);
switch (ret)
{
case AES_API_ERR_WRONG_CMD:
case AES_API_ERR_NOT_SUPPORTED:
case AES_API_ERR_KEY_ALREADY_PROGRAMMED:
ret = -EINVAL;
break;
case AES_API_ERR_DMA_CHANNEL_CFG:
case AES_API_ERR_DMA_MUX_CFG:
case AES_API_ERR_DMA_BUSY:
ret = -EBUSY;
break;
}
return 0;
}
static int aes_update(const void *out,
uint32_t *outl, const void *in,
uint32_t inl)
{
if (g_aes == NULL)
{
return -ENOSYS;
}
if ((inl & (AES_BLOCK_SIZE - 1)) != 0)
{
return -EINVAL;
}
if (inl > *outl)
{
return -EINVAL;
}
return g_aes->aes_operate((unsigned char *)out,
(unsigned char *)in, inl / 16);
}
/****************************************************************************
* Public Functions
****************************************************************************/
int aes_cypher(void *out, const void *in, size_t size, const void *iv,
const void *key, size_t keysize, int mode, int encrypt)
{
unsigned int ret = 0;
uint32_t outl = size;
g_aes = (struct lpc43_g_aes *) * ((uint32_t *)LPC43_ROM_AES_DRIVER_TABLE);
ret = aes_init(iv, key, keysize, mode, encrypt);
if (ret != OK)
{
return ret;
}
return aes_update(out, &outl, in, size);
}