| /* |
| * Copyright (C) 2014-2017 Amlogic, Inc. All rights reserved. |
| * |
| * All information contained herein is Amlogic confidential. |
| * |
| * This software is provided to you pursuant to Software License Agreement |
| * (SLA) with Amlogic Inc ("Amlogic"). This software may be used |
| * only in accordance with the terms of this agreement. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification is strictly prohibited without prior written permission from |
| * Amlogic. |
| * |
| * 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. |
| */ |
| /* |
| * 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) |