diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index da53154dac3479c78d91632f56e8194173fc5870..327307c649a18fec9a45c555873805222a3ada3c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,7 @@ simulate-hello: script: - echo "Simulation phase started" - source set_env.sh - - socsim test_nanosoc TESTNAME=hello + - socsim test_aes128 TESTNAME=hello tags: - VLAB-ZCU diff --git a/.gitmodules b/.gitmodules index f6b2614ff9efc2cf19e2d79c8cd0c2495d20aee2..0f2cd4014d9852ec8a26c1e8bebd39de8e2fd36c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ path = rtl_primitives_tech url = https://git.soton.ac.uk/soclabs/rtl_primitives_tech.git branch = main +[submodule "secworks-aes"] + path = secworks-aes + url = https://github.com/secworks/aes.git diff --git a/README.md b/README.md index 6b24c626aea40c32de184a86bf41169f90a1d775..7e4f6dfb965bd61fb78c59f76d92de99b9178c6c 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,22 @@ -# Accelerator System Top-Level +# AES-128 Example Accelerator System Project -This repo is the top-level project repository which is used as a base for other projects to be built from. - -Please Fork this repository in order to build your own custom project. This can be done through the git.soton.ac.uk/soclabs/accelerator-project website and create your own custom project folder which you can then customise to suit your needs. +This repo is the top-level repository which contains an example accelerator based on the secworks AES engine integrated in SoC Labs provided nanosoc chip design IP in forms of git subrepositories. ### Cloning this repository --- This Repository contains multiple sub-repositories. In order to clone them with this repository, please use the following command: -`git clone --recurse https://git.soton.ac.uk/soclabs/accelerator-project.git` - -This will clone this base repository. Change the url in the command above to clone your fork instead of the base repository. +`git clone --recurse https://git.soton.ac.uk/soclabs/aes-128-project.git` -### Setting up the Project Environment +## Setting up the Project Environment --- In order to checkout all the sub-repositories in your project to their branches and set up your local environment variables, from the top-level of this project run: `source set_env.sh` -### Adding a Custom Accelerator Repository ---- - -Custom accelerator repsitories can be added to your forked project using the following commands: - -`cd $SOCLABS_PROJECT_DIR; git submodule add youracceleratorurl.git` - -Once this has been done, you should see a folder at the top-level of your project containing your accelerator repository. This will be on a hash and not on a branch. - -To get this repository to checkout to a branch, modify the top-level `projbranch` file to add your repository name (this should be the name of the directory it is in), followed by a colon and the name of the branch you wish it to check out to. - -Then re-run the set environment script and force it to checkout all subrepositories: - -`source set_env.sh -f` - -The last thing you will wish to do it to modify the `env/dependency_env.sh` file. In here you can set an environment variable for your repsotry so it can be used in scripts and commands. Once this has been added, again run set environment command: - -`source set_env.sh` - -### Setting up your environment +### Setting up the Project Environment --- Every time you wish to run commands in this project, you will need to make sure the set environment script has been run for your current terminal session. This is done by moving to the top-level of the project and running: @@ -77,14 +54,12 @@ Accelerator wrappers are located in `wrapper/src`. These should instantiate acce ## Running the simulation --- -socsim is a tool that SoC Labs have developed that allows for running of shell scripts anywhere within your project environment. The idea is these scripts can be customised to run scripts for different simulators. +This design instantiates a custom (AMBA-AHB) wrapper around the AES core to implement a memory-mapped 128-bit AES encrypt/decrypt accelerator that can be used as a software-driven peripheral or a semi-autonomous DMA subystem when 128-bit keys and variable length data payloads can be set up as scatter/gather descriptor chains for background processing. -These scripts are located in `simulate/socsim`. There are some example scripts in there and can be run using the following command, where hello is the testcase to be run: +To run the simulation the 'socsim' command executes the makefile in the 'nanosoc_tech' microcontroller framework. (Edit the simulator target in nanosoc_tech/system/makefile for the simulator EDA tool used). Then use the: - `socsim system_nanosoc TESTNAME=hello` - -To run the simulation the 'socsim' command executes the makefile in the 'nanosoc_tech' microcontroller framework. (Edit the simulator target in nanosoc_tech/nanosoc/makefile for the simulator EDA tool used). +`socsim system_aes128 TESTNAME=aes128_tests` -This runs the integration test program on the Arm Cortex-M0 processor using the 'system_nanosoc.sh' script provided in the simulate/socsim directory and the logs are produced in the simulate/sim/system_nanosoc/logs directory. +This runs the integration test program on the Arm Cortex-M0 processor using the 'system_aes128.sh' script provided in the simulate/socsim directory and the logs are produced in the simulate/sim/system_aes128/logs directory. diff --git a/env/dependency_env.sh b/env/dependency_env.sh index ae068452224ab59be67fae901619a2a40e040f52..ffe841d4a237482660fb9aca17172e06268c2384 100755 --- a/env/dependency_env.sh +++ b/env/dependency_env.sh @@ -15,7 +15,7 @@ #----------------------------------------------------------------------------- # Accelerator Engine -- Add Your Accelerator Environment Variable HERE! -#export ACCELERATOR_DIR="$SOCLABS_PROJECT_DIR/youraccelerator" +export ACCELERATOR_DIR="$SOCLABS_PROJECT_DIR/secworks-aes" # Accelerator Wrapper export SOCLABS_WRAPPER_TECH_DIR="$SOCLABS_PROJECT_DIR/accelerator_wrapper_tech" diff --git a/flist/project/accelerator.flist b/flist/project/accelerator.flist index f700bd701acf21fb2b2f15d4eb6c61f029805f1f..2bf1f3cca8cefb5be849d385cfaed848cf9b789a 100644 --- a/flist/project/accelerator.flist +++ b/flist/project/accelerator.flist @@ -14,10 +14,10 @@ // ============= Accelerator Module search path ============= // ! Point this to your Accelerator RTL -//+incdir+$(ACCELERATOR_DIR)/src/rtl ++incdir+$(ACCELERATOR_DIR)/src/rtl // ! Point this to your Wrapper RTL -//$(SOCLABS_PROJECT_DIR)/wrapper/src/your_wrapper.v +$(SOCLABS_PROJECT_DIR)/wrapper/src/soclabs_ahb_aes128_ctrl.v // ! Point this to your Subsystem RTL -//$(SOCLABS_PROJECT_DIR)/system/src/accelerator_subsystem.v \ No newline at end of file +$(SOCLABS_PROJECT_DIR)/system/src/accelerator_subsystem.v \ No newline at end of file diff --git a/projbranch b/projbranch index 3cf812e8c730c71ef903a1832de2ce712d70972f..822a736b9428c89bb5d4726f21ee944275d6064b 100644 --- a/projbranch +++ b/projbranch @@ -11,6 +11,7 @@ # Each Repo needs to have its branch set manually in here - they will defaultly be checked out to main # Project Repository Subrepository Branch Index # Add your Accelerator Repository here +secworks-aes: master nanosoc_tech: main accelerator_wrapper_tech: main diff --git a/secworks-aes b/secworks-aes new file mode 160000 index 0000000000000000000000000000000000000000..b9a3f1965b4e0568f0ca9b2d575ce6ea6fec2f36 --- /dev/null +++ b/secworks-aes @@ -0,0 +1 @@ +Subproject commit b9a3f1965b4e0568f0ca9b2d575ce6ea6fec2f36 diff --git a/simulate/socsim/regression_aes128.sh b/simulate/socsim/regression_aes128.sh new file mode 100755 index 0000000000000000000000000000000000000000..737c8ae3ac20a8dadf5f225d81560b2d081223f9 --- /dev/null +++ b/simulate/socsim/regression_aes128.sh @@ -0,0 +1,31 @@ +#----------------------------------------------------------------------------- +# SoC Labs Simulation script for system level verification +# A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. +# +# Contributors +# +# David Mapstone (d.a.mapstone@soton.ac.uk) +# +# Copyright 2023, SoC Labs (www.soclabs.org) +#----------------------------------------------------------------------------- + +#!/usr/bin/env bash + +# Get simulation name from name of script +SIM_NAME=`basename -s .sh "$0"` + +# Directory to put simulation files +SIM_DIR=$SOCLABS_PROJECT_DIR/simulate/sim/$SIM_NAME + +# Create Directory to put simulation files +mkdir -p $SIM_DIR +cd $SOCLABS_PROJECT_DIR/simulate/sim/$SIM_NAME + +# Compile Simulation +# Call makefile in NanoSoC Repo with options +echo ${2} +make -C $SOCLABS_NANOSOC_TECH_DIR regression_mti \ + SIM_DIR=$SIM_DIR \ + ACCELERATOR=yes \ + ${@:2} + diff --git a/simulate/socsim/test_aes128.sh b/simulate/socsim/test_aes128.sh new file mode 100755 index 0000000000000000000000000000000000000000..1bfacd413d1a7326dee7254953312d535c2a755a --- /dev/null +++ b/simulate/socsim/test_aes128.sh @@ -0,0 +1,31 @@ +#----------------------------------------------------------------------------- +# SoC Labs Simulation script for system level verification +# A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. +# +# Contributors +# +# David Mapstone (d.a.mapstone@soton.ac.uk) +# +# Copyright 2023, SoC Labs (www.soclabs.org) +#----------------------------------------------------------------------------- + +#!/usr/bin/env bash + +# Get simulation name from name of script +SIM_NAME=`basename -s .sh "$0"` + +# Directory to put simulation files +SIM_DIR=$SOCLABS_PROJECT_DIR/simulate/sim/$SIM_NAME + +# Create Directory to put simulation files +mkdir -p $SIM_DIR +cd $SOCLABS_PROJECT_DIR/simulate/sim/$SIM_NAME + +# Compile Simulation +# Call makefile in NanoSoC Repo with options +echo ${2} +make -C $SOCLABS_NANOSOC_TECH_DIR run_mti \ + SIM_DIR=$SIM_DIR \ + ACCELERATOR=yes \ + ${@:2} + diff --git a/system/src/accelerator_subsystem.v b/system/src/accelerator_subsystem.v new file mode 100644 index 0000000000000000000000000000000000000000..6e68edad48b81fb3e96af758649229329eaf826c --- /dev/null +++ b/system/src/accelerator_subsystem.v @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// SoC Labs Accelerator Subsystem for SecWorks AES-128 Accelerator +// A joint work commissioned on behalf of SoC Labs; under Arm Academic Access license. +// +// Contributors +// +// David Mapstone (d.a.mapstone@soton.ac.uk) +// David Flynn (d.w.flynn@soton.ac.uk) +// +// Copyright (C) 2023; SoC Labs (www.soclabs.org) +//----------------------------------------------------------------------------- + +module accelerator_subsystem #( + parameter SYS_ADDR_W = 32, + parameter SYS_DATA_W = 32, + parameter ACC_ADDR_W = 16, + parameter IRQ_NUM = 4 +) ( + input wire HCLK, // Clock + input wire HRESETn, // Reset + + // AHB connection to Initiator + input wire HSEL, + input wire [SYS_ADDR_W-1:0] HADDR, + input wire [1:0] HTRANS, + input wire [2:0] HSIZE, + input wire [3:0] HPROT, + input wire HWRITE, + input wire HREADY, + input wire [SYS_DATA_W-1:0] HWDATA, + + output wire HREADYOUT, + output wire HRESP, + output wire [SYS_DATA_W-1:0] HRDATA, + + // Data Request Signal to DMAC + output wire [1:0] EXP_DRQ, + input wire [1:0] EXP_DLAST, + + // Interrupts + output wire [IRQ_NUM-1:0] EXP_IRQ +); + + //-------------------------------------- + // AES Accelerator Wrapper + //-------------------------------------- + soclabs_ahb_aes128_ctrl u_exp_aes128 ( + .ahb_hclk (HCLK), + .ahb_hresetn (HRESETn), + .ahb_hsel (HSEL), + .ahb_haddr16 (HADDR[ACC_ADDR_W-1:0]), + .ahb_htrans (HTRANS), + .ahb_hwrite (HWRITE), + .ahb_hsize (HSIZE), + .ahb_hprot (HPROT), + .ahb_hwdata (HWDATA), + .ahb_hready (HREADY), + .ahb_hrdata (HRDATA), + .ahb_hreadyout (HREADYOUT), + .ahb_hresp (HRESP), + .drq_ipdma128 (EXP_DRQ[0]), + .dlast_ipdma128 (EXP_DLAST[0]), + .drq_opdma128 (EXP_DRQ[1]), + .dlast_opdma128 (EXP_DLAST[1]), + .irq_key128 (EXP_IRQ[0]), + .irq_ip128 (EXP_IRQ[1]), + .irq_op128 (EXP_IRQ[2]), + .irq_error (EXP_IRQ[3]), + .irq_merged ( ) + ); + +endmodule diff --git a/system/testcodes/aes128_tests_dma230/adp.cmd b/system/testcodes/aes128_tests_dma230/adp.cmd new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/system/testcodes/aes128_tests_dma230/adp.cmd @@ -0,0 +1 @@ + diff --git a/system/testcodes/aes128_tests_dma230/aes128.h b/system/testcodes/aes128_tests_dma230/aes128.h new file mode 100644 index 0000000000000000000000000000000000000000..202adf42b9efc670fa80c6c2b5335b9352b41cd0 --- /dev/null +++ b/system/testcodes/aes128_tests_dma230/aes128.h @@ -0,0 +1,71 @@ +#ifndef _AES128_H_ +#define _AES128_H_ + +#include <stdint.h> + +// define the API addresses here. + +#define AES128_BASE (0x60000000) + +// byte address I/O buffers +#define AES128_BUF_SIZE (0x4000) + +typedef struct { + __I uint32_t CORE_NAME[2]; /* 0x0000-0007 */ + __I uint32_t CORE_VERSION; /* 0x0008-000B */ + uint32_t RESRV0C; /* 0x000C */ + __IO uint32_t CTRL; /* 0x0010 */ + __O uint32_t CTRL_SET; /* 0x0014 */ + __O uint32_t CTRLL_CLR; /* 0x0018 */ + __I uint32_t STATUS; /* 0x001c */ + __IO uint32_t QUAL; /* 0x0020 */ + uint32_t RESRV24[3]; /* 0x0024 - 2F*/ + __IO uint32_t DRQ_MSK; /* 0x0030 */ + __O uint32_t DRQ_MSK_SET; /* 0x0034 */ + __O uint32_t DRQ_MSK_CLR; /* 0x0038 */ + __I uint32_t DRQ_STATUS; /* 0x003C */ + __IO uint32_t IRQ_MSK; /* 0x0040 */ + __O uint32_t IRQ_MSK_SET; /* 0x0044 */ + __O uint32_t IRQ_MSK_CLR; /* 0x0048 */ + __I uint32_t IRQ_STATUS; /* 0x004C */ + uint8_t RESRV50[AES128_BUF_SIZE - 0x50];/* 0x0050-0x3FFC (4096-20 words) */ + __IO uint8_t KEY128[AES128_BUF_SIZE]; /* 0x4000-7FFF (0x3FFF is last alias) */ + __IO uint8_t TXTIP128[AES128_BUF_SIZE]; /* 0x8000-BFFF (0x3FFF is last alias) */ + __I uint8_t TXTOP128[AES128_BUF_SIZE]; /* 0xC000-FFFF (0x3FFF is last alias) */ +} AES128_TypeDef; + +#define AES128 ((AES128_TypeDef *) AES128_BASE ) + +#define AES_BLOCK_SIZE 16 + +#define AES_KEY_LEN_128 16 + +#define HW32_REG(ADDRESS) (*((volatile unsigned long *)(ADDRESS))) + +#define AES128_CTRL_REG_WIDTH ( 8) +#define AES128_CTRL_BIT_MAX ( (CTRL_REG_WIDTH-1) +#define AES128_CTRL_KEY_REQ_BIT (1<<0) +#define AES128_CTRL_IP_REQ_BIT (1<<1) +#define AES128_CTRL_OP_REQ_BIT (1<<2) +#define AES128_CTRL_ERR_REQ_BIT (1<<3) +#define AES128_CTRL_BYPASS_BIT (1<<6) +#define AES128_CTRL_ENCODE_BIT (1<<7) +#define AES128_STAT_REG_WIDTH ( 8) +#define AES128_STAT_KEY_REQ_BIT (1<<0) +#define AES128_STAT_IP_REQ_BIT (1<<1) +#define AES128_STAT_OP_REQ_BIT (1<<2) +#define AES128_STAT_ERR_REQ_BIT (1<<3) +#define AES128_STAT_KEYOK_BIT (1<<4) +#define AES128_STAT_VALID_BIT (1<<5) +#define AES128_STAT_BYPASS_BIT (1<<6) +#define AES128_STAT_ENCODE_BIT (1<<7) +#define AES128_KEY_REQ_BIT (1<<0) +#define AES128_IP_REQ_BIT (1<<1) +#define AES128_OP_REQ_BIT (1<<2) +#define AES128_ERR_REQ_BIT (1<<3) +#define AES128_KEYOK_BIT (1<<4) +#define AES128_VALID_BIT (1<<5) +#define AES128_BYPASS_BIT (1<<6) +#define AES128_ENCODE_BIT (1<<7) + +#endif // _AES128_H_ diff --git a/system/testcodes/aes128_tests_dma230/aes128_tests_dma230.c b/system/testcodes/aes128_tests_dma230/aes128_tests_dma230.c new file mode 100644 index 0000000000000000000000000000000000000000..3db83d702d9ba0bc6450ff42a51dd838d7669d7f --- /dev/null +++ b/system/testcodes/aes128_tests_dma230/aes128_tests_dma230.c @@ -0,0 +1,843 @@ +#include "CMSDK_CM0.h" +#include "aes128.h" +#include <string.h> +#include "uart_stdout.h" +#include <stdio.h> +// memcopy implememtation +#define os_memcpy memcpy +#define os_memset memset +// PL230DMA implementation +#include "dma_pl230_driver.h" + + +static volatile dma_pl230_channel_data aes_ip_chain[2]; +static volatile dma_pl230_channel_data aes_op_chain[2]; + +int pl230_dma_detect(void); +int ID_Check(const unsigned int id_array[], unsigned int offset); + +// associate DMA channel numbers +#define DMA_CHAN_AES128_IP (0) +#define DMA_CHAN_AES128_OP (1) + +volatile int dma_done_irq_occurred; +volatile int dma_done_irq_expected; +volatile int dma_error_irq_occurred; +volatile int dma_error_irq_expected; +volatile int aes_key_irq_occurred; +volatile int aes_key_irq_expected; +volatile int aes_ip_irq_occurred; +volatile int aes_ip_irq_expected; +volatile int aes_op_irq_occurred; +volatile int aes_op_irq_expected; +volatile int aes_err_irq_occurred; +volatile int aes_err_irq_expected; + + uint8_t _test_key128[AES_KEY_LEN_128] = { + 0x75, 0x46, 0x20, 0x67, + 0x6e, 0x75, 0x4b, 0x20, + 0x79, 0x6d, 0x20, 0x73, + 0x74, 0x61, 0x68, 0x54 }; + + uint8_t test_key128[AES_KEY_LEN_128] = { + 0x54, 0x68, 0x61, 0x74, + 0x73, 0x20, 0x6d, 0x79, + 0x20, 0x4b, 0x75, 0x6e, + 0x67, 0x20, 0x46, 0x75 }; + + uint8_t buf128[AES_BLOCK_SIZE] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + + uint8_t _test_text128[AES_BLOCK_SIZE] = { + 0x6f, 0x77, 0x54, 0x20, + 0x65, 0x6e, 0x69, 0x4e, + 0x20, 0x65, 0x6e, 0x4f, + 0x20, 0x6f, 0x77, 0x54 }; + + uint8_t test_text128[AES_BLOCK_SIZE] = { + 0x54, 0x77, 0x6f, 0x20, + 0x4f, 0x6e, 0x65, 0x20, + 0x4e, 0x69, 0x6e, 0x65, + 0x20, 0x54, 0x77, 0x6f }; + + uint8_t test_exp128[AES_BLOCK_SIZE] = { + 0x29, 0xc3, 0x50, 0x5f, + 0x57, 0x14, 0x20, 0xf6, + 0x40, 0x22, 0x99, 0xb3, + 0x1a, 0x02, 0xd7, 0x3a }; + +// add extra block[128] with all zeros to toggle bits low + uint8_t shift_patt[129*16] = { + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//127 + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//128 + }; + + uint8_t shift_buf1[sizeof(shift_patt)]; + uint8_t shift_buf2[sizeof(shift_patt)]; + +#if defined ( __CC_ARM ) +__asm unsigned int address_test_read(unsigned int addr); +#else + unsigned int address_test_read(unsigned int addr); +#endif + +void HardFault_Handler_c(unsigned int * hardfault_args, unsigned lr_value); + +/* Global variables */ +volatile int hardfault_occurred; +volatile int hardfault_expected; +volatile int temp_data; + +/* Detect if DMA230 is in System */ +int pl230_dma_detect(void) +{ + int result; + int volatile rdata; /* dummy variable for read data in bus fault testing */ + unsigned const int pl230_id[12] = { + 0x30, 0xB2, 0x0B, 0x00, + 0x0D, 0xF0, 0x05, 0xB1}; + puts("Detect if DMA controller is present..."); + hardfault_occurred = 0; + hardfault_expected = 1; + rdata = address_test_read(CMSDK_PL230_BASE+ 0xFE0); + hardfault_expected = 0; + result = hardfault_occurred ? 1 : ID_Check(&pl230_id[0], CMSDK_PL230_BASE); + hardfault_occurred = 0; + if (result!=0) { + puts("** TEST SKIPPED ** DMA controller is not present.\n"); + UartEndSimulation(); + } + return(result); +} + +int ID_Check(const unsigned int id_array[], unsigned int offset) +{ + int i; + unsigned long expected_val, actual_val; + unsigned long compare_mask; + int mismatch = 0; + unsigned long test_addr; + + /* Check the peripheral ID and component ID */ + for (i=0;i<8;i++) { + test_addr = offset + 4*i + 0xFE0; + expected_val = id_array[i]; + actual_val = HW32_REG(test_addr); + + /* create mask to ignore version numbers */ + if (i==2) { compare_mask = 0xF0;} // mask out version field + else { compare_mask = 0x00;} // compare whole value + + if ((expected_val & (~compare_mask)) != (actual_val & (~compare_mask))) { + printf ("Difference found: %x, expected %x, actual %x\n", test_addr, expected_val, actual_val); + mismatch++; + } + + } // end_for + return (mismatch); +} + +/* Note: Hardware supports byte, half-word or word accesses + So memcpy() can be used to load/save data + And memset() can be used to pad out data-in to 128-bits + mode =0 (bypass), =1 (encode) or =2 (decode) +*/ +void aes128_driver_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, + uint8_t *result, uint8_t mode) +{ + // Reset engine + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + AES128->QUAL = 0; + AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT | AES128_CTRL_ERR_REQ_BIT; + + // Set up parameters + if (mode == 1) + AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode + if (mode == 0) + AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode + + AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + + // Program Key + os_memcpy((uint8_t *)AES128->KEY128, key, AES_KEY_LEN_128); + while (!(AES128->STATUS & AES128_KEYOK_BIT)) + ; + + /* payload */ + while(nbytes) { + uint8_t len = (nbytes > AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : nbytes; + /* Align/pad input and load into hardware */ + os_memcpy((uint8_t *)AES128->TXTIP128, input, len); + //patch up any zero-padding + if (len < AES_BLOCK_SIZE) + os_memset((uint8_t *)&(AES128->TXTIP128[len]), 0, AES_BLOCK_SIZE-len); + /* Auto-started! - no need for manual start */ + /* Poll until completed */ + while (!(AES128->STATUS & AES128_VALID_BIT)) + ; + os_memcpy(result, (uint8_t *)AES128->TXTOP128, AES_BLOCK_SIZE); + /* Accounting */ + input += len; + result += len; + nbytes -= len; + AES128->IRQ_MSK_SET = (AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + } + AES128->CTRL = 0; +} + +// wrapper functions + +void aes128_bypass_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 0); } + +void aes128_encrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 1); } + +void aes128_decrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 2); } + + +int aes128_buffer_verify(uint32_t buflen, uint8_t *buf_A, uint8_t *buf_B) +{ + int i, j, fail = 0; + for (i=0 ; i < buflen; i++) { + if (buf_A[i] != buf_B[i]){ + fail = 1; + break; + } + } + if (fail) { + j=i; // print offending block + for (i=(j - (j%16)) ; i < (j-(j%16)+16); i++) { + if (i%16==0) + printf(" //%03d\n", (i>>4)); + printf("0x%02x,", buf_A[i]); + } + } + if (fail){ + i=j; + printf("Verify compare FAIL\n EXPECTED_RESULT[%2d]= 0x%02x, ACTUAL_RESULT= 0x%02x \n",i, buf_B[i], buf_A[i]); + return(-1); + } + return(0); +} + +void aes128_driver_aligned_dma32(uint8_t *key, uint32_t nbytes, uint8_t *input, + uint8_t *result, uint8_t mode) +{ + int c; + // Reset engine + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + AES128->QUAL = 0; + AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT; + + // Set up parameters + if (mode == 1) + AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode + if (mode == 0) + AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode + + dma_pl230_data_struct_init(); // initialize + + // program DMA transfers in multiples of 4 words (nbytes scaled >>2 for words) + aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_W,4); + aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_W,4); + aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_W,4,PL230_CTRL_RPWR_4); + + aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_W,(nbytes>>2)); + aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2)); + aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4); + + c=DMA_CHAN_AES128_IP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W,(2*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4); + + aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2)); + aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_W,(nbytes>>2)); + aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4); + + c=DMA_CHAN_AES128_OP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4); + + // enable DMA controller channels + dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active + + // and enable DMA requests + AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + // test to ensure output DMA has started + while (!(dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP)))) + ; + while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP))) + ; + while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP))) + ; + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */ + dma_pl230_init(0); // none active + return; +} + +void aes128_driver_dma8(uint8_t *key, uint32_t nbytes, uint8_t *input, + uint8_t *result, uint8_t mode) +{ + int c; + // Reset engine + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + AES128->QUAL = 0; + AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT; + + // Set up parameters + if (mode == 1) + AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode + if (mode == 0) + AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode + + dma_pl230_data_struct_init(); // initialize + + // program DMA transfers in multiples of 16 bytes + aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_B,16); + aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_B,16); + aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_B,16,PL230_CTRL_RPWR_16); + + aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_B,(nbytes)); + aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes)); + aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16); + + c=DMA_CHAN_AES128_IP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W, (2*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W, (1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4); + + aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes)); + aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_B,(nbytes)); + aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16); + + c=DMA_CHAN_AES128_OP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4); + + // enable DMA controller channels + dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active + + // and enable DMA requests + AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + // test to ensure output DMA has started + while (!(dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP))) + ; + while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP)) + ; + while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP)) + ; + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */ + dma_pl230_init(0); // none active + return; +} + +// wrapper functions + +void aes128_alignchk_block_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result, uint8_t mode) + { uint32_t dma_max = DMA_PL230_MAX_XFERS; // default to 1 K bytes + if (((((long)key) & 3)==0) && ((((long)input) & 3)==0) && ((((long)result) & 3)==0)) dma_max=(DMA_PL230_MAX_XFERS<<2); + while (nbytes >dma_max) { + if (dma_max == DMA_PL230_MAX_XFERS) // 1K bytes DMA + aes128_driver_dma8(key, dma_max, input, result, mode); + else // 1K words DMA + aes128_driver_aligned_dma32(key, dma_max, input, result, mode); + nbytes -= dma_max; input += dma_max; result += dma_max; + } + if (dma_max == DMA_PL230_MAX_XFERS) // up to 1K bytes remaining + aes128_driver_dma8(key, nbytes, input, result, mode); + else // up to 1K words remaining + aes128_driver_aligned_dma32(key, nbytes, input, result, mode); + } + +void aes128_bypass_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_alignchk_block_dma (key, nbytes, input, result, 0); } + +void aes128_encrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_alignchk_block_dma (key, nbytes, input, result, 1); } + +void aes128_decrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_alignchk_block_dma (key, nbytes, input, result, 2); } + + +int main(void) { + + + char rx_char [256] = "SoCLabs AES128v1"; // init to 0 + unsigned char id_string [16] = {0}; + int i, fail=0; + unsigned char * p; + // Exception Handler Variables + temp_data=0; + hardfault_occurred = 0; + hardfault_expected = 0; + if (pl230_dma_detect()!=0) { + return 0; /* Quit test if DMA is not present */ + } + + UartStdOutInit(); + printf("%s\n",rx_char); + printf("AES128 test program\n"); + printf(" AES128 ID: "); + // iterate over 3 32-bit fields + p = (unsigned char *)AES128->CORE_NAME; + for (i = 0; i < 12; i++) { + id_string[i^3]=*p; // fix byte ordering per word + p+=1; + } + id_string[12] = 0; + printf("%s\n",id_string); + + aes_key_irq_occurred = 0; + aes_key_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP0_IRQn); + NVIC_EnableIRQ(EXP0_IRQn); + aes_ip_irq_occurred = 0; + aes_ip_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP1_IRQn); + NVIC_EnableIRQ(EXP1_IRQn); + aes_op_irq_occurred = 0; + aes_op_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP2_IRQn); + NVIC_EnableIRQ(EXP2_IRQn); + aes_err_irq_occurred = 0; + aes_err_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP3_IRQn); + NVIC_EnableIRQ(EXP3_IRQn); + + printf("AES128 SW (memcpy) tests...\n"); + printf(" AES128 reference pattern test\n"); + + printf(" AES128 input/output bypass test\n"); + aes128_bypass_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != 2){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 1){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); + + printf(" AES128 decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(buf128), buf128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + aes_key_irq_occurred = 0; + aes_ip_irq_occurred = 0; + aes_op_irq_occurred = 0; + aes_err_irq_occurred = 0; + + printf(" AES128 logic toggle test\n"); + printf(" AES128 input/output pattern test\n"); + aes128_bypass_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != (129+1)){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 129){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 pattern encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + printf(" AES128 pattern decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); + + printf("AES128 DMA tests...\n"); + + aes_key_irq_occurred = 0; + aes_ip_irq_occurred = 0; + aes_op_irq_occurred = 0; + aes_err_irq_occurred = 0; + dma_error_irq_expected = 0; + dma_error_irq_occurred = 0; + dma_done_irq_expected = 1; + dma_done_irq_occurred = 0; + NVIC_ClearPendingIRQ(DMA_IRQn); + NVIC_EnableIRQ(DMA_IRQn); + + printf(" AES128 dma input/output bypass test\n"); + aes128_bypass_dma(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (dma_done_irq_occurred < 2){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + printf(" AES128 dma encrypt test\n"); + aes128_encrypt_dma(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); + + printf(" AES128 dma decrypt test\n"); + aes128_decrypt_dma(test_key128, sizeof(buf128), buf128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (dma_done_irq_occurred < 6){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + printf(" AES128 dma unaligned pattern test\n"); + aes128_bypass_dma(test_key128,(16*63), shift_patt, shift_buf1+3); + fail += aes128_buffer_verify((16*63), shift_buf1+3, shift_patt); + + printf(" AES128 dma input/output pattern test\n"); + aes128_bypass_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); + printf(" AES128 dma pattern encrypt test\n"); + aes128_encrypt_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + printf(" AES128 dma pattern decrypt test\n"); + aes128_decrypt_dma(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); + + if (dma_done_irq_occurred < (2*7)){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + // check IRQ masked by DRQs - except when Iinput buffer empty after DMA done + if (aes_key_irq_occurred != 0){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != 7){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 0){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + NVIC_DisableIRQ(DMA_IRQn); + NVIC_DisableIRQ(EXP0_IRQn); + NVIC_DisableIRQ(EXP1_IRQn); + NVIC_DisableIRQ(EXP2_IRQn); + NVIC_DisableIRQ(EXP3_IRQn); + + printf ("Data retrieved from the AES is: %s\n", id_string); + printf ("Data expected from the AES is: %s\n", rx_char); + if (fail >0) + printf("** AES TESTS FAILED (%d) **\n", fail); + else + printf("** AES TEST PASSED **\n"); + // End simulation + + + UartEndSimulation(); + + return 0; + +} + +/* --------------------------------------------------------------- */ +/* Interrupt handlers */ +/* --------------------------------------------------------------- */ + +void DMA_Handler(void) +{ +if ((DMA_PL230_DMAC->ERR_CLR & 1) != 0) { + /* DMA interrupt is caused by DMA error */ + dma_error_irq_occurred ++; + DMA_PL230_DMAC->ERR_CLR = 1; /* Clear dma_err */ + if (dma_error_irq_expected==0) { + puts ("ERROR : Unexpected DMA error interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } + } +else { + // DMA interrupt is caused by DMA done + dma_done_irq_occurred ++; + if (dma_done_irq_expected==0) { + puts ("ERROR : Unexpected DMA done interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } + } +} + +void EXP0_Handler(void) +{ + // AES128 interrupt is caused by Key buffer empty IRQ + aes_key_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_KEY_REQ_BIT; + if (aes_key_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Key buffer empty request interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP1_Handler(void) +{ + // AES128 interrupt is caused by Input buffer empty IRQ + aes_ip_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_IP_REQ_BIT; + if (aes_ip_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Input buffer empty reqest interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP2_Handler(void) +{ + // AES128 interrupt is caused by Output buffer full IRQ + aes_op_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_OP_REQ_BIT; + if (aes_op_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Output buffer full reqest interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP3_Handler(void) +{ + // AES128 interrupt is caused by Error IRQ + aes_err_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_ERR_REQ_BIT; + if (aes_err_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Error interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +/* Test function for read */ +#if defined ( __CC_ARM ) +/* Test function for read - for ARM / Keil */ +__asm unsigned int address_test_read(unsigned int addr) +{ + LDR R1,[R0] + DSB ; Ensure bus fault occurred before leaving this subroutine + MOVS R0, R1 + BX LR +} +#else +/* Test function for read - for gcc */ +unsigned int address_test_read(unsigned int addr) __attribute__((naked)); +unsigned int address_test_read(unsigned int addr) +{ + __asm(" ldr r1,[r0]\n" + " dsb \n" + " movs r0, r1 \n" + " bx lr \n" + ); +} +#endif + +#if defined ( __CC_ARM ) +/* ARM or Keil toolchain */ +__asm void HardFault_Handler(void) +{ + MOVS r0, #4 + MOV r1, LR + TST r0, r1 + BEQ stacking_used_MSP + MRS R0, PSP ; // first parameter - stacking was using PSP + B get_LR_and_branch +stacking_used_MSP + MRS R0, MSP ; // first parameter - stacking was using MSP +get_LR_and_branch + MOV R1, LR ; // second parameter is LR current value + LDR R2,=__cpp(HardFault_Handler_c) + BX R2 + ALIGN +} +#else +/* gcc toolchain */ +void HardFault_Handler(void) __attribute__((naked)); +void HardFault_Handler(void) +{ + __asm(" movs r0,#4\n" + " mov r1,lr\n" + " tst r0,r1\n" + " beq stacking_used_MSP\n" + " mrs r0,psp\n" /* first parameter - stacking was using PSP */ + " ldr r1,=HardFault_Handler_c \n" + " bx r1\n" + "stacking_used_MSP:\n" + " mrs r0,msp\n" /* first parameter - stacking was using PSP */ + " ldr r1,=HardFault_Handler_c \n" + " bx r1\n" + ".pool\n" ); +} + +#endif +/* C part of the fault handler - common between ARM / Keil /gcc */ +void HardFault_Handler_c(unsigned int * hardfault_args, unsigned lr_value) +{ + unsigned int stacked_pc; + unsigned int stacked_r0; + hardfault_occurred++; + puts ("[Hard Fault Handler]"); + if (hardfault_expected==0) { + puts ("ERROR : Unexpected HardFault interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } + stacked_r0 = ((unsigned long) hardfault_args[0]); + stacked_pc = ((unsigned long) hardfault_args[6]); + printf(" - Stacked R0 : 0x%x\n", stacked_r0); + printf(" - Stacked PC : 0x%x\n", stacked_pc); + /* Modify R0 to a valid address */ + hardfault_args[0] = (unsigned long) &temp_data; + + return; +} \ No newline at end of file diff --git a/system/testcodes/aes128_tests_dma230/makefile b/system/testcodes/aes128_tests_dma230/makefile new file mode 100644 index 0000000000000000000000000000000000000000..3f41cf935611a5a40a401b3830b1a433c216f8b1 --- /dev/null +++ b/system/testcodes/aes128_tests_dma230/makefile @@ -0,0 +1,253 @@ +#----------------------------------------------------------------------------- +# The confidential and proprietary information contained in this file may +# only be used by a person authorised under and to the extent permitted +# by a subsisting licensing agreement from Arm Limited or its affiliates. +# +# (C) COPYRIGHT 2010-2013 Arm Limited or its affiliates. +# ALL RIGHTS RESERVED +# +# This entire notice must be reproduced on all copies of this file +# and copies of this file may only be made by a person if such person is +# permitted to do so under the terms of a subsisting license agreement +# from Arm Limited or its affiliates. +# +# SVN Information +# +# Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $ +# +# Revision : $Revision: 371321 $ +# +# Release Information : Cortex-M System Design Kit-r1p1-00rel0 +#----------------------------------------------------------------------------- +# +# Cortex-M System Design Kit software compilation make file +# +#----------------------------------------------------------------------------- +# +# Configurations +# +# Choose the core instantiated, can be +# - CORTEX_M0 +# - CORTEX_M0PLUS +CPU_PRODUCT = CORTEX_M0 + +# Shared software directory +SOFTWARE_DIR = $(SOCLABS_NANOSOC_TECH_DIR)/software +CMSIS_DIR = $(SOFTWARE_DIR)/cmsis +CORE_DIR = $(CMSIS_DIR)/CMSIS/Include + +ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + DEVICE_DIR = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0plus +else + DEVICE_DIR = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0 +endif + +# Program file +TESTNAME = aes128_tests_dma230 + +# Endian Option +COMPILE_BIGEND = 0 + +# Configuration +ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + USER_DEFINE = -DCORTEX_M0PLUS +else + USER_DEFINE = -DCORTEX_M0 +endif + +DEPS_LIST = makefile + +# Tool chain : ds5 / gcc / keil +TOOL_CHAIN = ds5 + +ifeq ($(TOOL_CHAIN),ds5) + ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + CPU_TYPE = --cpu Cortex-M0plus + else + CPU_TYPE = --cpu Cortex-M0 + endif +endif + +ifeq ($(TOOL_CHAIN),gcc) + ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + CPU_TYPE = -mcpu=cortex-m0plus + else + CPU_TYPE = -mcpu=cortex-m0 + endif +endif + +# Startup code directory for DS-5 +ifeq ($(TOOL_CHAIN),ds5) + STARTUP_DIR = $(DEVICE_DIR)/Source/ARM +endif + +# Startup code directory for gcc +ifeq ($(TOOL_CHAIN),gcc) + STARTUP_DIR = $(DEVICE_DIR)/Source/GCC +endif + +ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + STARTUP_FILE = startup_CMSDK_CM0plus + SYSTEM_FILE = system_CMSDK_CM0plus +else + STARTUP_FILE = startup_CMSDK_CM0 + SYSTEM_FILE = system_CMSDK_CM0 +endif + +# --------------------------------------------------------------------------------------- +# DS-5 options + +# MicroLIB option +COMPILE_MICROLIB = 0 + +# Small Multiply (Cortex-M0/M0+ has small multiplier option) +COMPILE_SMALLMUL = 0 + +ARM_CC_OPTIONS = -c -O3 -Ospace -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \ + -I $(SOFTWARE_DIR)/common/retarget -I $(SOFTWARE_DIR)/drivers $(USER_DEFINE) +ARM_ASM_OPTIONS = +ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \ + --no_debug --rw_base 0x30000000 --ro_base 0x00000000 --map --info sizes + +ifeq ($(COMPILE_BIGEND),1) + # Big Endian + ARM_CC_OPTIONS += --bigend + ARM_ASM_OPTIONS += --bigend + ARM_LINK_OPTIONS += --be8 +endif + +ifeq ($(COMPILE_MICROLIB),1) + # MicroLIB + ARM_CC_OPTIONS += --library_type=microlib + ARM_ASM_OPTIONS += --library_type=microlib --pd "__MICROLIB SETA 1" + ARM_LINK_OPTIONS += --library_type=microlib +endif + +ifeq ($(COMPILE_SMALLMUL),1) + # In Cortex-M0, small multiply takes 32 cycles + ARM_CC_OPTIONS += --multiply_latency=32 +endif + +# --------------------------------------------------------------------------------------- +# gcc options + +GNG_CC = arm-none-eabi-gcc +GNU_OBJDUMP = arm-none-eabi-objdump +GNU_OBJCOPY = arm-none-eabi-objcopy + +LINKER_SCRIPT_PATH = $(SOFTWARE_DIR)/common/scripts +LINKER_SCRIPT = $(LINKER_SCRIPT_PATH)/cmsdk_cm0.ld + +GNU_CC_FLAGS = -g -O3 -mthumb $(CPU_TYPE) + +ifeq ($(COMPILE_BIGEND),1) + # Big Endian + GNU_CC_FLAGS += -mbig-endian +endif + +# --------------------------------------------------------------------------------------- +all: all_$(TOOL_CHAIN) + +# --------------------------------------------------------------------------------------- +# DS-5 +all_ds5 : $(TESTNAME).hex $(TESTNAME).lst + +$(TESTNAME).o : $(TESTNAME).c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +dma_pl230_driver.o : $(SOFTWARE_DIR)/drivers/dma_pl230_driver.c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +$(SYSTEM_FILE).o : $(DEVICE_DIR)/Source/$(SYSTEM_FILE).c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +retarget.o : $(SOFTWARE_DIR)/common/retarget/retarget.c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +uart_stdout.o : $(SOFTWARE_DIR)/common/retarget/uart_stdout.c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +$(STARTUP_FILE).o : $(STARTUP_DIR)/$(STARTUP_FILE).s $(DEPS_LIST) + armasm $(ARM_ASM_OPTIONS) $(CPU_TYPE) $< -o $@ + +$(TESTNAME).ELF : $(TESTNAME).o dma_pl230_driver.o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o + armlink $(ARM_LINK_OPTIONS) -o $@ $(TESTNAME).o dma_pl230_driver.o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o + +$(TESTNAME).hex : $(TESTNAME).ELF + fromelf --vhx --8x1 $< --output $@ + +$(TESTNAME).lst : $(TESTNAME).ELF + fromelf -c -d -e -s -z -v $< --output $@ + +# --------------------------------------------------------------------------------------- +# gcc +all_gcc: + $(GNG_CC) $(GNU_CC_FLAGS) $(STARTUP_DIR)/$(STARTUP_FILE).s \ + $(TESTNAME).c \ + $(SOFTWARE_DIR)/common/retarget/retarget.c \ + $(SOFTWARE_DIR)/common/retarget/uart_stdout.c \ + $(DEVICE_DIR)/Source/$(SYSTEM_FILE).c \ + -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \ + -I $(SOFTWARE_DIR)/common/retarget \ + -I $(SOFTWARE_DIR)/drivers \ + -L $(LINKER_SCRIPT_PATH) \ + -D__STACK_SIZE=0x200 \ + -D__HEAP_SIZE=0x1000 \ + $(USER_DEFINE) -T $(LINKER_SCRIPT) -o $(TESTNAME).o + # Generate disassembly code + $(GNU_OBJDUMP) -S $(TESTNAME).o > $(TESTNAME).lst + # Generate binary file + $(GNU_OBJCOPY) -S $(TESTNAME).o -O binary $(TESTNAME).bin + # Generate hex file + $(GNU_OBJCOPY) -S $(TESTNAME).o -O verilog $(TESTNAME).hex + +# Note: +# If the version of object copy you are using does not support verilog hex file output, +# you can generate the hex file from binary file using the following command +# od -v -A n -t x1 --width=1 $(TESTNAME).bin > $(TESTNAME).hex + + +# --------------------------------------------------------------------------------------- +# Keil MDK + +all_keil: + @echo "Please compile your project code and press ENTER when ready" + @read dummy + +# --------------------------------------------------------------------------------------- +# Binary + +all_bin: $(TESTNAME).bin + # Generate hex file from binary + od -v -A n -t x1 --width=1 $(TESTNAME).bin > $(TESTNAME).hex + +# --------------------------------------------------------------------------------------- +# Clean +clean : + @rm -rf *.o + @if [ -e $(TESTNAME).hex ] ; then \ + rm -rf $(TESTNAME).hex ; \ + fi + @if [ -e $(TESTNAME).lst ] ; then \ + rm -rf $(TESTNAME).lst ; \ + fi + @if [ -e $(TESTNAME).ELF ] ; then \ + rm -rf $(TESTNAME).ELF ; \ + fi + @if [ -e $(TESTNAME).bin ] ; then \ + rm -rf $(TESTNAME).bin ; \ + fi + @rm -rf *.crf + @rm -rf *.plg + @rm -rf *.tra + @rm -rf *.htm + @rm -rf *.map + @rm -rf *.dep + @rm -rf *.d + @rm -rf *.lnp + @rm -rf *.bak + @rm -rf *.lst + @rm -rf *.axf + @rm -rf *.sct + @rm -rf *.__i + @rm -rf *._ia diff --git a/system/testcodes/aes128_tests_memcpy/adp.cmd b/system/testcodes/aes128_tests_memcpy/adp.cmd new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/system/testcodes/aes128_tests_memcpy/adp.cmd @@ -0,0 +1 @@ + diff --git a/system/testcodes/aes128_tests_memcpy/aes128.h b/system/testcodes/aes128_tests_memcpy/aes128.h new file mode 100644 index 0000000000000000000000000000000000000000..202adf42b9efc670fa80c6c2b5335b9352b41cd0 --- /dev/null +++ b/system/testcodes/aes128_tests_memcpy/aes128.h @@ -0,0 +1,71 @@ +#ifndef _AES128_H_ +#define _AES128_H_ + +#include <stdint.h> + +// define the API addresses here. + +#define AES128_BASE (0x60000000) + +// byte address I/O buffers +#define AES128_BUF_SIZE (0x4000) + +typedef struct { + __I uint32_t CORE_NAME[2]; /* 0x0000-0007 */ + __I uint32_t CORE_VERSION; /* 0x0008-000B */ + uint32_t RESRV0C; /* 0x000C */ + __IO uint32_t CTRL; /* 0x0010 */ + __O uint32_t CTRL_SET; /* 0x0014 */ + __O uint32_t CTRLL_CLR; /* 0x0018 */ + __I uint32_t STATUS; /* 0x001c */ + __IO uint32_t QUAL; /* 0x0020 */ + uint32_t RESRV24[3]; /* 0x0024 - 2F*/ + __IO uint32_t DRQ_MSK; /* 0x0030 */ + __O uint32_t DRQ_MSK_SET; /* 0x0034 */ + __O uint32_t DRQ_MSK_CLR; /* 0x0038 */ + __I uint32_t DRQ_STATUS; /* 0x003C */ + __IO uint32_t IRQ_MSK; /* 0x0040 */ + __O uint32_t IRQ_MSK_SET; /* 0x0044 */ + __O uint32_t IRQ_MSK_CLR; /* 0x0048 */ + __I uint32_t IRQ_STATUS; /* 0x004C */ + uint8_t RESRV50[AES128_BUF_SIZE - 0x50];/* 0x0050-0x3FFC (4096-20 words) */ + __IO uint8_t KEY128[AES128_BUF_SIZE]; /* 0x4000-7FFF (0x3FFF is last alias) */ + __IO uint8_t TXTIP128[AES128_BUF_SIZE]; /* 0x8000-BFFF (0x3FFF is last alias) */ + __I uint8_t TXTOP128[AES128_BUF_SIZE]; /* 0xC000-FFFF (0x3FFF is last alias) */ +} AES128_TypeDef; + +#define AES128 ((AES128_TypeDef *) AES128_BASE ) + +#define AES_BLOCK_SIZE 16 + +#define AES_KEY_LEN_128 16 + +#define HW32_REG(ADDRESS) (*((volatile unsigned long *)(ADDRESS))) + +#define AES128_CTRL_REG_WIDTH ( 8) +#define AES128_CTRL_BIT_MAX ( (CTRL_REG_WIDTH-1) +#define AES128_CTRL_KEY_REQ_BIT (1<<0) +#define AES128_CTRL_IP_REQ_BIT (1<<1) +#define AES128_CTRL_OP_REQ_BIT (1<<2) +#define AES128_CTRL_ERR_REQ_BIT (1<<3) +#define AES128_CTRL_BYPASS_BIT (1<<6) +#define AES128_CTRL_ENCODE_BIT (1<<7) +#define AES128_STAT_REG_WIDTH ( 8) +#define AES128_STAT_KEY_REQ_BIT (1<<0) +#define AES128_STAT_IP_REQ_BIT (1<<1) +#define AES128_STAT_OP_REQ_BIT (1<<2) +#define AES128_STAT_ERR_REQ_BIT (1<<3) +#define AES128_STAT_KEYOK_BIT (1<<4) +#define AES128_STAT_VALID_BIT (1<<5) +#define AES128_STAT_BYPASS_BIT (1<<6) +#define AES128_STAT_ENCODE_BIT (1<<7) +#define AES128_KEY_REQ_BIT (1<<0) +#define AES128_IP_REQ_BIT (1<<1) +#define AES128_OP_REQ_BIT (1<<2) +#define AES128_ERR_REQ_BIT (1<<3) +#define AES128_KEYOK_BIT (1<<4) +#define AES128_VALID_BIT (1<<5) +#define AES128_BYPASS_BIT (1<<6) +#define AES128_ENCODE_BIT (1<<7) + +#endif // _AES128_H_ diff --git a/system/testcodes/aes128_tests_memcpy/aes128_tests.c b/system/testcodes/aes128_tests_memcpy/aes128_tests.c new file mode 100644 index 0000000000000000000000000000000000000000..36bc54900904cd499bb5b92a8bfd15ec7568479f --- /dev/null +++ b/system/testcodes/aes128_tests_memcpy/aes128_tests.c @@ -0,0 +1,688 @@ +#include "CMSDK_CM0.h" +#include "aes128.h" +#include <string.h> +#include "uart_stdout.h" +#include <stdio.h> +// memcopy implememtation +#define os_memcpy memcpy +#define os_memset memset +// PL230DMA implementation +#include "dma_pl230_driver.h" + + +static volatile dma_pl230_channel_data aes_ip_chain[2]; +static volatile dma_pl230_channel_data aes_op_chain[2]; + +// associate DMA channel numbers +#define DMA_CHAN_AES128_IP (0) +#define DMA_CHAN_AES128_OP (1) + +volatile int dma_done_irq_occurred; +volatile int dma_done_irq_expected; +volatile int dma_error_irq_occurred; +volatile int dma_error_irq_expected; +volatile int aes_key_irq_occurred; +volatile int aes_key_irq_expected; +volatile int aes_ip_irq_occurred; +volatile int aes_ip_irq_expected; +volatile int aes_op_irq_occurred; +volatile int aes_op_irq_expected; +volatile int aes_err_irq_occurred; +volatile int aes_err_irq_expected; + + uint8_t _test_key128[AES_KEY_LEN_128] = { + 0x75, 0x46, 0x20, 0x67, + 0x6e, 0x75, 0x4b, 0x20, + 0x79, 0x6d, 0x20, 0x73, + 0x74, 0x61, 0x68, 0x54 }; + + uint8_t test_key128[AES_KEY_LEN_128] = { + 0x54, 0x68, 0x61, 0x74, + 0x73, 0x20, 0x6d, 0x79, + 0x20, 0x4b, 0x75, 0x6e, + 0x67, 0x20, 0x46, 0x75 }; + + uint8_t buf128[AES_BLOCK_SIZE] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + + uint8_t _test_text128[AES_BLOCK_SIZE] = { + 0x6f, 0x77, 0x54, 0x20, + 0x65, 0x6e, 0x69, 0x4e, + 0x20, 0x65, 0x6e, 0x4f, + 0x20, 0x6f, 0x77, 0x54 }; + + uint8_t test_text128[AES_BLOCK_SIZE] = { + 0x54, 0x77, 0x6f, 0x20, + 0x4f, 0x6e, 0x65, 0x20, + 0x4e, 0x69, 0x6e, 0x65, + 0x20, 0x54, 0x77, 0x6f }; + + uint8_t test_exp128[AES_BLOCK_SIZE] = { + 0x29, 0xc3, 0x50, 0x5f, + 0x57, 0x14, 0x20, 0xf6, + 0x40, 0x22, 0x99, 0xb3, + 0x1a, 0x02, 0xd7, 0x3a }; + +// add extra block[128] with all zeros to toggle bits low + uint8_t shift_patt[129*16] = { + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//127 + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//128 + }; + + uint8_t shift_buf1[sizeof(shift_patt)]; + uint8_t shift_buf2[sizeof(shift_patt)]; + + +/* Note: Hardware supports byte, half-word or word accesses + So memcpy() can be used to load/save data + And memset() can be used to pad out data-in to 128-bits + mode =0 (bypass), =1 (encode) or =2 (decode) +*/ +void aes128_driver_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, + uint8_t *result, uint8_t mode) +{ + // Reset engine + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + AES128->QUAL = 0; + AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT | AES128_CTRL_ERR_REQ_BIT; + + // Set up parameters + if (mode == 1) + AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode + if (mode == 0) + AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode + + AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + + // Program Key + os_memcpy((uint8_t *)AES128->KEY128, key, AES_KEY_LEN_128); + while (!(AES128->STATUS & AES128_KEYOK_BIT)) + ; + + /* payload */ + while(nbytes) { + uint8_t len = (nbytes > AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : nbytes; + /* Align/pad input and load into hardware */ + os_memcpy((uint8_t *)AES128->TXTIP128, input, len); + //patch up any zero-padding + if (len < AES_BLOCK_SIZE) + os_memset((uint8_t *)&(AES128->TXTIP128[len]), 0, AES_BLOCK_SIZE-len); + /* Auto-started! - no need for manual start */ + /* Poll until completed */ + while (!(AES128->STATUS & AES128_VALID_BIT)) + ; + os_memcpy(result, (uint8_t *)AES128->TXTOP128, AES_BLOCK_SIZE); + /* Accounting */ + input += len; + result += len; + nbytes -= len; + AES128->IRQ_MSK_SET = (AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + } + AES128->CTRL = 0; +} + +// wrapper functions + +void aes128_bypass_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 0); } + +void aes128_encrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 1); } + +void aes128_decrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 2); } + + +int aes128_buffer_verify(uint32_t buflen, uint8_t *buf_A, uint8_t *buf_B) +{ + int i, j, fail = 0; + for (i=0 ; i < buflen; i++) { + if (buf_A[i] != buf_B[i]){ + fail = 1; + break; + } + } + if (fail) { + j=i; // print offending block + for (i=(j - (j%16)) ; i < (j-(j%16)+16); i++) { + if (i%16==0) + printf(" //%03d\n", (i>>4)); + printf("0x%02x,", buf_A[i]); + } + } + if (fail){ + i=j; + printf("Verify compare FAIL\n EXPECTED_RESULT[%2d]= 0x%02x, ACTUAL_RESULT= 0x%02x \n",i, buf_B[i], buf_A[i]); + return(-1); + } + return(0); +} + +void aes128_driver_aligned_dma32(uint8_t *key, uint32_t nbytes, uint8_t *input, + uint8_t *result, uint8_t mode) +{ + int c; + // Reset engine + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + AES128->QUAL = 0; + AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT; + + // Set up parameters + if (mode == 1) + AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode + if (mode == 0) + AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode + + dma_pl230_data_struct_init(); // initialize + + // program DMA transfers in multiples of 4 words (nbytes scaled >>2 for words) + aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_W,4); + aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_W,4); + aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_W,4,PL230_CTRL_RPWR_4); + + aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_W,(nbytes>>2)); + aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2)); + aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4); + + c=DMA_CHAN_AES128_IP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W,(2*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4); + + aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_W,(nbytes>>2)); + aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_W,(nbytes>>2)); + aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_W,(nbytes>>2),PL230_CTRL_RPWR_4); + + c=DMA_CHAN_AES128_OP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4); + + // enable DMA controller channels + dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active + + // and enable DMA requests + AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + // test to ensure output DMA has started + while (!(dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP)))) + ; + while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP))) + ; + while (dma_pl230_channel_active((1<<DMA_CHAN_AES128_OP))) + ; + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */ + dma_pl230_init(0); // none active + return; +} + +void aes128_driver_dma8(uint8_t *key, uint32_t nbytes, uint8_t *input, + uint8_t *result, uint8_t mode) +{ + int c; + // Reset engine + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + AES128->QUAL = 0; + AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT; + + // Set up parameters + if (mode == 1) + AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode + if (mode == 0) + AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode + + dma_pl230_data_struct_init(); // initialize + + // program DMA transfers in multiples of 16 bytes + aes_ip_chain[0].SrcEndPointer = DMA_PL230_PTR_END(key,PL230_XFER_B,16); + aes_ip_chain[0].DstEndPointer = DMA_PL230_PTR_END(&(AES128->KEY128[AES128_BUF_SIZE-16]),PL230_XFER_B,16); + aes_ip_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_DEV_CHAIN_ALT,PL230_XFER_B,16,PL230_CTRL_RPWR_16); + + aes_ip_chain[1].SrcEndPointer = DMA_PL230_PTR_END(input,PL230_XFER_B,(nbytes)); + aes_ip_chain[1].DstEndPointer = DMA_PL230_PTR_END(&(AES128->TXTIP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes)); + aes_ip_chain[1].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16); + + c=DMA_CHAN_AES128_IP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_ip_chain[0].SrcEndPointer), PL230_XFER_W, (2*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W, (1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(2*4),PL230_CTRL_RPWR_4); + + aes_op_chain[0].SrcEndPointer = DMA_PL230_PTR_END(&(AES128->TXTOP128[AES128_BUF_SIZE-nbytes]),PL230_XFER_B,(nbytes)); + aes_op_chain[0].DstEndPointer = DMA_PL230_PTR_END(result,PL230_XFER_B,(nbytes)); + aes_op_chain[0].Control = DMA_PL230_CTRL(PL230_CTRL_CYCLE_BASIC,PL230_XFER_B,(nbytes),PL230_CTRL_RPWR_16); + + c=DMA_CHAN_AES128_OP; + dma_pl230_table->Primary[c].SrcEndPointer = DMA_PL230_PTR_END(&(aes_op_chain[0].SrcEndPointer), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].DstEndPointer = DMA_PL230_PTR_END(&(dma_pl230_table->Alternate[c]), PL230_XFER_W,(1*4)); + dma_pl230_table->Primary[c].Control= DMA_PL230_CTRL_DSTFIX(PL230_CTRL_CYCLE_DEV_CHAIN_PRI,PL230_XFER_W,(1*4),PL230_CTRL_RPWR_4); + + // enable DMA controller channels + dma_pl230_init((1<<DMA_CHAN_AES128_OP) | (1<<DMA_CHAN_AES128_IP)); // two active + + // and enable DMA requests + AES128->DRQ_MSK_SET = (AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + // test to ensure output DMA has started + while (!(dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP))) + ; + while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP)) + ; + while (dma_pl230_channel_active(1<<DMA_CHAN_AES128_OP)) + ; + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + DMA_PL230_DMAC->DMA_CFG = 0; /* Disable DMA controller for initialization */ + dma_pl230_init(0); // none active + return; +} + +// wrapper functions + +void aes128_alignchk_block_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result, uint8_t mode) + { uint32_t dma_max = DMA_PL230_MAX_XFERS; // default to 1 K bytes + if (((((long)key) & 3)==0) && ((((long)input) & 3)==0) && ((((long)result) & 3)==0)) dma_max=(DMA_PL230_MAX_XFERS<<2); + while (nbytes >dma_max) { + if (dma_max == DMA_PL230_MAX_XFERS) // 1K bytes DMA + aes128_driver_dma8(key, dma_max, input, result, mode); + else // 1K words DMA + aes128_driver_aligned_dma32(key, dma_max, input, result, mode); + nbytes -= dma_max; input += dma_max; result += dma_max; + } + if (dma_max == DMA_PL230_MAX_XFERS) // up to 1K bytes remaining + aes128_driver_dma8(key, nbytes, input, result, mode); + else // up to 1K words remaining + aes128_driver_aligned_dma32(key, nbytes, input, result, mode); + } + +void aes128_bypass_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_alignchk_block_dma (key, nbytes, input, result, 0); } + +void aes128_encrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_alignchk_block_dma (key, nbytes, input, result, 1); } + +void aes128_decrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_alignchk_block_dma (key, nbytes, input, result, 2); } + + +int main(void) { + char rx_char [256] = "SoCLabs AES128v1"; // init to 0 + unsigned char id_string [16] = {0}; + int i, fail=0; + unsigned char * p; + + UartStdOutInit(); + printf("%s\n",rx_char); + printf("AES128 test program\n"); + printf(" AES128 ID: "); + // iterate over 3 32-bit fields + p = (unsigned char *)AES128->CORE_NAME; + for (i = 0; i < 12; i++) { + id_string[i^3]=*p; // fix byte ordering per word + p+=1; + } + id_string[12] = 0; + printf("%s\n",id_string); + + aes_key_irq_occurred = 0; + aes_key_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP0_IRQn); + NVIC_EnableIRQ(EXP0_IRQn); + aes_ip_irq_occurred = 0; + aes_ip_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP1_IRQn); + NVIC_EnableIRQ(EXP1_IRQn); + aes_op_irq_occurred = 0; + aes_op_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP2_IRQn); + NVIC_EnableIRQ(EXP2_IRQn); + aes_err_irq_occurred = 0; + aes_err_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP3_IRQn); + NVIC_EnableIRQ(EXP3_IRQn); + + printf("AES128 SW (memcpy) tests...\n"); + printf(" AES128 reference pattern test\n"); + + printf(" AES128 input/output bypass test\n"); + aes128_bypass_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != 2){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 1){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); + + printf(" AES128 decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(buf128), buf128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + aes_key_irq_occurred = 0; + aes_ip_irq_occurred = 0; + aes_op_irq_occurred = 0; + aes_err_irq_occurred = 0; + + printf(" AES128 logic toggle test\n"); + printf(" AES128 input/output pattern test\n"); + aes128_bypass_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != (129+1)){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 129){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 pattern encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + printf(" AES128 pattern decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); + + printf("AES128 DMA tests...\n"); + + aes_key_irq_occurred = 0; + aes_ip_irq_occurred = 0; + aes_op_irq_occurred = 0; + aes_err_irq_occurred = 0; + dma_error_irq_expected = 0; + dma_error_irq_occurred = 0; + dma_done_irq_expected = 1; + dma_done_irq_occurred = 0; + NVIC_ClearPendingIRQ(DMA_IRQn); + NVIC_EnableIRQ(DMA_IRQn); + + printf(" AES128 dma input/output bypass test\n"); + aes128_bypass_dma(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (dma_done_irq_occurred < 2){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + printf(" AES128 dma encrypt test\n"); + aes128_encrypt_dma(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); + + printf(" AES128 dma decrypt test\n"); + aes128_decrypt_dma(test_key128, sizeof(buf128), buf128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (dma_done_irq_occurred < 6){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + printf(" AES128 dma unaligned pattern test\n"); + aes128_bypass_dma(test_key128,(16*63), shift_patt, shift_buf1+3); + fail += aes128_buffer_verify((16*63), shift_buf1+3, shift_patt); + + printf(" AES128 dma input/output pattern test\n"); + aes128_bypass_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); + printf(" AES128 dma pattern encrypt test\n"); + aes128_encrypt_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + printf(" AES128 dma pattern decrypt test\n"); + aes128_decrypt_dma(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); + + if (dma_done_irq_occurred < (2*7)){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + // check IRQ masked by DRQs - except when Iinput buffer empty after DMA done + if (aes_key_irq_occurred != 0){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != 7){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 0){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + NVIC_DisableIRQ(DMA_IRQn); + NVIC_DisableIRQ(EXP0_IRQn); + NVIC_DisableIRQ(EXP1_IRQn); + NVIC_DisableIRQ(EXP2_IRQn); + NVIC_DisableIRQ(EXP3_IRQn); + + printf ("Data retrieved from the AES is: %s\n", id_string); + printf ("Data expected from the AES is: %s\n", rx_char); + if (fail >0) + printf("** AES TESTS FAILED (%d) **\n", fail); + else + printf("** AES TEST PASSED **\n"); + // End simulation + + + UartEndSimulation(); + + return 0; + +} + +/* --------------------------------------------------------------- */ +/* Interrupt handlers */ +/* --------------------------------------------------------------- */ + +void DMA_Handler(void) +{ +if ((DMA_PL230_DMAC->ERR_CLR & 1) != 0) { + /* DMA interrupt is caused by DMA error */ + dma_error_irq_occurred ++; + DMA_PL230_DMAC->ERR_CLR = 1; /* Clear dma_err */ + if (dma_error_irq_expected==0) { + puts ("ERROR : Unexpected DMA error interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } + } +else { + // DMA interrupt is caused by DMA done + dma_done_irq_occurred ++; + if (dma_done_irq_expected==0) { + puts ("ERROR : Unexpected DMA done interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } + } +} + +void EXP0_Handler(void) +{ + // AES128 interrupt is caused by Key buffer empty IRQ + aes_key_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_KEY_REQ_BIT; + if (aes_key_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Key buffer empty request interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP1_Handler(void) +{ + // AES128 interrupt is caused by Input buffer empty IRQ + aes_ip_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_IP_REQ_BIT; + if (aes_ip_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Input buffer empty reqest interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP2_Handler(void) +{ + // AES128 interrupt is caused by Output buffer full IRQ + aes_op_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_OP_REQ_BIT; + if (aes_op_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Output buffer full reqest interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP3_Handler(void) +{ + // AES128 interrupt is caused by Error IRQ + aes_err_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_ERR_REQ_BIT; + if (aes_err_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Error interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + diff --git a/system/testcodes/aes128_tests_memcpy/aes128_tests_memcpy.c b/system/testcodes/aes128_tests_memcpy/aes128_tests_memcpy.c new file mode 100644 index 0000000000000000000000000000000000000000..598d344a351959e33bb00da70b9ab533cef4a80c --- /dev/null +++ b/system/testcodes/aes128_tests_memcpy/aes128_tests_memcpy.c @@ -0,0 +1,435 @@ +#include "CMSDK_CM0.h" +#include "aes128.h" +#include <string.h> +#include "uart_stdout.h" +#include <stdio.h> +// memcopy implememtation +#define os_memcpy memcpy +#define os_memset memset + +volatile int aes_key_irq_occurred; +volatile int aes_key_irq_expected; +volatile int aes_ip_irq_occurred; +volatile int aes_ip_irq_expected; +volatile int aes_op_irq_occurred; +volatile int aes_op_irq_expected; +volatile int aes_err_irq_occurred; +volatile int aes_err_irq_expected; + + uint8_t _test_key128[AES_KEY_LEN_128] = { + 0x75, 0x46, 0x20, 0x67, + 0x6e, 0x75, 0x4b, 0x20, + 0x79, 0x6d, 0x20, 0x73, + 0x74, 0x61, 0x68, 0x54 }; + + uint8_t test_key128[AES_KEY_LEN_128] = { + 0x54, 0x68, 0x61, 0x74, + 0x73, 0x20, 0x6d, 0x79, + 0x20, 0x4b, 0x75, 0x6e, + 0x67, 0x20, 0x46, 0x75 }; + + uint8_t buf128[AES_BLOCK_SIZE] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + + uint8_t _test_text128[AES_BLOCK_SIZE] = { + 0x6f, 0x77, 0x54, 0x20, + 0x65, 0x6e, 0x69, 0x4e, + 0x20, 0x65, 0x6e, 0x4f, + 0x20, 0x6f, 0x77, 0x54 }; + + uint8_t test_text128[AES_BLOCK_SIZE] = { + 0x54, 0x77, 0x6f, 0x20, + 0x4f, 0x6e, 0x65, 0x20, + 0x4e, 0x69, 0x6e, 0x65, + 0x20, 0x54, 0x77, 0x6f }; + + uint8_t test_exp128[AES_BLOCK_SIZE] = { + 0x29, 0xc3, 0x50, 0x5f, + 0x57, 0x14, 0x20, 0xf6, + 0x40, 0x22, 0x99, 0xb3, + 0x1a, 0x02, 0xd7, 0x3a }; + +// add extra block[128] with all zeros to toggle bits low + uint8_t shift_patt[129*16] = { + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//127 + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//128 + }; + + uint8_t shift_buf1[sizeof(shift_patt)]; + uint8_t shift_buf2[sizeof(shift_patt)]; + + +/* Note: Hardware supports byte, half-word or word accesses + So memcpy() can be used to load/save data + And memset() can be used to pad out data-in to 128-bits + mode =0 (bypass), =1 (encode) or =2 (decode) +*/ +void aes128_driver_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, + uint8_t *result, uint8_t mode) +{ + // Reset engine + AES128->DRQ_MSK = 0; + AES128->IRQ_MSK = 0; + AES128->QUAL = 0; + AES128->CTRL = AES128_CTRL_KEY_REQ_BIT | AES128_CTRL_IP_REQ_BIT | AES128_CTRL_OP_REQ_BIT | AES128_CTRL_ERR_REQ_BIT; + + // Set up parameters + if (mode == 1) + AES128->CTRL_SET = AES128_ENCODE_BIT; // ENCODE mode + if (mode == 0) + AES128->CTRL_SET = AES128_BYPASS_BIT; // BYPASS mode + + AES128->IRQ_MSK_SET = (AES128_ERR_REQ_BIT | AES128_KEY_REQ_BIT | AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + + // Program Key + os_memcpy((uint8_t *)AES128->KEY128, key, AES_KEY_LEN_128); + while (!(AES128->STATUS & AES128_KEYOK_BIT)) + ; + + /* payload */ + while(nbytes) { + uint8_t len = (nbytes > AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : nbytes; + /* Align/pad input and load into hardware */ + os_memcpy((uint8_t *)AES128->TXTIP128, input, len); + //patch up any zero-padding + if (len < AES_BLOCK_SIZE) + os_memset((uint8_t *)&(AES128->TXTIP128[len]), 0, AES_BLOCK_SIZE-len); + /* Auto-started! - no need for manual start */ + /* Poll until completed */ + while (!(AES128->STATUS & AES128_VALID_BIT)) + ; + os_memcpy(result, (uint8_t *)AES128->TXTOP128, AES_BLOCK_SIZE); + /* Accounting */ + input += len; + result += len; + nbytes -= len; + AES128->IRQ_MSK_SET = (AES128_IP_REQ_BIT | AES128_OP_REQ_BIT); + } + AES128->CTRL = 0; +} + +// wrapper functions + +void aes128_bypass_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 0); } + +void aes128_encrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 1); } + +void aes128_decrypt_memcpy(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t *result) + { aes128_driver_memcpy(key, nbytes, input, result, 2); } + + +int aes128_buffer_verify(uint32_t buflen, uint8_t *buf_A, uint8_t *buf_B) +{ + int i, j, fail = 0; + for (i=0 ; i < buflen; i++) { + if (buf_A[i] != buf_B[i]){ + fail = 1; + break; + } + } + if (fail) { + j=i; // print offending block + for (i=(j - (j%16)) ; i < (j-(j%16)+16); i++) { + if (i%16==0) + printf(" //%03d\n", (i>>4)); + printf("0x%02x,", buf_A[i]); + } + } + if (fail){ + i=j; + printf("Verify compare FAIL\n EXPECTED_RESULT[%2d]= 0x%02x, ACTUAL_RESULT= 0x%02x \n",i, buf_B[i], buf_A[i]); + return(-1); + } + return(0); +} + + +int main(void) { + char rx_char [256] = "SoCLabs AES128v1"; // init to 0 + unsigned char id_string [16] = {0}; + int i, fail=0; + unsigned char * p; + + UartStdOutInit(); + printf("%s\n",rx_char); + printf("AES128 test program\n"); + printf(" AES128 ID: "); + // iterate over 3 32-bit fields + p = (unsigned char *)AES128->CORE_NAME; + for (i = 0; i < 12; i++) { + id_string[i^3]=*p; // fix byte ordering per word + p+=1; + } + id_string[12] = 0; + printf("%s\n",id_string); + + aes_key_irq_occurred = 0; + aes_key_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP0_IRQn); + NVIC_EnableIRQ(EXP0_IRQn); + aes_ip_irq_occurred = 0; + aes_ip_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP1_IRQn); + NVIC_EnableIRQ(EXP1_IRQn); + aes_op_irq_occurred = 0; + aes_op_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP2_IRQn); + NVIC_EnableIRQ(EXP2_IRQn); + aes_err_irq_occurred = 0; + aes_err_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP3_IRQn); + NVIC_EnableIRQ(EXP3_IRQn); + + printf("AES128 SW (memcpy) tests...\n"); + printf(" AES128 reference pattern test\n"); + + printf(" AES128 input/output bypass test\n"); + aes128_bypass_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != 2){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 1){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); + + printf(" AES128 decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(buf128), buf128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + aes_key_irq_occurred = 0; + aes_ip_irq_occurred = 0; + aes_op_irq_occurred = 0; + aes_err_irq_occurred = 0; + + printf(" AES128 logic toggle test\n"); + printf(" AES128 input/output pattern test\n"); + aes128_bypass_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != (129+1)){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 129){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 pattern encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + printf(" AES128 pattern decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); + + NVIC_DisableIRQ(EXP0_IRQn); + NVIC_DisableIRQ(EXP1_IRQn); + NVIC_DisableIRQ(EXP2_IRQn); + NVIC_DisableIRQ(EXP3_IRQn); + + printf ("Data retrieved from the AES is: %s\n", id_string); + printf ("Data expected from the AES is: %s\n", rx_char); + if (fail >0) + printf("** AES TESTS FAILED (%d) **\n", fail); + else + printf("** AES TEST PASSED **\n"); + // End simulation + + + UartEndSimulation(); + + return 0; + +} + +/* --------------------------------------------------------------- */ +/* Interrupt handlers */ +/* --------------------------------------------------------------- */ + +void EXP0_Handler(void) +{ + // AES128 interrupt is caused by Key buffer empty IRQ + aes_key_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_KEY_REQ_BIT; + if (aes_key_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Key buffer empty request interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP1_Handler(void) +{ + // AES128 interrupt is caused by Input buffer empty IRQ + aes_ip_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_IP_REQ_BIT; + if (aes_ip_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Input buffer empty reqest interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP2_Handler(void) +{ + // AES128 interrupt is caused by Output buffer full IRQ + aes_op_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_OP_REQ_BIT; + if (aes_op_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Output buffer full reqest interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + +void EXP3_Handler(void) +{ + // AES128 interrupt is caused by Error IRQ + aes_err_irq_occurred ++; + AES128->IRQ_MSK_CLR = AES128_ERR_REQ_BIT; + if (aes_err_irq_expected==0) { + puts ("ERROR : Unexpected AES128 Error interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } +} + diff --git a/system/testcodes/aes128_tests_memcpy/makefile b/system/testcodes/aes128_tests_memcpy/makefile new file mode 100644 index 0000000000000000000000000000000000000000..ef85d4e64d70bf3df1b5cc4963a54aa7f3debddc --- /dev/null +++ b/system/testcodes/aes128_tests_memcpy/makefile @@ -0,0 +1,253 @@ +#----------------------------------------------------------------------------- +# The confidential and proprietary information contained in this file may +# only be used by a person authorised under and to the extent permitted +# by a subsisting licensing agreement from Arm Limited or its affiliates. +# +# (C) COPYRIGHT 2010-2013 Arm Limited or its affiliates. +# ALL RIGHTS RESERVED +# +# This entire notice must be reproduced on all copies of this file +# and copies of this file may only be made by a person if such person is +# permitted to do so under the terms of a subsisting license agreement +# from Arm Limited or its affiliates. +# +# SVN Information +# +# Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $ +# +# Revision : $Revision: 371321 $ +# +# Release Information : Cortex-M System Design Kit-r1p1-00rel0 +#----------------------------------------------------------------------------- +# +# Cortex-M System Design Kit software compilation make file +# +#----------------------------------------------------------------------------- +# +# Configurations +# +# Choose the core instantiated, can be +# - CORTEX_M0 +# - CORTEX_M0PLUS +CPU_PRODUCT = CORTEX_M0 + +# Shared software directory +SOFTWARE_DIR = $(SOCLABS_NANOSOC_TECH_DIR)/software +CMSIS_DIR = $(SOFTWARE_DIR)/cmsis +CORE_DIR = $(CMSIS_DIR)/CMSIS/Include + +ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + DEVICE_DIR = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0plus +else + DEVICE_DIR = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0 +endif + +# Program file +TESTNAME = aes128_tests_memcpy + +# Endian Option +COMPILE_BIGEND = 0 + +# Configuration +ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + USER_DEFINE = -DCORTEX_M0PLUS +else + USER_DEFINE = -DCORTEX_M0 +endif + +DEPS_LIST = makefile + +# Tool chain : ds5 / gcc / keil +TOOL_CHAIN = ds5 + +ifeq ($(TOOL_CHAIN),ds5) + ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + CPU_TYPE = --cpu Cortex-M0plus + else + CPU_TYPE = --cpu Cortex-M0 + endif +endif + +ifeq ($(TOOL_CHAIN),gcc) + ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + CPU_TYPE = -mcpu=cortex-m0plus + else + CPU_TYPE = -mcpu=cortex-m0 + endif +endif + +# Startup code directory for DS-5 +ifeq ($(TOOL_CHAIN),ds5) + STARTUP_DIR = $(DEVICE_DIR)/Source/ARM +endif + +# Startup code directory for gcc +ifeq ($(TOOL_CHAIN),gcc) + STARTUP_DIR = $(DEVICE_DIR)/Source/GCC +endif + +ifeq ($(CPU_PRODUCT),CORTEX_M0PLUS) + STARTUP_FILE = startup_CMSDK_CM0plus + SYSTEM_FILE = system_CMSDK_CM0plus +else + STARTUP_FILE = startup_CMSDK_CM0 + SYSTEM_FILE = system_CMSDK_CM0 +endif + +# --------------------------------------------------------------------------------------- +# DS-5 options + +# MicroLIB option +COMPILE_MICROLIB = 0 + +# Small Multiply (Cortex-M0/M0+ has small multiplier option) +COMPILE_SMALLMUL = 0 + +ARM_CC_OPTIONS = -c -O3 -Ospace -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \ + -I $(SOFTWARE_DIR)/common/retarget -I $(SOFTWARE_DIR)/drivers $(USER_DEFINE) +ARM_ASM_OPTIONS = +ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \ + --no_debug --rw_base 0x30000000 --ro_base 0x00000000 --map --info sizes + +ifeq ($(COMPILE_BIGEND),1) + # Big Endian + ARM_CC_OPTIONS += --bigend + ARM_ASM_OPTIONS += --bigend + ARM_LINK_OPTIONS += --be8 +endif + +ifeq ($(COMPILE_MICROLIB),1) + # MicroLIB + ARM_CC_OPTIONS += --library_type=microlib + ARM_ASM_OPTIONS += --library_type=microlib --pd "__MICROLIB SETA 1" + ARM_LINK_OPTIONS += --library_type=microlib +endif + +ifeq ($(COMPILE_SMALLMUL),1) + # In Cortex-M0, small multiply takes 32 cycles + ARM_CC_OPTIONS += --multiply_latency=32 +endif + +# --------------------------------------------------------------------------------------- +# gcc options + +GNG_CC = arm-none-eabi-gcc +GNU_OBJDUMP = arm-none-eabi-objdump +GNU_OBJCOPY = arm-none-eabi-objcopy + +LINKER_SCRIPT_PATH = $(SOFTWARE_DIR)/common/scripts +LINKER_SCRIPT = $(LINKER_SCRIPT_PATH)/cmsdk_cm0.ld + +GNU_CC_FLAGS = -g -O3 -mthumb $(CPU_TYPE) + +ifeq ($(COMPILE_BIGEND),1) + # Big Endian + GNU_CC_FLAGS += -mbig-endian +endif + +# --------------------------------------------------------------------------------------- +all: all_$(TOOL_CHAIN) + +# --------------------------------------------------------------------------------------- +# DS-5 +all_ds5 : $(TESTNAME).hex $(TESTNAME).lst + +$(TESTNAME).o : $(TESTNAME).c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +dma_pl230_driver.o : $(SOFTWARE_DIR)/drivers/dma_pl230_driver.c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +$(SYSTEM_FILE).o : $(DEVICE_DIR)/Source/$(SYSTEM_FILE).c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +retarget.o : $(SOFTWARE_DIR)/common/retarget/retarget.c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +uart_stdout.o : $(SOFTWARE_DIR)/common/retarget/uart_stdout.c $(DEPS_LIST) + armcc $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o $@ + +$(STARTUP_FILE).o : $(STARTUP_DIR)/$(STARTUP_FILE).s $(DEPS_LIST) + armasm $(ARM_ASM_OPTIONS) $(CPU_TYPE) $< -o $@ + +$(TESTNAME).ELF : $(TESTNAME).o dma_pl230_driver.o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o + armlink $(ARM_LINK_OPTIONS) -o $@ $(TESTNAME).o $(SYSTEM_FILE).o $(STARTUP_FILE).o retarget.o uart_stdout.o + +$(TESTNAME).hex : $(TESTNAME).ELF + fromelf --vhx --8x1 $< --output $@ + +$(TESTNAME).lst : $(TESTNAME).ELF + fromelf -c -d -e -s -z -v $< --output $@ + +# --------------------------------------------------------------------------------------- +# gcc +all_gcc: + $(GNG_CC) $(GNU_CC_FLAGS) $(STARTUP_DIR)/$(STARTUP_FILE).s \ + $(TESTNAME).c \ + $(SOFTWARE_DIR)/common/retarget/retarget.c \ + $(SOFTWARE_DIR)/common/retarget/uart_stdout.c \ + $(DEVICE_DIR)/Source/$(SYSTEM_FILE).c \ + -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \ + -I $(SOFTWARE_DIR)/common/retarget \ + -I $(SOFTWARE_DIR)/drivers \ + -L $(LINKER_SCRIPT_PATH) \ + -D__STACK_SIZE=0x200 \ + -D__HEAP_SIZE=0x1000 \ + $(USER_DEFINE) -T $(LINKER_SCRIPT) -o $(TESTNAME).o + # Generate disassembly code + $(GNU_OBJDUMP) -S $(TESTNAME).o > $(TESTNAME).lst + # Generate binary file + $(GNU_OBJCOPY) -S $(TESTNAME).o -O binary $(TESTNAME).bin + # Generate hex file + $(GNU_OBJCOPY) -S $(TESTNAME).o -O verilog $(TESTNAME).hex + +# Note: +# If the version of object copy you are using does not support verilog hex file output, +# you can generate the hex file from binary file using the following command +# od -v -A n -t x1 --width=1 $(TESTNAME).bin > $(TESTNAME).hex + + +# --------------------------------------------------------------------------------------- +# Keil MDK + +all_keil: + @echo "Please compile your project code and press ENTER when ready" + @read dummy + +# --------------------------------------------------------------------------------------- +# Binary + +all_bin: $(TESTNAME).bin + # Generate hex file from binary + od -v -A n -t x1 --width=1 $(TESTNAME).bin > $(TESTNAME).hex + +# --------------------------------------------------------------------------------------- +# Clean +clean : + @rm -rf *.o + @if [ -e $(TESTNAME).hex ] ; then \ + rm -rf $(TESTNAME).hex ; \ + fi + @if [ -e $(TESTNAME).lst ] ; then \ + rm -rf $(TESTNAME).lst ; \ + fi + @if [ -e $(TESTNAME).ELF ] ; then \ + rm -rf $(TESTNAME).ELF ; \ + fi + @if [ -e $(TESTNAME).bin ] ; then \ + rm -rf $(TESTNAME).bin ; \ + fi + @rm -rf *.crf + @rm -rf *.plg + @rm -rf *.tra + @rm -rf *.htm + @rm -rf *.map + @rm -rf *.dep + @rm -rf *.d + @rm -rf *.lnp + @rm -rf *.bak + @rm -rf *.lst + @rm -rf *.axf + @rm -rf *.sct + @rm -rf *.__i + @rm -rf *._ia diff --git a/wrapper/src/soclabs_ahb_aes128_ctrl.v b/wrapper/src/soclabs_ahb_aes128_ctrl.v new file mode 100644 index 0000000000000000000000000000000000000000..63b2bc31851807b3e5122ec4a1e9f2872d41a21c --- /dev/null +++ b/wrapper/src/soclabs_ahb_aes128_ctrl.v @@ -0,0 +1,583 @@ + //----------------------------------------------------------------------------- +// top-level soclabs example AHB interface +// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. +// +// Contributors +// +// David Flynn (d.w.flynn@soton.ac.uk) +// +// Copyright (C) 2023, SoC Labs (www.soclabs.org) +//----------------------------------------------------------------------------- + +module soclabs_ahb_aes128_ctrl( +// ------------------------------------------------------- +// MCU interface +// ------------------------------------------------------- + input wire ahb_hclk, // Clock + input wire ahb_hresetn, // Reset + input wire ahb_hsel, // Device select + input wire [15:0] ahb_haddr16, // Address for byte select + input wire [1:0] ahb_htrans, // Transfer control + input wire [2:0] ahb_hsize, // Transfer size + input wire [3:0] ahb_hprot, // Protection control + input wire ahb_hwrite, // Write control + input wire ahb_hready, // Transfer phase done + input wire [31:0] ahb_hwdata, // Write data + output wire ahb_hreadyout, // Device ready + output wire [31:0] ahb_hrdata, // Read data output + output wire ahb_hresp, // Device response +// stream data + output wire drq_ipdma128, // (to) DMAC input burst request + input wire dlast_ipdma128,// (from) DMAC input burst end (last transfer) + output wire drq_opdma128, // (to) DMAC output dma burst request + input wire dlast_opdma128,// (from) DMAC output burst end (last transfer) + output wire irq_key128, + output wire irq_ip128, + output wire irq_op128, + output wire irq_error, + output wire irq_merged // combined interrrupt request (to CPU) + ); + + //---------------------------------------------------------------- + // Internal parameter definitions. + //---------------------------------------------------------------- + +///typedef struct { +/// __I uint32_t CORE_NAME[2]; /* 0x0000-0007 */ +/// __I uint32_t CORE_VERSION; /* 0x0008-000B */ +/// uint32_t RESRV0C; /* 0x000C */ +/// __IO uint32_t CTRL; /* 0x0010 */ +/// __O uint32_t CTRL_SET; /* 0x0014 */ +/// __O uint32_t CTRLL_CLR; /* 0x0018 */ +/// __I uint32_t STATUS; /* 0x001c */ +/// __IO uint32_t QUAL; /* 0x0020 */ +/// uint32_t RESRV24[3]; /* 0x0024 - 2F*/ +/// __IO uint32_t DRQ_MSK; /* 0x0030 */ +/// __O uint32_t DRQ_MSK_SET; /* 0x0034 */ +/// __O uint32_t DRQ_MSK_CLR; /* 0x0038 */ +/// __I uint32_t DRQ_STATUS; /* 0x003C */ +/// __IO uint32_t IRQ_MSK; /* 0x0040 */ +/// __O uint32_t IRQ_MSK_SET; /* 0x0044 */ +/// __O uint32_t IRQ_MSK_CLR; /* 0x0048 */ +/// __I uint32_t IRQ_STATUS; /* 0x004C */ +/// uint32_t RESRV50[4076]; /* 0x0050-0x3FFC (4096-20 words) */ +/// __IO uint8_t KEY128[0x4000]; /* 0x4000-7FFF (0x3FFF is last alias) */ +/// __IO uint8_t TXTIP128[0x4000]; /* 0x8000-BFFF (0x3FFF is last alias) */ +/// __I uint8_t TXTOP128[0x4000]; /* 0xC000-FFFF (0x3FFF is last alias) */ +///} AES128_TypeDef; + + +// CORE ID + localparam ADDR_CORE_NAME0 = 16'h0000; + localparam ADDR_CORE_NAME1 = 16'h0004; + localparam ADDR_CORE_VERSION= 16'h0008; + localparam CORE_NAME0 = 32'h61657331; // "aes1" + localparam CORE_NAME1 = 32'h32382020; // "28 " + localparam CORE_VERSION = 32'h302e3031; // "0.01" + +// CTRL control register with bit-set/bit-clear options + localparam ADDR_CTRL = 16'h0010; + localparam ADDR_CTRL_SET = 16'h0014; + localparam ADDR_CTRL_CLR = 16'h0018; + localparam CTRL_REG_WIDTH = 8; + localparam CTRL_BIT_MAX = (CTRL_REG_WIDTH-1); + localparam CTRL_KEY_REQ_BIT = 0; + localparam CTRL_IP_REQ_BIT = 1; + localparam CTRL_OP_REQ_BIT = 2; + localparam CTRL_ERR_REQ_BIT = 3; + localparam CTRL_KEYOK_BIT = 4; + localparam CTRL_VALID_BIT = 5; + localparam CTRL_BYPASS_BIT = 6; + localparam CTRL_ENCODE_BIT = 7; +// STAT status regisyer + localparam ADDR_STAT = 16'h001c; + localparam STAT_REG_WIDTH = 8; + localparam STAT_BIT_MAX = (STAT_REG_WIDTH-1); + localparam STAT_KEYREQ_BIT = 0; + localparam STAT_INPREQ_BIT = 1; + localparam STAT_OUTREQ_BIT = 2; + localparam STAT_ERROR_BIT = 3; + localparam STAT_KEYOK_BIT = 4; + localparam STAT_VALID_BIT = 5; + +// QUAL qualifier field + localparam ADDR_QUAL = 16'h0020; + localparam QUAL_REG_WIDTH = 32; + localparam QUAL_BIT_MAX = (QUAL_REG_WIDTH-1); + +// DREQ DMAC request control with bit-set/bit-clear options + localparam ADDR_DREQ = 16'h0030; + localparam ADDR_DREQ_SET = 16'h0034; + localparam ADDR_DREQ_CLR = 16'h0038; + localparam ADDR_DREQ_ACT = 16'h003c; + localparam DREQ_REG_WIDTH = 3; + localparam DREQ_BIT_MAX = (DREQ_REG_WIDTH-1); + localparam REQ_KEYBUF_BIT = 0; + localparam REQ_IP_BUF_BIT = 1; + localparam REQ_OP_BUF_BIT = 2; + +// IREQ CPU interrupt request control with bit-set/bit-clear options + localparam ADDR_IREQ = 16'h0040; + localparam ADDR_IREQ_SET = 16'h0044; + localparam ADDR_IREQ_CLR = 16'h0048; + localparam ADDR_IREQ_ACT = 16'h004c; + localparam IREQ_REG_WIDTH = 4; + localparam IREQ_BIT_MAX = (IREQ_REG_WIDTH-1); + localparam REQ_ERROR_BIT = 3; + + localparam ADDR_KEY_BASE = 16'h4000; + localparam ADDR_KEY0 = 16'h4000; + localparam ADDR_KEY3 = 16'h400c; + localparam ADDR_KEY7 = 16'h401c; + + localparam ADDR_IBUF_BASE = 16'h8000; + localparam ADDR_IBUF_0 = 16'h8000; + localparam ADDR_IBUF_3 = 16'h800c; + + localparam ADDR_OBUF_BASE = 16'hc000; + localparam ADDR_OBUF_3 = 16'hc00c; + + + // -------------------------------------------------------------------------- + // Internal regs/wires + // -------------------------------------------------------------------------- + + reg [15:0] addr16_r; + reg sel_r; + reg wcyc_r; + reg rcyc_r; + reg [3:0] byte4_r; + + wire key128_load_ack; + wire ip128_load_ack; + wire op128_load_ack; + + // -------------------------------------------------------------------------- + // AHB slave byte buffer interface, support for unaligned data transfers + // -------------------------------------------------------------------------- + + wire [1:0] byt_adr = ahb_haddr16[1:0]; + // generate next byte enable decodes for Word/Half/Byte CPU/DMA accesses + wire [3:0] byte_nxt; + assign byte_nxt[0] = (ahb_hsize[1])|((ahb_hsize[0])&(!byt_adr[1]))|(byt_adr[1:0]==2'b00); + assign byte_nxt[1] = (ahb_hsize[1])|((ahb_hsize[0])&(!byt_adr[1]))|(byt_adr[1:0]==2'b01); + assign byte_nxt[2] = (ahb_hsize[1])|((ahb_hsize[0])&( byt_adr[1]))|(byt_adr[1:0]==2'b10); + assign byte_nxt[3] = (ahb_hsize[1])|((ahb_hsize[0])&( byt_adr[1]))|(byt_adr[1:0]==2'b11); + + // de-pipelined registered access signals + always @(posedge ahb_hclk or negedge ahb_hresetn) + if (!ahb_hresetn) + begin + addr16_r <= 16'h0000; + sel_r <= 1'b0; + wcyc_r <= 1'b0; + rcyc_r <= 1'b0; + byte4_r <= 4'b0000; + end else if (ahb_hready) + begin + addr16_r <= (ahb_hsel & ahb_htrans[1]) ? ahb_haddr16 : addr16_r; + sel_r <= (ahb_hsel & ahb_htrans[1]); + wcyc_r <= (ahb_hsel & ahb_htrans[1] & ahb_hwrite); + rcyc_r <= (ahb_hsel & ahb_htrans[1] & !ahb_hwrite); + byte4_r <= (ahb_hsel & ahb_htrans[1]) ? byte_nxt[3:0] : 4'b0000; + end + + +// pipelined "early" last access decodes, for PL230 dma_ack timing to deassert dma requests +// wire ahb128_last = ahb_hsel & ahb_htrans[1] & ahb_hready & ahb_haddr16[3] & ahb_haddr16[2] & byte_nxt[3]; +// wire ahb128_wlast = ahb_last & ahb_hwrite & |ahb_haddr[15:14]; // address phase of last write transfer +// wire ahb128_rlast = ahb_last & !ahb_hwrite & |ahb_haddr[15:14]; // address phase of last read transfer + + wire wlast128 = |ahb_haddr16[15:14] & addr16_r[3] & addr16_r[2] & byte4_r[3] & wcyc_r; // write last pulse + wire rlast128 = &ahb_haddr16[15:14] & addr16_r[3] & addr16_r[2] & byte4_r[3] & rcyc_r; // read last pulse + + //---------------------------------------------------------------- + // API register state and wiring + // + //---------------------------------------------------------------- + + reg [CTRL_BIT_MAX:0] control; + reg [QUAL_BIT_MAX:0] param; + reg [DREQ_BIT_MAX:0] drq_enable; + reg [IREQ_BIT_MAX:0] irq_enable; + + wire [STAT_BIT_MAX:0] status; + wire [DREQ_BIT_MAX:0] drq_active; + wire [IREQ_BIT_MAX:0] irq_active; + + wire [31:0] rd_keybuf; + wire [31:0] rd_ipbuf; + wire [31:0] rd_opbuf; + + //---------------------------------------------------------------- + // API write decoder + // + //---------------------------------------------------------------- + + wire sel_mode = sel_r & (addr16_r[15: 8] == 0); + wire sel_keybuf = sel_r & (addr16_r[15:14] == 1); + wire sel_ipbuf = sel_r & (addr16_r[15:14] == 2); + wire sel_opbuf = sel_r & (addr16_r[15:14] == 3); +// add address map "last" transfer signalling when last (byte) of alias map is written + wire alast_key128 = sel_keybuf & wcyc_r & (&addr16_r[13:2]) & byte4_r[3]; + wire alast_ip128 = sel_ipbuf & wcyc_r & (&addr16_r[13:2]) & byte4_r[3]; + wire alast_op128 = sel_opbuf & rcyc_r & (&addr16_r[13:2]) & byte4_r[3]; + + always @(posedge ahb_hclk or negedge ahb_hresetn) + if (!ahb_hresetn) begin + control <= {CTRL_REG_WIDTH{1'b0}}; + param <= {QUAL_REG_WIDTH{1'b0}}; + drq_enable <= {DREQ_REG_WIDTH{1'b0}}; + irq_enable <= {IREQ_REG_WIDTH{1'b0}}; + end + else if (sel_mode & wcyc_r & byte4_r[0]) + case ({addr16_r[15:2],2'b00}) + ADDR_CTRL : control <= ahb_hwdata[CTRL_BIT_MAX:0]; // overwrite ctl reg + ADDR_CTRL_SET: control <= ahb_hwdata[CTRL_BIT_MAX:0] | control; // bit set ctl mask pattern + ADDR_CTRL_CLR: control <= ~ahb_hwdata[CTRL_BIT_MAX:0] & control; // bit clear ctl mask pattern + ADDR_QUAL : param <= ahb_hwdata[QUAL_BIT_MAX:0]; // write qual pattern + ADDR_DREQ : drq_enable <= ahb_hwdata[DREQ_BIT_MAX:0]; // overwrite dreq reg + ADDR_DREQ_SET: drq_enable <= ahb_hwdata[DREQ_BIT_MAX:0] | drq_enable; // bit set dreq mask pattern + ADDR_DREQ_CLR: drq_enable <= ~ahb_hwdata[DREQ_BIT_MAX:0] & drq_enable; // bit clear dreq mask pattern + ADDR_IREQ : irq_enable <= ahb_hwdata[IREQ_BIT_MAX:0]; // overwrite ireq reg + ADDR_IREQ_SET: irq_enable <= ahb_hwdata[IREQ_BIT_MAX:0] | irq_enable; // bit set ireq mask pattern + ADDR_IREQ_CLR: irq_enable <= ~ahb_hwdata[IREQ_BIT_MAX:0] & irq_enable; // bit clear ireq mask pattern + default: ; + endcase + else if (sel_keybuf & wcyc_r & (dlast_ipdma128 | alast_key128)) // key terminate + drq_enable[0] <= 1'b0; + else if (sel_ipbuf & wcyc_r & (dlast_ipdma128 | alast_ip128)) // ip-buffer terminate + drq_enable[1] <= 1'b0; + else if (sel_opbuf & rcyc_r & (dlast_opdma128 | alast_op128)) // op-buffer complete + drq_enable[2] <= 1'b0; + + //---------------------------------------------------------------- + // API read decoder + // + //---------------------------------------------------------------- + +reg [31:0] rdata32; // mux read data + + always @* + begin : read_decoder + rdata32 = 32'hbad0bad; + if (sel_r & rcyc_r) + case ({addr16_r[15:2],2'b00}) + ADDR_CORE_NAME0 : rdata32 = CORE_NAME0; + ADDR_CORE_NAME1 : rdata32 = CORE_NAME1; + ADDR_CORE_VERSION : rdata32 = CORE_VERSION; + ADDR_CTRL : rdata32 = {{(32-CTRL_REG_WIDTH){1'b0}}, control}; + ADDR_STAT : rdata32 = {{(32-STAT_REG_WIDTH){1'b0}}, status}; + ADDR_QUAL : rdata32 = {{(32-QUAL_REG_WIDTH){1'b0}}, param}; + ADDR_DREQ : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, drq_enable}; + ADDR_DREQ_ACT : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, drq_active}; + ADDR_IREQ : rdata32 = {{(32-IREQ_REG_WIDTH){1'b0}}, irq_enable}; + ADDR_IREQ_ACT : rdata32 = {{(32-DREQ_REG_WIDTH){1'b0}}, irq_active}; + default: + if (sel_keybuf) rdata32 = rd_keybuf; + else if (sel_ipbuf) rdata32 = rd_ipbuf; + else if (sel_opbuf) rdata32 = rd_opbuf; + endcase + end // read_decoder + + assign ahb_hrdata = rdata32; + + assign ahb_hreadyout = 1'b1; // zero wait state interface + assign ahb_hresp = 1'b0; + + // -------------------------------------------------------------------------- + // Key Input Buffer - keybuf + // -------------------------------------------------------------------------- + + wire [127:0] key128_be; + + soclabs_iobuf_reg128 + #(.WRITE_ONLY (1), + .WRITE_ZPAD (0)) + u_reg128_key + ( + .clk (ahb_hclk ), // Clock + .rst_b (ahb_hresetn ), // Reset + .sel_r (sel_keybuf ), // Bank decode select + .wcyc_r (wcyc_r ), // Write cycle (wdata32 valid) + .rcyc_r (rcyc_r ), // Read cycle (return rdata32) + .word2_r (addr16_r[3:2] ), // Address for word select + .byte4_r (byte4_r[3:0] ), // Byte select decoded (up to 4 enabled) + .wdata32 (ahb_hwdata[31:0]), // Write data (byte lane qualified) + .rdata32 (rd_keybuf ), // Read data output + .dma128_ack (key128_load_ack ), // DMA burst acknowledge + .out128_le ( ), // Big-Endian 128-bit value + .out128_be (key128_be ) // Big-Endian 128-bit value + ); + + // -------------------------------------------------------------------------- + // Data Input Buffer - ipbuf + // -------------------------------------------------------------------------- + + wire [127:0] ip128_le; + wire [127:0] ip128_be; + + soclabs_iobuf_reg128 + #(.WRITE_ONLY (0), + .WRITE_ZPAD (1)) + u_reg128_ip + ( + .clk (ahb_hclk ), // Clock + .rst_b (ahb_hresetn ), // Reset + .sel_r (sel_ipbuf ), // Bank decode select + .wcyc_r (wcyc_r ), // Write cycle (wdata32 valid) + .rcyc_r (rcyc_r ), // Read cycle (return rdata32) + .word2_r (addr16_r[3:2] ), // Address for word select + .byte4_r (byte4_r[3:0] ), // Byte select decoded (up to 4 enabled) + .wdata32 (ahb_hwdata[31:0]), // Write data (byte lane qualified) + .rdata32 (rd_ipbuf ), // Read data output + .dma128_ack (ip128_load_ack ), // DMA burst acknowledge + .out128_le (ip128_le ), // Big-Endian 128-bit value + .out128_be (ip128_be ) // Big-Endian 128-bit value + ); + + // -------------------------------------------------------------------------- + // Data Output Buffer - opbufsel_keybuf + // -------------------------------------------------------------------------- + + wire [127:0] op128_be; + wire [127:0] op128_muxed = (control[CTRL_BYPASS_BIT]) ? ip128_be : op128_be; + + wire [31:0] op_slice32 [0:3]; + assign op_slice32[3] = {op128_muxed[ 7: 0],op128_muxed[ 15: 8],op128_muxed[ 23: 16],op128_muxed[ 31: 24]}; + assign op_slice32[2] = {op128_muxed[ 39: 32],op128_muxed[ 47: 40],op128_muxed[ 55: 48],op128_muxed[ 63: 56]}; + assign op_slice32[1] = {op128_muxed[ 71: 64],op128_muxed[ 79: 72],op128_muxed[ 87: 80],op128_muxed[ 95: 88]}; + assign op_slice32[0] = {op128_muxed[103: 96],op128_muxed[111:104],op128_muxed[119:112],op128_muxed[127:120]}; + + // 32-bit addressed read data + assign rd_opbuf = op_slice32[addr16_r[3:2]]; + + assign op128_load_ack = (sel_opbuf & rcyc_r & addr16_r[3] & addr16_r[2] & byte4_r[3]); + + // -------------------------------------------------------------------------- + // example aes128 engine timing + // -------------------------------------------------------------------------- + // -------------------------------------------------------------------------- + // AES-specific control interface + // -------------------------------------------------------------------------- + +wire aes128_encode = control[CTRL_ENCODE_BIT]; +wire aes256_keysize = 1'b0; + +wire aes_keyloaded_pulse = key128_load_ack; // pulse on last byte load of key128 +wire aes_dataloaded_pulse= ip128_load_ack; // pulse on last byte load of text128 +wire aes_ready; +wire aes_valid; + +// state machine control +reg aes_ready_del; +reg aes_init; +reg aes_next; +reg aes_key_busy; +reg aes_key_rdy; +reg aes_res_busy; +reg aes_res_rdy; +reg aes_err; + + always @(posedge ahb_hclk or negedge ahb_hresetn) + if (!ahb_hresetn) begin + aes_ready_del <= 1'b0; + aes_init <= 1'b0; + aes_next <= 1'b0; + aes_key_busy <= 1'b0; + aes_key_rdy <= 1'b0; + aes_res_busy <= 1'b0; + aes_res_rdy <= 1'b0; + aes_err <= 1'b0; + end else begin + aes_ready_del <= aes_ready; // delay for rising edge detect + aes_init <= aes_keyloaded_pulse; + aes_next <= aes_dataloaded_pulse; + aes_key_busy <= (aes_init) | (aes_key_busy & !(aes_ready & !aes_ready_del)); // hold until key expansion done + aes_key_rdy <= (aes_key_busy & aes_ready & !aes_ready_del) // expanded key ready + | (aes_key_rdy & !(sel_keybuf & wcyc_r)); // hold until any key update + aes_res_busy <= (aes_next) | (aes_res_busy & !(aes_ready & !aes_ready_del)); // hold until block processing done + aes_res_rdy <= (aes_res_busy & aes_ready & !aes_ready_del) // block ready + | (aes_res_rdy & !op128_load_ack); // hold until output transferred + aes_err <= (!aes_key_rdy & ((sel_ipbuf & wcyc_r) | (sel_opbuf & rcyc_r))) + | (aes_err & !(sel_keybuf & wcyc_r)); + end + + assign drq_active[REQ_KEYBUF_BIT] = control[CTRL_KEY_REQ_BIT] & (!aes_keyloaded_pulse & !aes_init & !aes_key_busy & !aes_key_rdy); + assign drq_active[REQ_IP_BUF_BIT] = control[CTRL_IP_REQ_BIT] & (!aes_dataloaded_pulse & !aes_next & !aes_res_busy & !aes_res_rdy & aes_key_rdy); + assign drq_active[REQ_OP_BUF_BIT] = control[CTRL_OP_REQ_BIT] & (!aes_res_busy & aes_res_rdy); + +// input DMA channel shared by Key and Data-In + assign drq_ipdma128 = (drq_enable[REQ_KEYBUF_BIT] & drq_active[REQ_KEYBUF_BIT] & !wlast128) // if key DMA enabled + | (drq_enable[REQ_IP_BUF_BIT] & drq_active[REQ_IP_BUF_BIT] & !wlast128) // if ip128 DMA requested + ; + +// output DMA channel for Data-Out + assign drq_opdma128 = (drq_enable[REQ_OP_BUF_BIT] & drq_active[REQ_OP_BUF_BIT] & !rlast128); // if op128 DMA requested + +// and Interrupt requests are masked out if corresponding DMA requests are enabled + assign irq_active[REQ_KEYBUF_BIT] = drq_active[REQ_KEYBUF_BIT] & !drq_enable[REQ_KEYBUF_BIT]; + assign irq_active[REQ_IP_BUF_BIT] = drq_active[REQ_IP_BUF_BIT] & !drq_enable[REQ_IP_BUF_BIT]; + assign irq_active[REQ_OP_BUF_BIT] = drq_active[REQ_OP_BUF_BIT] & !drq_enable[REQ_OP_BUF_BIT]; + assign irq_active[REQ_ERROR_BIT ] = control[CTRL_ERR_REQ_BIT] & aes_err; // error raised in SW + + assign irq_key128 = irq_active[REQ_KEYBUF_BIT] & irq_enable[REQ_KEYBUF_BIT]; + assign irq_ip128 = irq_active[REQ_IP_BUF_BIT] & irq_enable[REQ_IP_BUF_BIT]; + assign irq_op128 = irq_active[REQ_OP_BUF_BIT] & irq_enable[REQ_OP_BUF_BIT]; + assign irq_error = irq_active[REQ_ERROR_BIT ] & irq_enable[REQ_ERROR_BIT ]; +// merge and mask if not DRQ + assign irq_merged = irq_key128 | irq_ip128 | irq_op128 | irq_error; + + +// wire up status port + assign status[2:0] = control [2:0]; + assign status[STAT_ERROR_BIT] = (!aes_res_busy & !aes_key_rdy); + assign status[STAT_KEYOK_BIT] = aes_key_rdy; + assign status[STAT_VALID_BIT] = aes_res_rdy; + assign status[7:6] = control [7:6]; + + //---------------------------------------------------------------- + // core instantiation. + //---------------------------------------------------------------- + aes_core core( + .clk(ahb_hclk), + .reset_n(ahb_hresetn), + + .encdec(aes128_encode), + .init(aes_init), + .next(aes_next), + .ready(aes_ready), + + .key({key128_be,key128_be}), + .keylen(aes256_keysize), + + .block(ip128_be), + .result(op128_be), + .result_valid(aes_valid) + ); + +endmodule + +module soclabs_iobuf_reg128 + #( + parameter WRITE_ONLY = 0, + parameter WRITE_ZPAD = 0 + ) ( +// ------------------------------------------------------- +// de-pipelined register interface +// ------------------------------------------------------- +// ahb + input wire clk, // Clock + input wire rst_b, // Reset + input wire sel_r, // Bank decode select + input wire wcyc_r, // Write cycle (wdata32 valid) + input wire rcyc_r, // Read cycle (return rdata32) + input wire [1:0] word2_r, // Address for word select + input wire [3:0] byte4_r, // Byte select decoded (up to 4 enabled) + input wire [31:0] wdata32, // Write data (byte lae qualified) + output wire [31:0] rdata32, // Read data output + output wire dma128_ack, // DMA burst acknowledge + output wire [127:0] out128_le, // Litte-Endian 128-bit value + output wire [127:0] out128_be // Big-Endian 128-bit value +) ; + + reg [7:0] byte0 [0:3]; + reg [7:0] byte1 [0:3]; + reg [7:0] byte2 [0:3]; + reg [7:0] byte3 [0:3]; + reg ack128; + + wire zpad_cfg = (WRITE_ZPAD==0) ? 1'b0 : 1'b1; + +// byte-0 array; flush on write to word-0, byte-0 +// else addressed word byte-0 write + always @(posedge clk or negedge rst_b) + if (!rst_b) + begin byte0[0] <= 8'h00; byte0[1] <= 8'h00; byte0[2] <= 8'h00; byte0[3] <= 8'h00; end + else if (zpad_cfg & sel_r & wcyc_r & byte4_r[0] & !word2_r[1] & !word2_r[0]) // Z-PAD rest + begin byte0[0] <= wdata32[ 7: 0]; byte0[1] <= 8'h00; byte0[2] <= 8'h00; byte0[3] <= 8'h00; end + else if (sel_r & wcyc_r & byte4_r[0]) + byte0[word2_r[1:0]] <= wdata32[ 7: 0]; + +// byte-1 array; flush on write to word-0, byte-0 if byte-1 not also written +// flush rest on write to word-0, byte-0 and byte-1 also written +// else address word byte-1 write + always @(posedge clk or negedge rst_b) + if (!rst_b) + begin byte1[0] <= 8'h00; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end + else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[1] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD + begin byte1[0] <= 8'h00; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end + else if (zpad_cfg & sel_r & wcyc_r & byte4_r[1] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest + begin byte1[0] <= wdata32[15: 8]; byte1[1] <= 8'h00; byte1[2] <= 8'h00; byte1[3] <= 8'h00; end + else if (sel_r & wcyc_r & byte4_r[1]) + byte1[word2_r[1:0]] <= wdata32[15: 8]; + +// byte-2 array; flush on write to word-0, byte-0 if byte-2 not also written +// flush rest on write to word-0, byte-0 and byte-2 also written +// else address word byte-2 write + always @(posedge clk or negedge rst_b) + if (!rst_b) + begin byte2[0] <= 8'h00; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end + else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[2] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD + begin byte2[0] <= 8'h00; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end + else if (zpad_cfg & sel_r & wcyc_r & byte4_r[2] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest + begin byte2[0] <= wdata32[23:16]; byte2[1] <= 8'h00; byte2[2] <= 8'h00; byte2[3] <= 8'h00; end + else if (sel_r & wcyc_r & byte4_r[2]) + byte2[word2_r[1:0]] <= wdata32[23:16]; + +// byte-3 array; flush on write to word-0, byte-0 if byte-3 not also written +// flush rest on write to word-0, byte-0 and byte-3 also written +// else address word byte-3 write + always @(posedge clk or negedge rst_b) + if (!rst_b) + begin byte3[0] <= 8'h00; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end + else if (zpad_cfg & sel_r & wcyc_r & !byte4_r[3] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD + begin byte3[0] <= 8'h00; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end + else if (zpad_cfg & sel_r & wcyc_r & byte4_r[3] & !word2_r[1] & !word2_r[0] & byte4_r[0]) // Z-PAD rest + begin byte3[0] <= wdata32[31:24]; byte3[1] <= 8'h00; byte3[2] <= 8'h00; byte3[3] <= 8'h00; end + else if (sel_r & wcyc_r & byte4_r[3]) + byte3[word2_r[1:0]] <= wdata32[31:24]; + + // ack on write to final byte [15] + always @(posedge clk or negedge rst_b) + if (!rst_b) + ack128 <= 1'b0; + else + ack128 <= sel_r & wcyc_r & word2_r[1] & word2_r[0] & byte4_r[3]; + + assign dma128_ack = ack128; + +// byte reverse per word for Big Endian AES engine + assign out128_be = {byte0[0], byte1[0], byte2[0], byte3[0], + byte0[1], byte1[1], byte2[1], byte3[1], + byte0[2], byte1[2], byte2[2], byte3[2], + byte0[3], byte1[3], byte2[3], byte3[3]}; + +// byte reverse per word for Big Endian AES engine + assign out128_le = {byte3[3], byte2[3], byte1[3], byte0[3], + byte3[2], byte2[2], byte1[2], byte0[2], + byte3[1], byte2[1], byte1[1], byte0[1], + byte3[0], byte2[0], byte1[0], byte0[0]}; + +// little-endian read data (if not Write-Only) + assign rdata32 = (sel_r & rcyc_r & (WRITE_ONLY == 0)) + ? {byte3[word2_r[1:0]], byte2[word2_r[1:0]], + byte1[word2_r[1:0]], byte0[word2_r[1:0]]} + : 32'h00000000; + +endmodule + +// include SecWorks IP but fix up default_nettype issues that breaks elsewhere + +`include "aes_core.v" +`default_nettype wire +`include "aes_encipher_block.v" +`default_nettype wire +`include "aes_decipher_block.v" +`default_nettype wire +`include "aes_key_mem.v" +`default_nettype wire +`include "aes_sbox.v" +`default_nettype wire +`include "aes_inv_sbox.v" +`default_nettype wire