sdk-hwV1.3/lichee/xr806/appos/project/common/cmd/cmd_flashc_crypto.c

1583 lines
46 KiB
C
Executable File

/*
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "image/flash.h"
#include "cmd_debug.h"
#include "cmd_util.h"
#include "driver/chip/hal_flash.h"
#include "driver/chip/psram/hal_psramctrl.h"
#include "driver/chip/hal_dcache.h"
#include "sys/io.h"
#include "sys/sys_heap.h"
#if ((CONFIG_CHIP_ARCH_VER == 3) && defined(CONFIG_FLASH_CRYPTO))
#ifdef CONFIG_TRUSTZONE
#include "trustzone/nsc_table.h"
#include "trustzone/tz_rpc.h"
#endif
/*
* Flash Crypto disable interface take effect option for test. If the flash
* crypto disable interface is avaliable, configure this macro to 1; Otherwise
* configure the macro is 0.
*/
#define FLASH_CRYPTO_DISABLE_CAN_USE 1
typedef struct {
uint32_t crypto_type;
uint32_t crypto_addr;
uint32_t crypto_length;
int32_t crypto_channel;
OS_Thread_t thread;
OS_Semaphore_t sem;
OS_Queue_t queue;
uint32_t test_times;
} cmd_fc_t;
static cmd_fc_t g_fc_info;
#define MFLASH 0
static uint8_t flash_enc_nonce[6] = {0x50, 0x00, 0x06, 0x20, 0x00, 0x00};
// The number of columns comprising a state in AES. This is a constant in AES.
// Value=4
#define Nb 4
// The number of rounds in AES Cipher. It is simply initiated to zero. The
// actual value is recieved in the program.
int Nr;
// The number of 32 bit words in the key. It is simply initiated to zero. The
// actual value is recieved in the program.
int Nk;
// in - it is the array that holds the plain text to be encrypted.
// out - it is the array that holds the key for encryption.
// state - the array that holds the intermediate results during encryption.
//unsigned char in[16], out[16], state[4][4];
unsigned char state[4][4];
// The array that stores the round keys.
unsigned char RoundKey[240];
// The Key input to the AES Program
//unsigned char Key[32];
static const int rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
static const int sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 //F
};
int getSBoxValue(int num)
{
return sbox[num];
}
int getSBoxInvert(int num)
{
return rsbox[num];
}
// The round constant word array, Rcon[i], contains the values given by
// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(28)
// Note that i starts at 1, not 0).
static const int Rcon[255] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb
};
// This function produces Nb(Nr+1) round keys. The round keys are used in each
// round to encrypt the states.
void KeyExpansion(unsigned char *Key)
{
int i, j;
unsigned char temp[4], k;
// The first round key is the key itself.
for (i = 0; i < Nk; i++) {
RoundKey[i * 4] = Key[i * 4];
RoundKey[i * 4 + 1] = Key[i * 4 + 1];
RoundKey[i * 4 + 2] = Key[i * 4 + 2];
RoundKey[i * 4 + 3] = Key[i * 4 + 3];
}
// All other round keys are found from the previous round keys.
while (i < (Nb * (Nr + 1))) {
for (j = 0; j < 4; j++) {
temp[j] = RoundKey[(i - 1) * 4 + j];
}
if (i % Nk == 0) {
// This function rotates the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
{
k = temp[0];
temp[0] = temp[1];
temp[1] = temp[2];
temp[2] = temp[3];
temp[3] = k;
}
// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.
// Function Subword()
{
temp[0] = getSBoxValue(temp[0]);
temp[1] = getSBoxValue(temp[1]);
temp[2] = getSBoxValue(temp[2]);
temp[3] = getSBoxValue(temp[3]);
}
temp[0] = temp[0] ^ Rcon[i/Nk];
} else if (Nk > 6 && i % Nk == 4) {
// Function Subword()
{
temp[0] = getSBoxValue(temp[0]);
temp[1] = getSBoxValue(temp[1]);
temp[2] = getSBoxValue(temp[2]);
temp[3] = getSBoxValue(temp[3]);
}
}
RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ temp[0];
RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ temp[1];
RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ temp[2];
RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ temp[3];
i++;
}
}
// This function adds the round key to state.
// The round key is added to the state by an XOR function.
void AddRoundKey(int round)
{
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
state[j][i] ^= RoundKey[round * Nb * 4 + i * Nb + j];
}
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
void SubBytes(void)
{
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
state[i][j] = getSBoxValue(state[i][j]);
}
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
void InvSubBytes(void)
{
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
state[i][j] = getSBoxInvert(state[i][j]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
void ShiftRows(void)
{
unsigned char temp;
// Rotate first row 1 columns to left
temp = state[1][0];
state[1][0] = state[1][1];
state[1][1] = state[1][2];
state[1][2] = state[1][3];
state[1][3] = temp;
// Rotate second row 2 columns to left
temp = state[2][0];
state[2][0] = state[2][2];
state[2][2] = temp;
temp = state[2][1];
state[2][1] = state[2][3];
state[2][3] = temp;
// Rotate third row 3 columns to left
temp = state[3][0];
state[3][0] = state[3][3];
state[3][3] = state[3][2];
state[3][2] = state[3][1];
state[3][1] = temp;
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
void InvShiftRows(void)
{
unsigned char temp;
// Rotate first row 1 columns to right
temp = state[1][3];
state[1][3] = state[1][2];
state[1][2] = state[1][1];
state[1][1] = state[1][0];
state[1][0] = temp;
// Rotate second row 2 columns to right
temp = state[2][0];
state[2][0] = state[2][2];
state[2][2] = temp;
temp = state[2][1];
state[2][1] = state[2][3];
state[2][3] = temp;
// Rotate third row 3 columns to right
temp = state[3][0];
state[3][0] = state[3][1];
state[3][1] = state[3][2];
state[3][2] = state[3][3];
state[3][3] = temp;
}
// xtime is a macro that finds the product of {02} and the argument to xtime
// modulo {1b}
#define xtime(x) ((x << 1) ^ (((x >> 7) & 1) * 0x1b))
// Multiplty is a macro used to multiply numbers in the field GF(2^8)
#define Multiply(x, y) ( \
((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) \
^ ((y>>2 & 1) * xtime(xtime(x))) \
^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) \
^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))) \
)
// MixColumns function mixes the columns of the state matrix
void MixColumns(void)
{
int i;
unsigned char Tmp, Tm, t;
for (i = 0; i < 4; i++) {
t = state[0][i];
Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i];
Tm = state[0][i] ^ state[1][i] ; Tm = xtime(Tm); state[0][i] ^= Tm ^ Tmp;
Tm = state[1][i] ^ state[2][i] ; Tm = xtime(Tm); state[1][i] ^= Tm ^ Tmp;
Tm = state[2][i] ^ state[3][i] ; Tm = xtime(Tm); state[2][i] ^= Tm ^ Tmp;
Tm = state[3][i] ^ t ; Tm = xtime(Tm); state[3][i] ^= Tm ^ Tmp;
}
}
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the
// inexperienced. Please use the references to gain more information.
void InvMixColumns(void)
{
int i;
unsigned char a, b, c, d;
for (i = 0; i < 4; i++) {
a = state[0][i];
b = state[1][i];
c = state[2][i];
d = state[3][i];
state[0][i] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d)
^ Multiply(d, 0x09);
state[1][i] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b)
^ Multiply(d, 0x0d);
state[2][i] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e)
^ Multiply(d, 0x0b);
state[3][i] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09)
^ Multiply(d, 0x0e);
}
}
// Cipher is the main function that encrypts the PlainText.
void Cipher(unsigned char *in, unsigned char *out)
{
int i, j, round = 0;
//Copy the input PlainText to state array.
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
state[j][i] = in[i * 4 + j];
}
}
// Add the First round key to the state before starting the rounds.
AddRoundKey(0);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr-1 rounds are executed in the loop below.
for (round = 1; round < Nr; round++) {
SubBytes();
ShiftRows();
MixColumns();
AddRoundKey(round);
}
// The last round is given below.
// The MixColumns function is not here in the last round.
SubBytes();
ShiftRows();
AddRoundKey(Nr);
// The encryption process is over.
// Copy the state array to output array.
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
out[i * 4 + j] = state[j][i];
}
}
}
// InvCipher is the main function that decrypts the CipherText.
void InvCipher(unsigned char *in, unsigned char *out)
{
int i, j, round = 0;
//Copy the input CipherText to state array.
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
state[j][i] = in[i * 4 + j];
}
}
// Add the First round key to the state before starting the rounds.
AddRoundKey(Nr);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr-1 rounds are executed in the loop below.
for (round = Nr - 1; round > 0; round--) {
InvShiftRows();
InvSubBytes();
AddRoundKey(round);
InvMixColumns();
}
// The last round is given below.
// The MixColumns function is not here in the last round.
InvShiftRows();
InvSubBytes();
AddRoundKey(0);
// The decryption process is over.
// Copy the state array to output array.
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
out[i * 4 + j] = state[j][i];
}
}
}
#if FLASH_CRYPTO_DISABLE_CAN_USE
static void soft_aes_enc(unsigned char *key, int key_size,
unsigned char *in_buf, unsigned char *out_buf,
unsigned long text_size, unsigned char *iv_buf)
{
unsigned long i, k;
unsigned char in[16], out[16];
Nk = key_size / 32;
Nr = Nk + 6;
KeyExpansion(key);
for (k = 0; k < 16; k++)
in[k] = iv_buf[k];
for (i = 0; i < text_size / 16; i++) {
Cipher(in, out);
for (k = 0; k < 16; k++) {
out_buf[i * 16 + k] = in_buf[i * 16 + k] ^ out[k];
in[k] = out[k];
}
}
}
static void soft_flash_enc(uint8_t *nonce, uint8_t *key, uint32_t faddr,
uint32_t len, uint8_t *in, uint8_t *out)
{
uint8_t iv[16];
uint32_t i, ahb_addr;
uint32_t block_num = len >> 4;
memset(iv, 0, sizeof(iv));
for (i = 0; i < block_num; i++) {
ahb_addr = faddr + (i << 4);
iv[0] = nonce[1];
iv[1] = nonce[0];
iv[2] = nonce[5];
iv[3] = nonce[4];
iv[4] = nonce[3];
iv[5] = nonce[2];
iv[6] = ahb_addr >> 24;
iv[7] = ahb_addr >> 16;
iv[8] = ahb_addr >> 8;
iv[9] = (nonce[4] >> 4) | (ahb_addr & 0xF0);
iv[10] = ((nonce[4] << 4) & 0xF0) | (nonce[3] >> 4);
iv[11] = ((nonce[3] << 4) & 0xF0) | (nonce[2] >> 4);
iv[12] = ((nonce[2] << 4) & 0xF0) | (ahb_addr >> 28);
iv[13] = ahb_addr >> 20;
iv[14] = ahb_addr >> 12;
iv[15] = ahb_addr >> 4;
reversed_order(iv, sizeof(iv));
soft_aes_enc(key, 128, (uint8_t *)((uint32_t)in + (i << 4)),
(uint8_t *)((uint32_t)out + (i << 4)), 16, iv);
}
}
#endif
/*
* cmd_flash_crypto_bench_exec1
* drv flashcrypto flash_bench m=0 l=1024
* drv flashcrypto flash_bench <m=0/1> <l=size>
* m: 0:flash write/read, 1:flash crypto write/read
*/
static enum cmd_status cmd_flash_crypto_bench_exec(char *cmd)
{
int32_t err;
uint32_t throuth_mb, throuth_kb;
OS_Time_t tick_usew, tick_user, tick_startw, tick_startr;
int32_t cnt;
uint8_t *src = NULL;
uint32_t addr = 0x180000;
uint32_t mode, size, bench_size;
#if FLASH_CRYPTO_DISABLE_CAN_USE
uint8_t key[16] = {0x15, 0x22, 0x67, 0x55, 0x1a, 0x3b, 0x5c, 0x34, 0x79,
0x7f, 0x11, 0x35, 0xbd, 0xf4, 0x88, 0x3b};
#endif
cnt = cmd_sscanf(cmd, "m=%u l=%u", &mode, &size);
if (cnt != 2) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_FAIL;
}
#if !FLASH_CRYPTO_DISABLE_CAN_USE
if (mode == 1) {
CMD_ERR("flash crypto disable function is disable, can't test crypto"
" read/write!\n");
return CMD_STATUS_FAIL;
}
#endif
src = cmd_malloc(size);
if (src == NULL) {
CMD_ERR("no memory\n");
return CMD_STATUS_FAIL;
}
if (mode == 1)
HAL_FlashCrypto_Init(flash_enc_nonce);
if (HAL_Flash_Open(MFLASH, 5000) != HAL_OK) {
CMD_ERR("flash driver open failed\n");
return CMD_STATUS_FAIL;
}
/* write normal function test */
for (int src_temp = 0; src_temp < size / 4; src_temp++)
src[src_temp] = src_temp;
#if 1
if (HAL_Flash_Overwrite(MFLASH, addr, src, size) != HAL_OK) {
CMD_ERR("flash write failed !\n");
}
#else
if (flash_erase(MFLASH, addr, 0x8000)) {
CMD_ERR("Flash Erase failure !\n");
}
if (HAL_Flash_Write(MFLASH, addr, src, size)) {
CMD_ERR("flash write failed\n");
}
#endif
if (HAL_Flash_Check(MFLASH, addr, src, size) != 0) {
CMD_ERR("flash write not success !\n");
}
cmd_free(src);
src = NULL;
for (int i = 0; i < 1000; i++) {
int j;
bench_size = size * (1 << i);
uint8_t *buf = cmd_malloc(bench_size);
if (!buf) {
CMD_ERR("test end for malloc buff failed!\n");
CMD_DBG("%s test end\n", __func__);
goto out;
}
for (j = 0; j < bench_size; j++) {
buf[j] = (j & 0xff);
}
tick_startw = OS_GetTicks();
if (mode == 0) {
#if 1
err = HAL_Flash_Overwrite(MFLASH, addr, buf, bench_size);
#else
if (flash_erase(MFLASH, addr, 0x8000)) {
CMD_ERR("Flash Erase failure !\n");
err = -1;
}
if (HAL_Flash_Write(MFLASH, addr, buf, bench_size)) {
CMD_ERR("flash write failed\n");
err = -1;
}
#endif
} else if (mode == 1) {
#if FLASH_CRYPTO_DISABLE_CAN_USE
#if 0
err = HAL_Flash_Overwrite_Crypto(MFLASH, addr, buf, bench_size, key);
#else
if (flash_erase(MFLASH, addr, 0x8000)) {
CMD_ERR("Flash Erase failure !\n");
err = -1;
}
if (flash_write_crypto(MFLASH, addr, src, size, key) != size) {
CMD_ERR("flash write failed\n");
err = -1;
}
#endif
#endif
}
tick_usew = OS_GetTicks() - tick_startw;
if (!tick_usew)
tick_usew = 1;
if (err) {
CMD_ERR("flash write err!\n");
goto next;
} else {
throuth_kb = bench_size * 1000 / 1024
/ (uint32_t)OS_TicksToMSecs(tick_usew);
throuth_mb = throuth_kb / 1000;
CMD_DBG("%s flash write ok, ", __func__);
CMD_LOG(CMD_DBG_ON, "%3d", bench_size/1024);
CMD_LOG(CMD_DBG_ON, " KB use:%3d ms, throughput:%d.%d MB/S\n",
(uint32_t)OS_TicksToMSecs(tick_usew),
throuth_mb, throuth_kb - throuth_mb);
}
for (j = 0; j < bench_size; j++)
buf[j] = 0;
tick_startr = OS_GetTicks();
if (mode == 0) {
err = HAL_Flash_Read(MFLASH, addr, buf, bench_size);
} else if (mode == 1) {
#if FLASH_CRYPTO_DISABLE_CAN_USE
if (flash_read_crypto(MFLASH, addr, buf, bench_size, key) != bench_size) {
err = 1;
}
#endif
}
tick_user = OS_GetTicks() - tick_startr;
if (!tick_user)
tick_user = 1;
if (err) {
CMD_ERR("flash read err!\n");
goto next;
}
err = 0;
for (j = 0; j < bench_size; j++) {
if (buf[j] != (j & 0xff)) {
err = -1;
break;
}
}
if (err) {
CMD_ERR("bench_size:%d write data err:0x%x should:0x%x, idx:%d!\n",
bench_size, buf[j], (j & 0xff), j);
print_hex_dump_words((const void *)&buf[j], 256);
goto next;
}
throuth_kb = bench_size * 1000 / 1024 / (uint32_t)OS_TicksToMSecs(tick_user);
throuth_mb = throuth_kb / 1000;
CMD_DBG("%s flash read ok, ", __func__);
CMD_LOG(CMD_DBG_ON, "%3d", bench_size/1024);
CMD_LOG(CMD_DBG_ON, " KB use:%3d ms, throughput:%d.%d MB/S\n",
(uint32_t)OS_TicksToMSecs(tick_user),
throuth_mb, throuth_kb - throuth_mb);
goto next;
next:
cmd_free(buf);
buf = NULL;
OS_MSleep(10);
if (err)
break;
}
out:
if (HAL_Flash_Close(MFLASH) != HAL_OK) {
CMD_ERR("flash driver close failed\n");
}
return CMD_STATUS_OK;
}
#if FLASH_CRYPTO_DISABLE_CAN_USE
static enum cmd_status cmd_flash_crypto_exec(char *cmd)
{
int32_t cnt;
uint32_t ret = CMD_STATUS_FAIL, i;
uint8_t *src, *soft_result, *ahb_result;
uint32_t addr = 0x180000;
uint32_t size = 0x400;
uint8_t key[16] = {0x15, 0x22, 0x67, 0x55, 0x1a, 0x3b, 0x5c, 0x34, 0x79,
0x7f, 0x11, 0x35, 0xbd, 0xf4, 0x88, 0x3b};
uint8_t data_fill[4] = {0xa1, 0xb2, 0xc3, 0xd4};
cnt = cmd_sscanf(cmd, "l=0x%x", &size);
if (cnt != 1) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_INVALID_ARG;
}
src = cmd_malloc(size);
if (src == NULL) {
CMD_ERR("no memory\n");
cmd_free(src);
return ret;
}
soft_result = cmd_malloc(size);
if (soft_result == NULL) {
CMD_ERR("no memory\n");
cmd_free(soft_result);
return ret;
}
ahb_result = cmd_malloc(size);
if (ahb_result == NULL) {
CMD_ERR("no memory\n");
cmd_free(ahb_result);
return ret;
}
HAL_FlashCrypto_Init(flash_enc_nonce);
if (HAL_Flash_Open(MFLASH, 5000) != HAL_OK) {
CMD_ERR("flash driver open failed\n");
return CMD_STATUS_FAIL;
}
/* write normal function test */
if (HAL_Flash_Overwrite(MFLASH, addr, src, size) != HAL_OK) {
CMD_ERR("flash write failed !\n");
}
if (HAL_Flash_Check(MFLASH, addr, src, size) != 0) {
CMD_ERR("flash write not success !\n");
}
for (i = 0; i < 1; i++) {
cmd_memset(src, data_fill[i], size);
#if 1
if (flash_erase(MFLASH, addr, 0x1000)) {
CMD_ERR("Flash Erase failure !\n");
goto error_exit;
}
if (flash_write_crypto(MFLASH, addr, src, size, key) != size) {
CMD_ERR("flash read failed\n");
goto error_exit;
}
#else
if (HAL_Flash_Overwrite_Crypto(MFLASH, addr, src, size, key) != HAL_OK) {
CMD_ERR("flash write failed !\n");
}
#endif
if (flash_read_crypto(MFLASH, addr, ahb_result, size, key) != size) {
CMD_ERR("flash read failed\n");
goto error_exit;
}
if (cmd_memcmp(src, ahb_result, size)) {
CMD_ERR("flash decrypt test error !\n");
CMD_DBG("the source data :\n");
print_hex_dump_bytes(src, size);
CMD_DBG("HW decrypt result :\n");
print_hex_dump_bytes(ahb_result, size);
goto error_exit;
}
soft_flash_enc(flash_enc_nonce, key, addr, size, src, soft_result);
cmd_memset(ahb_result, 0x0, size);
if (flash_read(MFLASH, addr, ahb_result, size) != size) {
CMD_ERR("flash read failed\n");
goto error_exit;
}
if (cmd_memcmp(soft_result, ahb_result, size)) {
CMD_ERR("flash encrypt test error !\n");
CMD_DBG("SW encrypt result :\n");
print_hex_dump_bytes(soft_result, size);
CMD_DBG("HW encrypt result :\n");
print_hex_dump_bytes(ahb_result, size);
goto error_exit;
}
}
CMD_LOG(1, "flash crypto test successful !\n");
ret = CMD_STATUS_OK;
error_exit:
if (HAL_Flash_Close(MFLASH) != HAL_OK) {
CMD_ERR("flash driver close failed\n");
return CMD_STATUS_FAIL;
}
cmd_free(src);
cmd_free(soft_result);
cmd_free(ahb_result);
return ret;
}
#endif
#if (defined(CONFIG_PSRAM))
static enum cmd_status cmd_psram_crypto_exec(char *cmd)
{
int32_t cnt;
uint32_t ret = CMD_STATUS_FAIL, i, mode_cpu_ndma;
uint8_t *src = NULL, *soft_result = NULL;
uint8_t *ahb_result = NULL, *psram_buf = NULL;
uint32_t size = 0x400;
uint8_t key[16] = {0x15, 0x22, 0x67, 0x55, 0x1a, 0x3b, 0x5c, 0x34, 0x79,
0x7f, 0x11, 0x35, 0xbd, 0xf4, 0x88, 0x3b};
uint8_t data_fill[4] = {0xa1, 0xb2, 0xc3, 0xd4};
DMA_ChannelInitParam dmaParam;
DMA_Channel dma_ch;
OS_Semaphore_t *dma_sem;
cnt = cmd_sscanf(cmd, "l=0x%x m=%u", &size, &mode_cpu_ndma);
if (cnt != 2) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_INVALID_ARG;
}
src = cmd_malloc(size);
if (src == NULL) {
CMD_ERR("no memory\n");
goto error_exit;
}
soft_result = cmd_malloc(size);
if (soft_result == NULL) {
CMD_ERR("no memory\n");
goto error_exit;
}
ahb_result = cmd_malloc(size);
if (ahb_result == NULL) {
CMD_ERR("no memory\n");
goto error_exit;
}
psram_buf = psram_malloc(size);
if (psram_buf == NULL) {
CMD_ERR("no psram heap memory\n");
goto error_exit;
}
HAL_FlashCrypto_Init(flash_enc_nonce);
/* write normal function test */
cmd_memset(src, 0x5a, size);
cmd_memcpy((void *)psram_buf, src, size);
HAL_Dcache_Clean((uint32_t)psram_buf, size);
cmd_memcpy(ahb_result, (void *)psram_buf, size);
if (cmd_memcmp(src, ahb_result, size)) {
CMD_ERR("psram normal wr-test fail !\n");
}
for (i = 0; i < 1; i++) {
cmd_memset(src, data_fill[i], size);
cmd_memset(ahb_result, 0x0, size);
#if FLASH_CRYPTO_DISABLE_CAN_USE
int32_t crypto_ch = FlashCryptoRequest((uint32_t)psram_buf,
(uint32_t)psram_buf + size - 1,
key);
#else
FlashCryptoRequest((uint32_t)psram_buf, (uint32_t)psram_buf + size - 1,
key);
#endif
if (!mode_cpu_ndma) {
//CPU
CMD_DBG("psram crypto test through CPU\n");
cmd_memcpy((void *)psram_buf, src, size);
HAL_Dcache_Clean((uint32_t)psram_buf, size);
cmd_memcpy(ahb_result, (void *)psram_buf, size);
} else {
//DMA
CMD_DBG("psram crypto test through DMA\n");
//DMA channel request
dma_ch = HAL_DMA_Request();
if (dma_ch == DMA_CHANNEL_INVALID) {
CMD_ERR("request dma channel fail !\n");
goto error_exit;
}
dma_sem = &g_fc_info.sem;
OS_SemaphoreCreate(dma_sem, 0, 1);
dmaParam.irqType = DMA_IRQ_TYPE_END;
dmaParam.endCallback = (DMA_IRQCallback)OS_SemaphoreRelease;
dmaParam.endArg = dma_sem;
//src->psram_buf
dmaParam.cfg = HAL_DMA_MakeChannelInitCfg(DMA_WORK_MODE_SINGLE,
DMA_WAIT_CYCLE_2,
DMA_BYTE_CNT_MODE_REMAIN,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_4,
DMA_ADDR_MODE_INC,
DMA_PERIPH_FLASHC,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_1,
DMA_ADDR_MODE_INC,
DMA_PERIPH_SRAM);
HAL_DMA_Init(dma_ch, &dmaParam);
HAL_DMA_Start(dma_ch, (uint32_t)src, (uint32_t)psram_buf, size);
if (OS_SemaphoreWait(dma_sem, 2000) != OS_OK)
CMD_ERR("sem wait failed: %d\n", ret);
HAL_DMA_Stop(dma_ch);
HAL_DMA_DeInit(dma_ch);
//psram_buf->ahb_result
dmaParam.cfg = HAL_DMA_MakeChannelInitCfg(DMA_WORK_MODE_SINGLE,
DMA_WAIT_CYCLE_2,
DMA_BYTE_CNT_MODE_REMAIN,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_1,
DMA_ADDR_MODE_INC,
DMA_PERIPH_SRAM,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_4,
DMA_ADDR_MODE_INC,
DMA_PERIPH_FLASHC);
HAL_DMA_Init(dma_ch, &dmaParam);
HAL_DMA_Start(dma_ch, (uint32_t)psram_buf, (uint32_t)ahb_result, size);
if (OS_SemaphoreWait(dma_sem, 2000) != OS_OK)
CMD_ERR("sem wait failed: %d\n", ret);
HAL_DMA_Stop(dma_ch);
HAL_DMA_DeInit(dma_ch);
//DMA channel release
HAL_DMA_Release(dma_ch);
OS_SemaphoreDelete(dma_sem);
}
if (cmd_memcmp(src, ahb_result, size)) {
CMD_ERR("psram decrypt test error !\n");
CMD_DBG("the source data :\n");
print_hex_dump_bytes(src, size);
CMD_DBG("HW decrypt result :\n");
print_hex_dump_bytes(ahb_result, size);
goto error_exit;
}
#if FLASH_CRYPTO_DISABLE_CAN_USE
FlashCryptoRelease(crypto_ch);
soft_flash_enc(flash_enc_nonce, key,
(uint32_t)psram_buf - CONFIG_PSRAM_START, size, src,
soft_result);
cmd_memset(ahb_result, 0x0, size);
if (!mode_cpu_ndma) {
//CPU
HAL_Dcache_Flush((uint32_t)psram_buf, size);
cmd_memcpy(ahb_result, (void *)psram_buf, size);
} else {
//DMA
//DMA channel request
dma_ch = HAL_DMA_Request();
if (dma_ch == DMA_CHANNEL_INVALID) {
CMD_ERR("request dma channel fail !\n");
goto error_exit;
}
dma_sem = &g_fc_info.sem;
OS_SemaphoreCreate(dma_sem, 0, 1);
dmaParam.irqType = DMA_IRQ_TYPE_END;
dmaParam.endCallback = (DMA_IRQCallback)OS_SemaphoreRelease;
dmaParam.endArg = dma_sem;
//psram_buf->ahb_result
dmaParam.cfg = HAL_DMA_MakeChannelInitCfg(DMA_WORK_MODE_SINGLE,
DMA_WAIT_CYCLE_2,
DMA_BYTE_CNT_MODE_REMAIN,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_1,
DMA_ADDR_MODE_INC,
DMA_PERIPH_SRAM,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_4,
DMA_ADDR_MODE_INC,
DMA_PERIPH_FLASHC);
HAL_DMA_Init(dma_ch, &dmaParam);
HAL_DMA_Start(dma_ch, (uint32_t)psram_buf, (uint32_t)ahb_result, size);
if (OS_SemaphoreWait(dma_sem, 2000) != OS_OK)
CMD_ERR("sem wait failed: %d\n", ret);
HAL_DMA_Stop(dma_ch);
HAL_DMA_DeInit(dma_ch);
//DMA channel release
HAL_DMA_Release(dma_ch);
OS_SemaphoreDelete(dma_sem);
}
if (cmd_memcmp(soft_result, ahb_result, size)) {
CMD_ERR("psram encrypt test error !\n");
CMD_DBG("SW encrypt result :\n");
print_hex_dump_bytes(soft_result, size);
CMD_DBG("HW encrypt result :\n");
print_hex_dump_bytes(ahb_result, size);
goto error_exit;
}
#endif
}
CMD_LOG(1, "psarm crypto test successful !\n");
ret = CMD_STATUS_OK;
error_exit:
cmd_free(src);
cmd_free(soft_result);
cmd_free(ahb_result);
psram_free(psram_buf);
return ret;
}
static enum cmd_status cmd_flash_crypto_setup_exec(char *cmd)
{
int32_t cnt;
uint32_t mode, start_addr, size;
uint8_t key[16] = {0x15, 0x22, 0x67, 0x55, 0x1a, 0x3b, 0x5c, 0x34, 0x79,
0x7f, 0x11, 0x35, 0xbd, 0xf4, 0x88, 0x3b};
cnt = cmd_sscanf(cmd, "m=%u s=0x%x l=0x%x", &mode, &start_addr, &size);
if (cnt != 3) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_INVALID_ARG;
}
if (start_addr < 0x100000) {
CMD_ERR("flash test address should not less than 1MB, 0x%x!\n",
start_addr);
}
if (mode) {
start_addr += CONFIG_PSRAM_START;
}
g_fc_info.crypto_type = mode;
g_fc_info.crypto_addr = start_addr;
g_fc_info.crypto_length = size;
HAL_FlashCrypto_Init(flash_enc_nonce);
g_fc_info.crypto_channel = FlashCryptoRequest(start_addr,
start_addr + size - 1, key);
return CMD_STATUS_OK;
}
#endif
static enum cmd_status cmd_flash_crypto_test_exec(char *cmd)
{
int32_t cnt;
uint32_t ret = CMD_STATUS_FAIL, i;
uint8_t *src, *ahb_result;
uint32_t start_addr, size;
cnt = cmd_sscanf(cmd, "s=0x%x l=0x%x", &start_addr, &size);
if (cnt != 2) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_INVALID_ARG;
}
src = cmd_malloc(size);
if (src == NULL) {
CMD_ERR("no memory\n");
cmd_free(src);
return ret;
}
ahb_result = cmd_malloc(size);
if (ahb_result == NULL) {
CMD_ERR("no memory\n");
cmd_free(ahb_result);
return ret;
}
for (i = 0; i < size; i++) {
src[i] = (i & 0xff);
}
cmd_memset(ahb_result, 0x0, size);
if (g_fc_info.crypto_type) {
start_addr += CONFIG_PSRAM_START;
cmd_memcpy((void *)start_addr, src, size);
cmd_memcpy(ahb_result, (void *)start_addr, size);
} else {
if (HAL_Flash_Open(MFLASH, 5000) != HAL_OK) {
CMD_ERR("flash driver open failed\n");
goto error_exit;
}
if (HAL_Flash_Overwrite(MFLASH, start_addr, src, size) != HAL_OK) {
CMD_ERR("flash write failed !\n");
}
if (flash_read(MFLASH, start_addr, ahb_result, size) != size) {
CMD_ERR("flash read failed\n");
}
if (HAL_Flash_Close(MFLASH) != HAL_OK) {
CMD_ERR("flash driver close failed\n");
}
}
if (cmd_memcmp(src, ahb_result, size)) {
CMD_ERR("flash decrypt test error !\n");
CMD_DBG("the source data :\n");
print_hex_dump_bytes(src, size);
CMD_DBG("HW decrypt result :\n");
print_hex_dump_bytes(ahb_result, size);
goto error_exit;
}
CMD_LOG(1, "flash crypto test successful !\n");
ret = CMD_STATUS_OK;
error_exit:
cmd_free(src);
cmd_free(ahb_result);
return ret;
}
#if FLASH_CRYPTO_DISABLE_CAN_USE
static enum cmd_status cmd_flash_crypto_finish_exec(char *cmd)
{
FlashCryptoRelease(g_fc_info.crypto_channel);
return CMD_STATUS_OK;
}
#endif
static void fc_press_test_task(void *arg)
{
uint8_t *src = NULL, *ahb_result = NULL;
uint32_t i, start_addr, size, test_times = 0;
cmd_fc_t *priv = &g_fc_info;
start_addr = priv->crypto_addr;
size = priv->crypto_length > 4096 ? 4096 : priv->crypto_length;
if (!priv->crypto_type) {
if (HAL_Flash_Open(MFLASH, 5000) != HAL_OK) {
CMD_ERR("flash driver open failed\n");
goto exit;
}
}
src = cmd_malloc(size);
if (src == NULL) {
CMD_ERR("no memory\n");
goto exit;
}
ahb_result = cmd_malloc(size);
if (ahb_result == NULL) {
CMD_ERR("no memory\n");
goto exit;
}
for (i = 0; i < size; i++) {
src[i] = (i & 0xff);
}
while (test_times++ < priv->test_times) {
cmd_memset(ahb_result, 0x0, size);
if (priv->crypto_type) {
cmd_memcpy((void *)start_addr, src, size);
HAL_Dcache_Clean(start_addr, size);
cmd_memcpy(ahb_result, (void *)start_addr, size);
} else {
if (HAL_Flash_Overwrite(MFLASH, start_addr, src, size) != HAL_OK) {
CMD_ERR("flash write failed !\n");
}
if (flash_read(MFLASH, start_addr, ahb_result, size) != size) {
CMD_ERR("flash read failed\n");
}
}
if (cmd_memcmp(src, ahb_result, size)) {
CMD_ERR("flash decrypt test error !\n");
CMD_DBG("the source data :\n");
print_hex_dump_bytes(src, size);
CMD_DBG("HW decrypt result :\n");
print_hex_dump_bytes(ahb_result, size);
CMD_LOG(1, "test failed on the %d times.\n", test_times);
goto exit;
} else {
if (!(test_times % 50)) {
CMD_LOG(1, "flash crypto pressure test %04u times...\n", test_times);
}
}
OS_MSleep(100);
}
CMD_LOG(1, "flash crypto pressure test pass !\n");
exit:
if (!priv->crypto_type) {
if (HAL_Flash_Close(MFLASH) != HAL_OK) {
CMD_ERR("flash driver close failed\n");
}
}
cmd_free(src);
cmd_free(ahb_result);
OS_SemaphoreRelease(&priv->sem);
}
static enum cmd_status cmd_flash_crypto_pressure_exec(char *cmd)
{
int32_t cnt;
uint32_t test_times;
cmd_fc_t *priv = &g_fc_info;
cnt = cmd_sscanf(cmd, "t=%u", &test_times);
if (cnt != 1) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_INVALID_ARG;
}
priv->test_times = test_times;
OS_SemaphoreCreate(&priv->sem, 0, 1);
if (OS_ThreadCreate(&priv->thread,
"fcrypto-press-test",
fc_press_test_task,
NULL,
OS_PRIORITY_NORMAL,
1024) != OS_OK) {
CMD_LOG(1, "create Task[fcrypto-press-test] failed\n");
return CMD_STATUS_FAIL;
}
OS_SemaphoreWait(&priv->sem, OS_WAIT_FOREVER);
OS_SemaphoreDelete(&priv->sem);
OS_ThreadDelete(&priv->thread);
return CMD_STATUS_OK;
}
#if FLASH_CRYPTO_DISABLE_CAN_USE
static void fc_bus_switch_test_task1(void *arg)
{
uint8_t *src = NULL, *ahb_result = NULL;
uint32_t i, start_addr, size;
cmd_fc_t *priv = &g_fc_info;
static uint32_t run_time = 0;
uint8_t key[16] = {0x15, 0x22, 0x67, 0x55, 0x1a, 0x3b, 0x5c, 0x34, 0x79,
0x7f, 0x11, 0x35, 0xbd, 0xf4, 0x88, 0x3b};
OS_Time_t tick_current = 0, tick_record = 0;
OS_Time_t tick_end = OS_GetTicks() + OS_SecsToTicks(priv->test_times);
start_addr = priv->crypto_addr;
size = priv->crypto_length > 4096 ? 4096 : priv->crypto_length;
src = cmd_malloc(size);
if (src == NULL) {
CMD_ERR("no memory\n");
goto exit;
}
ahb_result = cmd_malloc(size);
if (ahb_result == NULL) {
CMD_ERR("no memory\n");
goto exit;
}
for (i = 0; i < size; i++) {
src[i] = (i & 0xff);
}
HAL_FlashCrypto_Init(flash_enc_nonce);
#if 1
if (flash_erase(MFLASH, start_addr, 0x8000)) {
CMD_ERR("Flash Erase failure !\n");
goto exit;
}
if (flash_write_crypto(MFLASH, start_addr, src, size, key) != size) {
CMD_ERR("flash read failed\n");
goto exit;
}
#else
if (HAL_Flash_Overwrite_Crypto(MFLASH, start_addr, src, size, key) != HAL_OK) {
CMD_ERR("flash write failed !\n");
goto exit;
}
#endif
while (tick_current < tick_end) {
cmd_memset(ahb_result, 0x0, size);
if (flash_read_crypto(MFLASH, start_addr, ahb_result, size, key) != size) {
CMD_ERR("flash read failed\n");
}
if (cmd_memcmp(src, ahb_result, size)) {
CMD_ERR("flash decrypt test error !\n");
CMD_DBG("the source data :\n");
print_hex_dump_bytes(src, size);
CMD_DBG("HW decrypt result :\n");
print_hex_dump_bytes(ahb_result, size);
break;
}
OS_MSleep(4);
tick_current = OS_GetTicks();
if (OS_TicksToSecs(tick_current - tick_record) >= 10) {
run_time += 10;
CMD_LOG(1, "test run normally %04ds...\n", run_time);
tick_record = tick_current;
}
}
if (tick_current >= tick_end) {
CMD_LOG(1, "thread[%s] test successful !\n", __func__);
}
exit:
run_time = 0;
cmd_free(src);
cmd_free(ahb_result);
OS_ThreadDelete(NULL);
}
static void fc_bus_switch_test_task2(void *arg)
{
int ret;
uint32_t addr, size = 0x200, i;
uint8_t *wbuf;
cmd_fc_t *priv = &g_fc_info;
OS_Time_t tick_current = 0;
OS_Time_t tick_end = OS_GetTicks() + OS_SecsToTicks(priv->test_times);
wbuf = cmd_malloc(size);
if (wbuf == NULL) {
CMD_ERR("no heap memory\n");
goto exit;
}
for (i = 0; i < size; i++) {
wbuf[i] = (i & 0xff);
}
addr = priv->crypto_addr + priv->crypto_length + 0x1000;
while (tick_current < tick_end) {
if (HAL_Flash_Open(MFLASH, 3000) != HAL_OK) {
CMD_ERR("flash driver open failed\n");
break;
}
if ((ret = HAL_Flash_Overwrite(MFLASH, addr, wbuf, size)) != HAL_OK) {
CMD_ERR("flash write failed: %d\n", ret);
break;
}
if ((ret = HAL_Flash_Check(MFLASH, addr, wbuf, size)) != 0) {
CMD_ERR("flash write not success %d\n", ret);
break;
}
if (HAL_Flash_Close(MFLASH) != HAL_OK) {
CMD_ERR("flash driver close failed\n");
break;
}
OS_MSleep(3);
tick_current = OS_GetTicks();
}
if (tick_current >= tick_end) {
CMD_LOG(1, "thread[%s] test successful !\n", __func__);
}
exit:
cmd_free(wbuf);
OS_ThreadDelete(NULL);
}
static enum cmd_status cmd_flash_crypto_bus_switch_exec(char *cmd)
{
int32_t cnt;
uint32_t start_addr, size, test_times;
cmd_fc_t *priv = &g_fc_info;
cnt = cmd_sscanf(cmd, "s=0x%x l=0x%x t=%u", &start_addr, &size, &test_times);
if (cnt != 3) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_INVALID_ARG;
}
g_fc_info.crypto_addr = start_addr;
g_fc_info.crypto_length = size;
g_fc_info.test_times = test_times;
if (OS_ThreadCreate(&priv->thread,
"fc_bus_switch_test_task1",
fc_bus_switch_test_task1,
NULL,
OS_PRIORITY_NORMAL,
1024) != OS_OK) {
CMD_LOG(1, "create Task[fc_bus_switch_test_task1] failed\n");
return CMD_STATUS_FAIL;
}
OS_ThreadSetInvalid(&priv->thread);
if (OS_ThreadCreate(&priv->thread,
"fc_bus_switch_test_task2",
fc_bus_switch_test_task2,
NULL,
OS_PRIORITY_NORMAL,
1024) != OS_OK) {
CMD_LOG(1, "create Task[fc_bus_switch_test_task2] failed\n");
return CMD_STATUS_FAIL;
}
OS_ThreadSetInvalid(&priv->thread);
return CMD_STATUS_OK;
}
#endif
#if (defined(CONFIG_PSRAM))
/*
* @brief To make the statistics of cache miss/hit counter more accurate,
* please make sure that no code&data in psram.
*/
static enum cmd_status cmd_flash_crypto_cache_exec(char *cmd)
{
#if FLASH_CRYPTO_DISABLE_CAN_USE
int32_t crypto_ch = 0;
#endif
int32_t cnt;
enum cmd_status ret = CMD_STATUS_FAIL;
uint8_t *src = NULL, *ahb_result = NULL, *psram_buf = NULL;
uint32_t size = 0x400, i, cache_write_cnt = 0, cache_read_cnt = 0;
uint8_t key[16] = {0x15, 0x22, 0x67, 0x55, 0x1a, 0x3b, 0x5c, 0x34, 0x79,
0x7f, 0x11, 0x35, 0xbd, 0xf4, 0x88, 0x3b};
DMA_ChannelInitParam dmaParam;
DMA_Channel dma_ch;
OS_Semaphore_t *dma_sem;
cnt = cmd_sscanf(cmd, "l=0x%x", &size);
if (cnt != 1) {
CMD_ERR("invalid param number %d\n", cnt);
return CMD_STATUS_INVALID_ARG;
}
src = cmd_malloc(size);
if (src == NULL) {
CMD_ERR("no memory\n");
goto error_exit;
}
ahb_result = cmd_malloc(size);
if (ahb_result == NULL) {
CMD_ERR("no memory\n");
goto error_exit;
}
psram_buf = psram_malloc(size);
if (psram_buf == NULL) {
CMD_ERR("no psram heap memory\n");
goto error_exit;
}
for (i = 0; i < size; i++) {
src[i] = (i & 0xff);
}
HAL_FlashCrypto_Init(flash_enc_nonce);
#if FLASH_CRYPTO_DISABLE_CAN_USE
crypto_ch = FlashCryptoRequest((uint32_t)psram_buf,
(uint32_t)psram_buf + size - 1, key);
#else
FlashCryptoRequest((uint32_t)psram_buf, (uint32_t)psram_buf + size - 1,
key);
#endif
OS_ThreadSuspendScheduler();
HAL_Dcache_CleanAll();
HAL_Dcache_FlushAll();
HAL_Dcache_DumpMissHit();
cache_write_cnt = HAL_REG_32BIT(0x40009090);
cache_read_cnt = HAL_REG_32BIT(0x40009094);
for (i = 0; i < size; i++) {
psram_buf[i] = src[i];
}
CMD_LOG(1, "after write %d bytes psram :\n", size);
HAL_Dcache_DumpMissHit();
cache_write_cnt = HAL_REG_32BIT(0x40009090) - cache_write_cnt;
cache_read_cnt = HAL_REG_32BIT(0x40009094) - cache_read_cnt;
CMD_LOG(1, "cache_write_cnt -> 0x%08x, cache_read_cnt -> 0x%08x\n",
cache_write_cnt, cache_read_cnt);
OS_ThreadResumeScheduler();
dma_ch = HAL_DMA_Request();
if (dma_ch == DMA_CHANNEL_INVALID) {
CMD_ERR("request dma channel fail !\n");
goto error_exit;
}
dma_sem = &g_fc_info.sem;
OS_SemaphoreCreate(dma_sem, 0, 1);
dmaParam.irqType = DMA_IRQ_TYPE_END;
dmaParam.endCallback = (DMA_IRQCallback)OS_SemaphoreRelease;
dmaParam.endArg = dma_sem;
dmaParam.cfg = HAL_DMA_MakeChannelInitCfg(DMA_WORK_MODE_SINGLE,
DMA_WAIT_CYCLE_2,
DMA_BYTE_CNT_MODE_REMAIN,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_4,
DMA_ADDR_MODE_INC,
DMA_PERIPH_FLASHC,
DMA_DATA_WIDTH_8BIT,
DMA_BURST_LEN_1,
DMA_ADDR_MODE_INC,
DMA_PERIPH_SRAM);
HAL_DMA_Init(dma_ch, &dmaParam);
HAL_DMA_Start(dma_ch, (uint32_t)psram_buf, (uint32_t)ahb_result, size);
if (OS_SemaphoreWait(dma_sem, 2000) != OS_OK)
CMD_ERR("sem wait failed: %d\n", ret);
HAL_DMA_Stop(dma_ch);
HAL_DMA_DeInit(dma_ch);
HAL_DMA_Release(dma_ch);
OS_SemaphoreDelete(dma_sem);
if (cmd_memcmp(src, ahb_result, size)) {
CMD_ERR("psram crypto wr-test fail !\n");
goto error_exit;
}
CMD_LOG(1, "psarm crypto wr-test successful !\n");
ret = CMD_STATUS_OK;
error_exit:
#if FLASH_CRYPTO_DISABLE_CAN_USE
FlashCryptoRelease(crypto_ch);
#endif
cmd_free(src);
cmd_free(ahb_result);
psram_free(psram_buf);
return ret;
}
#endif
static const struct cmd_data g_flashc_crypto_cmds[] = {
#if (defined(CONFIG_PSRAM))
{ "psram", cmd_psram_crypto_exec },
{ "fc-setup", cmd_flash_crypto_setup_exec },
#endif
{ "fc-test", cmd_flash_crypto_test_exec },
#if FLASH_CRYPTO_DISABLE_CAN_USE
{ "fc-finish", cmd_flash_crypto_finish_exec },
{ "flash", cmd_flash_crypto_exec },
{ "bus-switch-scene", cmd_flash_crypto_bus_switch_exec },
#endif
{ "fc-pressure", cmd_flash_crypto_pressure_exec },
{ "flash_bench", cmd_flash_crypto_bench_exec },
#if (defined(CONFIG_PSRAM))
{ "fc-cache-scene", cmd_flash_crypto_cache_exec }
#endif
};
enum cmd_status cmd_flashc_crypto_exec(char *cmd)
{
return cmd_exec(cmd, g_flashc_crypto_cmds,
cmd_nitems(g_flashc_crypto_cmds));
}
#endif