blob: 9c7cf5ff0f8b45748512bc8a7151ae5a1923e970 [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* common/cmd_sha2.c
*
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
*
*/
/*
* Functions in this file implement Amlogic SHA2 function
*
* Author : zhongfu.luo@amlogic.com
*
* Feature: implement uboot command for SHA2 common usage
* command : sha2 addr_in len [addr_out]
* addr_in[IN] : DDR address for input buffer
* len[IN] : total data size to be processed for SHA2
* addr_out[OUT]: user defined output buffer for the SHA2 (if not set then the SHA2 of input will shown only but not stored)
*
* History: 1. 2017.06.01 function init
*
*
*/
#include <common.h>
#include <malloc.h>
#include <asm/arch/regs.h>
#include <u-boot/sha256.h>
#define DATA_MAX_LEN (1 << 31) //max length of SHA2 is 2 GB
static int do_sha2(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
int nReturn=CMD_RET_USAGE;
ulong addr_in,nLength,addr_out=0;
unsigned char szSHA2[32];
unsigned char *pSHA2 = szSHA2;
int nSHA2Type = 256;
char *endp;
int i;
/* need at least three arguments */
if (argc < 3)
goto exit;
nReturn = __LINE__;
if ( 0 == *argv[1] )
{
printf("[addr_in] format error! \n" );
goto exit;
}
addr_in = simple_strtoul(argv[1], &endp, 16);
if ( 0 != *endp )
{
printf("[addr_in] format error! \n" );
goto exit;
}
nReturn = __LINE__;
if ( 0 == *argv[2])
{
printf("[Length] format error! \n" );
goto exit;
}
nLength = simple_strtoul(argv[2], &endp, 16);
if ( 0 != *endp )
{
printf("[Length] format error! \n" );
goto exit;
}
if ( !nLength || nLength > DATA_MAX_LEN)
{
printf("Length range: 0x00000001 ~ 0x%08x Byte! \n", DATA_MAX_LEN );
goto exit;
}
nReturn = __LINE__;
if (argc > 3)
{
if ( 0 == *argv[3] )
{
printf("[addr_out] format error! \n" );
goto exit;
}
addr_out = simple_strtoul(argv[3], &endp, 16);
if ( 0 != *endp )
{
printf("[addr_out] format error! \n" );
goto exit;
}
pSHA2=(unsigned char *)addr_out;
}
sha256_csum_wd((unsigned char *)addr_in, nLength,pSHA2,0);
printf("\nSHA%d of addr_in: 0x%08x, len: 0x%08x ", nSHA2Type, (unsigned int)addr_in, (unsigned int)nLength);
if (argc > 3)
printf(", addr_out: 0x%08x \n", (unsigned int)addr_out);
printf("\n");
for (i=0; i<SHA256_SUM_LEN; i++)
printf("%02x%s", pSHA2[i], ((i+1) % 16==0) ? "\n" :" ");
nReturn = 0;
exit:
return nReturn;
}
#undef DATA_MAX_LEN
U_BOOT_CMD(
sha2, 4, 1, do_sha2,
"SHA2 command",
"addr_in len [addr_out] \n"
);
/*
* Feature: implement uboot command for test SHA2 common usage
* command : sha2test [writeval] [len]
* writeval[IN] : the value of data for test(default is 0x01)
* len[IN] : total data size to be processed for SHA2 (default is 128k bytes)
*
* History: 1. 2017.06.01 function init
*
*
*/
//#define CONFIG_AML_SHA2_TEST
#if defined(CONFIG_AML_SHA2_TEST)
#define writel(val,reg) (*((volatile unsigned *)(reg)))=(val)
#define readl(reg) (*((volatile unsigned *)(reg)))
#define TEST_MAX_LEN (10<<20)
#define TEST_MIN_LEN (64)
static int do_sha2test(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
int nReturn = __LINE__;
unsigned char *pBuffer = 0;
int i;
int nLength = TEST_MAX_LEN;
unsigned int byPattern = 1;
char *endp;
int nSHA2Type = 256;
unsigned int ntime1,ntime2,ntime;
unsigned char szSHA2[32];
int testLength[8]={TEST_MAX_LEN,1024*1024,100*1024,10*1024,1024,512,128,TEST_MIN_LEN};
int c=0;
#ifdef CONFIG_AML_HW_SHA2
printf("aml log : Amlogic HW SHA2 \n");
#else
printf("aml log : Software SHA2 \n");
#endif
//pattern
if (argc > 1)
{
if ( 0 == *argv[1] )
{
printf("[writeval] format error! \n" );
goto exit;
}
byPattern = simple_strtoul(argv[1], &endp, 16);
if ( 0 != *endp )
{
printf("[writeval] format error! \n" );
goto exit;
}
if ( byPattern > 0xff)
{
printf("writeval range: 0x00 ~ 0xff! \n" );
goto exit;
}
}
nReturn = __LINE__;
//length
if (argc > 2)
{
if ( 0== *argv[2] )
{
printf("[Length] format error! \n" );
goto exit;
}
nLength = simple_strtoul(argv[2], &endp, 16);
if ( 0 != *endp )
{
printf("[Length] format error! \n" );
goto exit;
}
if ( !nLength || nLength > TEST_MAX_LEN)
{
printf("Length range: 0x00000001 ~ 0x%08x Byte! \n", TEST_MAX_LEN );
goto exit;
}
}
nReturn = __LINE__;
pBuffer=(unsigned char*)malloc(nLength);
if (!pBuffer)
{
printf("malloc fail! \n" );
goto exit;
}
//set buffer with dedicated pattern
memset(pBuffer,byPattern,nLength);
do
{
ntime1=readl(P_ISA_TIMERE);
sha256_csum_wd(pBuffer, nLength,szSHA2,0 );
ntime2=readl(P_ISA_TIMERE);
ntime = ntime2 - ntime1;
printf("\nSHA%d of value: 0x%02x, len: 0x%08x, time used: %d us, bandwidth: %d kB/s \n",\
nSHA2Type, (unsigned int)byPattern, nLength,ntime, (unsigned int)((float)nLength/1024/ntime*1000000));
//SHA2 dump
for (i=0; i<SHA256_SUM_LEN; i++)
printf("%02x%s", szSHA2[i], ((i+1) % 16==0) ? "\n" :" ");
if (argc > 2)
break;
nLength =testLength[++c];
}
while (nLength > TEST_MIN_LEN) ;
nReturn = 0;
exit:
if (pBuffer)
{
free(pBuffer);
pBuffer = 0;
}
return nReturn;
}
#undef writel
#undef readl
#undef TEST_MAX_LEN
#undef TEST_MIN_LEN
U_BOOT_CMD(
sha2test, 3, 1, do_sha2test,
"test SHA2 fuction",
"[writeval] [len] \n"
);
#endif //#if defined(CONFIG_AML_SHA2_TEST)