diff --git a/lib/sw_services/xilsecure/data/xilsecure.mld b/lib/sw_services/xilsecure/data/xilsecure.mld new file mode 100755 index 00000000..477cef69 --- /dev/null +++ b/lib/sw_services/xilsecure/data/xilsecure.mld @@ -0,0 +1,50 @@ +############################################################################### +# +# Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# Modification History +# +# Ver Who Date Changes +# ----- ---- -------- ----------------------------------------------- +# 1.00a ba 06/01/15 Initial Release +# +############################################################################## + +OPTION psf_version = 2.1; + +BEGIN LIBRARY xilsecure + OPTION copyfiles = all; + OPTION REQUIRES_OS = (standalone); + OPTION APP_LINKER_FLAGS = "-Wl,--start-group,-lxilsecure,-lxil,-lgcc,-lc,--end-group"; + OPTION desc = "Xilinx Secure Library "; + OPTION VERSION = 1.0; + OPTION NAME = xilsecure; +END LIBRARY diff --git a/lib/sw_services/xilsecure/data/xilsecure.tcl b/lib/sw_services/xilsecure/data/xilsecure.tcl new file mode 100755 index 00000000..96685162 --- /dev/null +++ b/lib/sw_services/xilsecure/data/xilsecure.tcl @@ -0,0 +1,86 @@ +############################################################################### +# +# Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# Modification History +# +# Ver Who Date Changes +# ----- ---- -------- ----------------------------------------------- +# 1.00a ba 06/01/15 Initial Release +############################################################################## + +#--------------------------------------------- +# skey_drc +#--------------------------------------------- +proc skey_drc {libhandle} { + +} + +proc generate {libhandle} { + +} + +#------- +# post_generate: called after generate called on all libraries +#------- +proc post_generate {libhandle} { + + xgen_opts_file $libhandle +} + +#------- +# execs_generate: called after BSP's, libraries and drivers have been compiled +# This procedure builds the libxilsecure.a library +#------- +proc execs_generate {libhandle} { + +} + +proc xgen_opts_file {libhandle} { + + + # Copy the include files to the include directory + set srcdir [file join src include] + set dstdir [file join .. .. include] + + # Create dstdir if it does not exist + if { ! [file exists $dstdir] } { + file mkdir $dstdir + } + + # Get list of files in the srcdir + set sources [file -join $srcdir *.h] + + # Copy each of the files in the list to dstdir + foreach source $sources { + file copy -force $source $dstdir + } +} diff --git a/lib/sw_services/xilsecure/examples/index.html b/lib/sw_services/xilsecure/examples/index.html new file mode 100755 index 00000000..6b4c4530 --- /dev/null +++ b/lib/sw_services/xilsecure/examples/index.html @@ -0,0 +1,19 @@ + + +
+ + +Copyright � 1995-2014 Xilinx, Inc. All rights reserved.
+ + diff --git a/lib/sw_services/xilsecure/examples/xilsecure_aes_example.c b/lib/sw_services/xilsecure/examples/xilsecure_aes_example.c new file mode 100755 index 00000000..2f7f2288 --- /dev/null +++ b/lib/sw_services/xilsecure/examples/xilsecure_aes_example.c @@ -0,0 +1,193 @@ +/* + * secure_example_aes.c + * + * Created on: Oct 22, 2014 + * Author: bameta + */ + +/****************************************************************************** +* +* (c) Copyright 2010-13 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file secure_example_aes.c +* +* @note +* This example requires downloading an encrypted boot image without PMU +* firmware to a location in DDR memory. +* +* MODIFICATION HISTORY: +*+* Ver Who Date Changes +* ----- ------ -------- ------------------------------------------------- +* 1.00a ba 01/13/14 First Release +* +*+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xsecure_aes.h" + +/************************** Constant Definitions *****************************/ +/* + * the hard coded aes key for decryption, in case user given key is being used + * it will be loaded in KUP before decryption + */ +static const u8 csu_key[] = { + 0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18, + 0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08, + 0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10, + 0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00 +}; + +/* + * the hard coded iv used for decryption secure header and block 0 + */ +static const u32 csu_iv[] = {0xD2450E07, 0xEA5DE042, 0x6C0FA133, 0x00000000}; + +static u32 ImageOffset = 0x04000000; +static u32 HeaderSrcOffset = 0x030; +static u32 HeaderFsblLenOffset = 0x03C; + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int SecureAesExample(void); + +/************************** Variable Definitions *****************************/ + +XSecure_Aes Secure_Aes; +XCsuDma CsuDma; + +/*****************************************************************************/ +/** +* +* Main function to call the SecureAesExample. +* +* @param None +* +* @return +* - XST_FAILURE if the Test Failed . +* +* @note None +* +******************************************************************************/ +s32 main(void) +{ + int Status; + + Status = SecureAesExample(); + + if(Status == XST_SUCCESS) { + xil_printf("\r\n Decryption was successful \r\n"); + } + + return Status; +} + +/****************************************************************************/ +/** +* +* This function decrypts the FSBL from an encrypted boot image located in DDR. +* The resulting FSBL will be stored in FSBL at a higher offset +* The purpose of this function is to illustrate how to use the XSecure_Aes +* driver. +* +* +* @return +* - XST_FAILURE if the Aes decryption failed. +* - XST_SUCCESS if the Aes decryption was successful +* +* @note None. +* +****************************************************************************/ +int SecureAesExample(void) +{ + u8 *Dst = (u8 *)0x04100000; + XCsuDma_Config *Config; + + int Status; + + Config = XCsuDma_LookupConfig(0); + if (NULL == Config) { + xil_printf("config failed \n\r"); + return XST_FAILURE; + } + + Status = XCsuDma_CfgInitialize(&CsuDma, Config, Config->BaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Download the boot image elf in DDR, Read the boot header + * assign Src pointer to the location of FSBL image in it. Ensure + * that linker script does not map the example elf to the same + * location as this standalone example + */ + u32 FsblOffset = XSecure_In32((u32 *)(ImageOffset + HeaderSrcOffset)); + + u32 FsblLocation = ImageOffset + FsblOffset; + + u32 FsblLength = XSecure_In32((u32 *)(ImageOffset + HeaderFsblLenOffset)); + + /* + * Initialize the Aes driver so that it's ready to use + */ + XSecure_AesInitialize(&Secure_Aes, &CsuDma, XSECURE_CSU_AES_KEY_SRC_KUP, + (u32 *)csu_iv, (u32 *)csu_key); + + Status = XSecure_AesDecrypt(&Secure_Aes, Dst, (u8 *)FsblLocation, + FsblLength); + + + if(Status != XST_SUCCESS) + { + return XST_FAILURE; + } + + return XST_SUCCESS; +} diff --git a/lib/sw_services/xilsecure/examples/xilsecure_rsa_example.c b/lib/sw_services/xilsecure/examples/xilsecure_rsa_example.c new file mode 100755 index 00000000..9f151e98 --- /dev/null +++ b/lib/sw_services/xilsecure/examples/xilsecure_rsa_example.c @@ -0,0 +1,304 @@ +/* + * secure_example_rsa.c + * + * Created on: Oct 22, 2014 + * Author: bameta + */ + +/****************************************************************************** +* +* (c) Copyright 2010-13 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file secure_example_rsa.c +* +* @note +* This example requires downloading an RSA authenticated(SHA-3) boot image +* to a location in DDR memory. +* +* MODIFICATION HISTORY: +*
+* Ver Who Date Changes +* ----- ------ -------- ------------------------------------------------- +* 1.00a bameta 11/04/14 First Release +* +*+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xsecure_rsa.h" +#include "xsecure_sha.h" + +/************************** Constant Definitions *****************************/ + +static u32 ImageOffset = 0x04000000; +static u32 HeaderSrcOffset = 0x030; +static u32 HeaderFsblTotalLenOffset = 0x040; +static u32 HeaderFsblLenOffset = 0x03C; + +#define XSECURE_PPK_SIZE (512+512+64) +#define XSECURE_SPK_SIZE XSECURE_PPK_SIZE +#define XSECURE_SPK_SIG_SIZE (512) +#define XSECURE_BHDR_SIG_SIZE (512) +#define XSECURE_FSBL_SIG_SIZE (512) +#define XSECURE_RSA_KEY_LEN (4096) +#define XSECURE_RSA_BIG_ENDIAN (0x1) +#define XSECURE_RSA_AC_ALIGN (64) + +#define XSECURE_AUTH_HEADER_SIZE (8) + +#define XSECURE_AUTH_CERT_USER_DATA (64 - XSECURE_AUTH_HEADER_SIZE) + +#define XSECURE_AUTH_CERT_MIN_SIZE (XSECURE_AUTH_HEADER_SIZE \ + + XSECURE_AUTH_CERT_USER_DATA \ + + XSECURE_PPK_SIZE \ + + XSECURE_PPK_SIZE \ + + XSECURE_SPK_SIG_SIZE \ + + XSECURE_BHDR_SIG_SIZE \ + + XSECURE_FSBL_SIG_SIZE) + +#define XSECURE_AUTH_CERT_MAX_SIZE (XSECURE_AUTH_CERT_MIN_SIZE + 60) + +#define XSECURE_PARTIAL_AC_SIZE (XSECURE_AUTH_CERT_MIN_SIZE - \ + XSECURE_FSBL_SIG_SIZE) + +#define XSECURE_IMAGE_VERIF_ERROR (2) +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +u32 SecureRsaExample(void); + +/************************** Variable Definitions *****************************/ + +XSecure_Rsa Secure_Rsa; +XSecure_Sha3 Secure_Sha3; +XCsuDma CsuDma; +u8 XSecure_RsaSha3Array[XSECURE_FSBL_SIG_SIZE]; + +/*****************************************************************************/ +/** +* +* Main function to call the SecureRsaExample +* +* @param None +* +* @return +* - XST_FAILURE if the boot image authentication Failed . +* +* @note None +* +******************************************************************************/ +/*int main(void) +{ + u32 Status; + + Status = SecureRsaExample(); + + if(Status != XST_SUCCESS) + { + xil_printf("\r\n Decryption Failed: %d \r\n ",Status); + return XST_FAILURE; + } + + xil_printf("\r\n Hashes matched, Decryption successful \r\n "); + xil_printf(" \r\n "); + + return XST_SUCCESS; +}*/ + +/****************************************************************************/ +/** +* +* This function authenticates boot image located in DDR using RSA-4096 +* algorithm. The decrypted hash is matched against the calculated boot image +* hash. +* The purpose of this function is to illustrate how to use the XSecure_Rsa +* driver. +* +* +* @return +* - XST_FAILURE if the authentication failed. +* +* @note None. +* +****************************************************************************/ +u32 SecureRsaExample(void) +{ + u32 Status; + + /* + * Download the boot image elf at a DDR location, Read the boot header + * assign Src pointer to the location of FSBL image in it. Ensure + * that linker script does not map the example elf to the same + * location as this standalone example + */ + u32 FsblOffset = XSecure_In32((u32 *)(ImageOffset + HeaderSrcOffset)); + + xil_printf(" Fsbl Offset in the image is %0x ",FsblOffset); + xil_printf(" \r\n "); + + u32 FsblLocation = ImageOffset + FsblOffset; + + xil_printf(" Fsbl Location is %0x ",FsblLocation); + xil_printf(" \r\n "); + + u32 TotalFsblLength = XSecure_In32((u32 *)(ImageOffset + + HeaderFsblTotalLenOffset)); + + u32 FsblLength = XSecure_In32((u32 *)(ImageOffset + + HeaderFsblLenOffset)); + + u32 AcLocation = FsblLocation + TotalFsblLength - XSECURE_AUTH_CERT_MIN_SIZE; + + xil_printf(" Authentication Certificate Location is %0x ",AcLocation); + xil_printf(" \r\n "); + + u8 BIHash[XSECURE_HASH_TYPE_SHA3] __attribute__ ((aligned (4))); + u8 * SpkModular = (u8 *)XNULL; + u8 * SpkModularEx = (u8 *)XNULL; + u32 SpkExp = 0; + u8 * AcPtr = (u8 *)AcLocation; + u32 ErrorCode = XST_SUCCESS; + u32 FsblTotalLen = TotalFsblLength - XSECURE_FSBL_SIG_SIZE; + + xil_printf(" Fsbl Total Length(Total - BI Signature) %0x ", + (u32)FsblTotalLen); + xil_printf(" \r\n "); + + /** + * Set SPK pointer + */ + AcPtr += (XSECURE_RSA_AC_ALIGN + XSECURE_PPK_SIZE); + SpkModular = (u8 *)AcPtr; + AcPtr += XSECURE_FSBL_SIG_SIZE; + SpkModularEx = (u8 *)AcPtr; + AcPtr += XSECURE_FSBL_SIG_SIZE; + SpkExp = *((u32 *)AcPtr); + AcPtr += XSECURE_RSA_AC_ALIGN; + + /** + * Set Boot Image Signature pointer + */ + AcPtr += (XSECURE_SPK_SIG_SIZE + XSECURE_BHDR_SIG_SIZE); + xil_printf(" Boot Image Signature Location is %0x ",(u32)AcPtr); + xil_printf(" \r\n "); + + /* + * Set up CSU DMA instance for SHA-3 transfers + */ + XCsuDma_Config *Config; + + Config = XCsuDma_LookupConfig(0); + if (NULL == Config) { + xil_printf("config failed\n\r"); + return XST_FAILURE; + } + + Status = XCsuDma_CfgInitialize(&CsuDma, Config, Config->BaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Initialize the SHA-3 driver so that it's ready to use + * Look up the configuration in the config table and then initialize it. + */ + + XSecure_Sha3Initialize(&Secure_Sha3, &CsuDma); + XSecure_Sha3Start(&Secure_Sha3); + + /** + * Calculate FSBL Hash + */ + XSecure_Sha3Update(&Secure_Sha3, (u8 *)FsblLocation, + FsblTotalLen); + + XSecure_Sha3Finish(&Secure_Sha3, (u8 *)BIHash); + + /* + * Initialize the Rsa driver so that it's ready to use + * Look up the configuration in the config table and then initialize it. + */ + XSecure_RsaInitialize(&Secure_Rsa, AcPtr, SpkModular, SpkModularEx, + (u8 *)&SpkExp); + + /* + * Decrypt Boot Image Signature. + */ + if(XST_SUCCESS != XSecure_RsaDecrypt(&Secure_Rsa, XSecure_RsaSha3Array)) + { + ErrorCode = XSECURE_IMAGE_VERIF_ERROR; + goto ENDF; + } + + xil_printf("\r\n Calculated Boot image Hash \r\n "); + int i= 0; + for(i=0; i < 384/8; i++) + { + xil_printf(" %0x ", BIHash[i]); + } + xil_printf(" \r\n "); + + xil_printf("\r\n Hash From Signature \r\n "); + int ii= 128; + for(ii = 464; ii < 512; ii++) + { + xil_printf(" %0x ", XSecure_RsaSha3Array[ii]); + } + xil_printf(" \r\n "); + + /* + * Authenticate FSBL Signature. + */ + if(XSecure_RsaCheckPadding(XSecure_RsaSha3Array, BIHash, + XSECURE_HASH_TYPE_SHA3) != 0) + { + ErrorCode = XSECURE_IMAGE_VERIF_ERROR; + } + +ENDF: + return ErrorCode; +} diff --git a/lib/sw_services/xilsecure/examples/xilsecure_sha_example.c b/lib/sw_services/xilsecure/examples/xilsecure_sha_example.c new file mode 100755 index 00000000..3f10304f --- /dev/null +++ b/lib/sw_services/xilsecure/examples/xilsecure_sha_example.c @@ -0,0 +1,162 @@ +/* + * secure_example.c + * + * Created on: Oct 20, 2014 + * Author: bameta + */ + +/****************************************************************************** +* +* (c) Copyright 2010-13 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file secure_example_sha.c +* +* @note None +* +* MODIFICATION HISTORY: +*
+* Ver Who Date Changes +* ----- ------ -------- ------------------------------------------------- +* 1.00a bameta 11/05/14 First Release +* +*+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xsecure_sha.h" + +/************************** Constant Definitions *****************************/ + +/* + * The following constants map to the XPAR parameters created in the + * xparameters.h file. They are defined here such that a user can easily + * change all the needed parameters in one place. + */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int SecureSha3Example(void); + +/************************** Variable Definitions *****************************/ + +XSecure_Sha3 Secure_Sha3; +XCsuDma CsuDma; + +/*****************************************************************************/ +/** +* +* Main function to call the SecureShaExample +* +* @param None +* +* @return +* - XST_FAILURE if the SHA calculation failed. +* +* @note None +* +******************************************************************************/ +/*int main(void) +{ + int Status; + + Status = SecureHelloWorldExample(); + + return Status; +}*/ + +/****************************************************************************/ +/** +* +* This function sends 'Hello World' to SHA-3 module for hashing. +* The purpose of this function is to illustrate how to use the XSecure_Sha3 +* driver. +* +* +* @return +* - XST_FAILURE if the SHA-3 hashing failed. +* +* @note None. +* +****************************************************************************/ +int SecureHelloWorldExample() +{ + u8 HelloWorld[4] = {'h','e','l','l'}; + u32 Size = sizeof(HelloWorld); + u8 Out[384/8]; + XCsuDma_Config *Config; + + int Status; + + Config = XCsuDma_LookupConfig(0); + if (NULL == Config) { + xil_printf("config failed\n\r"); + return XST_FAILURE; + } + + Status = XCsuDma_CfgInitialize(&CsuDma, Config, Config->BaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Initialize the SHA-3 driver so that it's ready to use + */ + XSecure_Sha3Initialize(&Secure_Sha3, &CsuDma); + + XSecure_Sha3Digest(&Secure_Sha3, HelloWorld, Size, Out); + + xil_printf(" Calculated Digest \r\n "); + int i= 0; + for(i=0; i< (384/8); i++) + { + xil_printf(" %0x ", Out[i]); + } + xil_printf(" \r\n "); + + return XST_SUCCESS; +} diff --git a/lib/sw_services/xilsecure/src/Makefile b/lib/sw_services/xilsecure/src/Makefile new file mode 100755 index 00000000..ca96f405 --- /dev/null +++ b/lib/sw_services/xilsecure/src/Makefile @@ -0,0 +1,106 @@ +############################################################################### +# +# Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### + +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= + +ifeq ($(COMPILER) , arm-xilinx-eabi-gcc) + EXTRA_ARCHIVE_FLAGS=rc +else +ifeq ($(COMPILER) , aarch64-none-elf-gcc) + EXTRA_ARCHIVE_FLAGS=rc +else +ifeq ($(COMPILER) , arm-none-eabi-gcc) + EXTRA_ARCHIVE_FLAGS=rc +else + EXTRA_ARCHIVE_FLAGS=--create +endif +endif +endif + +ifeq ($(COMPILER) , mb-gcc) + EXTRA_ARCHIVE_FLAGS=rc +endif + +RELEASEDIR=../../../lib +#RELEASEDIR= . +INCLUDEDIR=../../../include +INCLUDES=-I./include/ -I${INCLUDEDIR} +SECURE_DIR = . + +LIB_SRCS = $(SECURE_DIR)/xsecure_sha.c \ + $(SECURE_DIR)/xsecure_aes.c \ + $(SECURE_DIR)/xsecure_rsa.c + + +# create SECURE_SRCS based on configured options + +SECURE_SRCS = $(LIB_SRCS) + +SECURE_OBJS = $(SECURE_SRCS:%.c=%.o) + + +EXPORT_INCLUDE_FILES = $(SECURE_DIR)/xsecure_sha.h \ + $(SECURE_DIR)/xsecure_rsa.h \ + $(SECURE_DIR)/xsecure_aes.h + + +libs: libxilsecure.a + cp libxilsecure.a $(RELEASEDIR) + make clean + +include: + @for i in $(EXPORT_INCLUDE_FILES); do \ + ${CP} -r $$i ${INCLUDEDIR}; \ + done + +clean: + rm -rf obj/xsecure_rsa.o obj/xsecure_sha.o obj/xsecure_aes.o + rmdir obj + rm libxilsecure.a + + +libxilsecure.a: obj_dir print_msg_secure_base $(SECURE_OBJS) + @echo "Creating archive $@" + $(ARCHIVER) $(EXTRA_ARCHIVE_FLAGS) $@ obj/xsecure_rsa.o obj/xsecure_sha.o obj/xsecure_aes.o + + +obj_dir: + mkdir obj + +print_msg_secure_base: + @echo "Compiling Xilsecure Library" + +.c.o: + $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) -c $< -o obj/$(@F) diff --git a/lib/sw_services/xilsecure/src/xsecure_aes.c b/lib/sw_services/xilsecure/src/xsecure_aes.c new file mode 100755 index 00000000..ad133752 --- /dev/null +++ b/lib/sw_services/xilsecure/src/xsecure_aes.c @@ -0,0 +1,741 @@ +/****************************************************************************** +* +* (c) Copyright 2013 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +*******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xsecure_aes.c +* +* This file contains the implementation of the interface functions for AES +* driver. Refer to the header file xsecure_aes.h for more detailed information. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- --- -------- ------------------------------------------------------- +* 1.00 ba 09/10/2014 Initial release +* +*+* +* @note +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xsecure_aes.h" + +/************************** Function Prototypes ******************************/ + +/************************** Function Definitions *****************************/ + +/*****************************************************************************/ +/** + * + * Waits for AES completion for keyload. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * @param @param CsuDmaPtr is the pointer to the XCsuDma instance. + * @param KeySel is the key source for decryption, can be KUP or device key + * @param Iv is pointer to the Initialization Vector for decryption + * @param Key is the pointer to Aes decryption key in case KUP key is used + * Pass Null if device key is to be used + * + * @return XST_SUCCESS if initialization was successful. + * + ******************************************************************************/ +s32 XSecure_AesInitialize(XSecure_Aes *InstancePtr, XCsuDma *CsuDmaPtr, + u32 KeySel, u32* Iv, u32* Key) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(CsuDmaPtr != NULL); + Xil_AssertNonvoid(Iv != NULL); + + InstancePtr->BaseAddress = XSECURE_CSU_AES_BASE; + InstancePtr->CsuDmaPtr = CsuDmaPtr; + InstancePtr->KeySel = KeySel; + InstancePtr->Iv = Iv; + + /* + * Clarify if Aes block expects IV in big or small endian, swap endianness + * of Iv likewise + */ + + InstancePtr->Key = Key; + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * + * Waits for AES completion for keyload. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * + * @return None + * + ******************************************************************************/ +static void XSecure_AesWaitKeyLoad(XSecure_Aes *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + volatile u32 Status; + + do { + Status = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_STS_OFFSET); + } while (!((u32)Status & XSECURE_CSU_AES_STS_KEY_INIT_DONE)); +} + +/*****************************************************************************/ +/** + * + * Waits for AES completion. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * + * @return None + * + ******************************************************************************/ +static void XSecure_AesWaitForDone(XSecure_Aes *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + volatile u32 Status; + + do { + Status = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_STS_OFFSET); + } while ((u32)Status & XSECURE_CSU_AES_STS_AES_BUSY); +} + +/*****************************************************************************/ +/** + * + * Reset the AES engine. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * + * @return None + * + ******************************************************************************/ +void XSecure_AesReset(XSecure_Aes *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_RESET_OFFSET, XSECURE_CSU_AES_RESET); + + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_RESET_OFFSET, 0x0U); + //replaced mb here +} + +/*****************************************************************************/ +/** + * + * Reset the AES key storage registers. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * + * @return None + * + ******************************************************************************/ +void XSecure_AesKeyZero(XSecure_Aes *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + volatile u32 Status; + + Status = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KEY_CLR_OFFSET); + Status |= InstancePtr->KeySel; + + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KEY_CLR_OFFSET, (u32)Status); + Status &= ~InstancePtr->KeySel; + + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KEY_CLR_OFFSET, (u32)Status); + + do { + Status = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_STS_OFFSET); + } while ((InstancePtr->KeySel << 8) == ((u32)Status & + (InstancePtr->KeySel << 8))); +} + +/*****************************************************************************/ +/** + * + * Configures and load AES key from selected key source. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * + * @return None + * + ******************************************************************************/ +void XSecure_AesKeySelNLoad(XSecure_Aes *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + if(InstancePtr->KeySel == XSECURE_CSU_AES_KEY_SRC_DEV) + { + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KEY_SRC_OFFSET, XSECURE_CSU_AES_KEY_SRC_DEV); + } + else + { + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KEY_SRC_OFFSET, + XSECURE_CSU_AES_KEY_SRC_KUP); + } + + /** + * Trig loading of key. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KEY_LOAD_OFFSET, + XSECURE_CSU_AES_KEY_LOAD); + + /** + * Wait for AES key loading. + */ + XSecure_AesWaitKeyLoad(InstancePtr); +} + +/*****************************************************************************/ +/** + * + * Function for doing encryption using h/w AES engine. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * @param Dst is pointer to location where encrypted output will be written. + * @param Src is pointer to input data for encryption. + * @param Len is the size of input data in bytes + * + * @return None + * + ******************************************************************************/ +void XSecure_AesEncrypt(XSecure_Aes *InstancePtr, u8 *Dst, const u8 *Src, + u32 Len) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Dst != NULL); + Xil_AssertVoid(Src != NULL); + Xil_AssertVoid(Len != (u32)0x0); + + u32 SssCfg = 0U; + + /** + * Configure the SSS for AES. + */ + u32 SssDma = XSecure_SssInputDstDma(XSECURE_CSU_SSS_SRC_AES); + u32 SssAes = XSecure_SssInputAes(XSECURE_CSU_SSS_SRC_SRC_DMA); + + SssCfg = SssDma|SssAes ; + + XSecure_SssSetup(SssCfg); + + /** + * Configure the AES for Encryption. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_AES_CFG_OFFSET, + XSECURE_CSU_AES_CFG_ENC); + + /** + * Start the message. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_START_MSG_OFFSET, + XSECURE_CSU_AES_START_MSG); + + /** + * Push IV into the AES engine. + */ + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + (u64)InstancePtr->Iv, + XSECURE_SECURE_GCM_TAG_SIZE/4U, 0); + + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL); + + /** + * Configure the CSU DMA Tx/Rx. + */ + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL, (u64) Dst, + (Len + XSECURE_SECURE_GCM_TAG_SIZE)/4U, 0); + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, (u64) Src, + XSECURE_SECURE_GCM_TAG_SIZE/4U, 1); + + /** + * Wait for Dst/Src DMA done. + */ + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL); + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL); + + /** + * Wait for AES encryption completion. + */ + XSecure_AesWaitForDone(InstancePtr); +} + +/*****************************************************************************/ +/** + * + * Function for doing decryption using h/w AES engine. + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * @param Dst is pointer to location where encrypted output will be written. + * @param Src is pointer to input data for encryption. + * @param Tag is pointer to the GCM tag used for authentication + * @param Len is the length of the output data expected after decryption. + * @param Flag denotes whether the block is Secure header or data block + * + * @return + * -returns 1 if GCM tag matching was successful + * + ******************************************************************************/ +static u32 XSecure_AesDecryptBlk(XSecure_Aes *InstancePtr, u8 *Dst, const u8 *Src, + const u8 *Tag, u32 Len, u32 Flag) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Dst != NULL); + Xil_AssertNonvoid(Src != NULL); + Xil_AssertNonvoid(Tag != NULL); + + volatile u32 Status = 0U; + + /* + * Start the message. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_START_MSG_OFFSET, + XSECURE_CSU_AES_START_MSG); + + /* + * Push IV into the AES engine. + */ + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + (u64)InstancePtr->Iv, XSECURE_SECURE_GCM_TAG_SIZE/4U, 0); + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL); + + /** + * Enable CSU DMA Src channel for byte swapping. + */ + XCsuDma_Configure ConfigurValues = {0}; + + XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + &ConfigurValues); + + ConfigurValues.EndianType = 1U; + + XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + &ConfigurValues); + + if(Flag) + { + /** + * This means we are decrypting Block of the boot image. + * Enable CSU DMA Dst channel for byte swapping. + */ + + XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL, + &ConfigurValues); + ConfigurValues.EndianType = 1U; + + XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL, + &ConfigurValues); + /* + * Configure the CSU DMA Tx/Rx for the incoming Block. + */ + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL, + (u64)Dst, Len/4U, 0); + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + (u64)Src, Len/4U, 0); + + /* + * Wait for the Dst DMA completion. + */ + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL); + + /* + * Disble CSU DMA Dst channel for byte swapping. + */ + + XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL, + &ConfigurValues); + + ConfigurValues.EndianType = 0U; + + XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL, + &ConfigurValues); + + /* + * Configure AES engine to push decrypted Key and IV in the block, + * to the CSU KEY and IV registers. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KUP_WR_OFFSET, + XSECURE_CSU_AES_IV_WR | XSECURE_CSU_AES_KUP_WR); + + } + else + { + /* + * This means we are decrypting the Secure header. + * Configure AES engine to push decrypted IV in the Secure header, + * to the CSU IV register. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KUP_WR_OFFSET, + XSECURE_CSU_AES_IV_WR | XSECURE_CSU_AES_KUP_WR); + } + + /* + * Push the Secure header/footer for decrypting next blocks KEY and IV. + */ + + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + (u64)(Src + Len), XSECURE_SECURE_HDR_SIZE/4U, 1); + + /* + * Wait for the Src DMA completion. + */ + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL); + + /* + * Restore Key write register to 0. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_KUP_WR_OFFSET, 0x0); + + /* + * Push the GCM tag. + */ + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, (u64)Tag, + XSECURE_SECURE_GCM_TAG_SIZE/4U, 0); + + /* + * Wait for the Src DMA completion. + */ + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL); + + /* + * Disable CSU DMA Src channel for byte swapping. + */ + + XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + &ConfigurValues); + ConfigurValues.EndianType = 0U; + + XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + &ConfigurValues); + + /* + * Wait for AES Decryption completion. + */ + XSecure_AesWaitForDone(InstancePtr); + + /* + * Get the AES status to know if GCM check passed. + */ + Status = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_STS_OFFSET) & + XSECURE_CSU_AES_STS_GCM_TAG_OK; + + return !!Status; +} + +/*****************************************************************************/ +/** + * + * This function will handle the AES-GCM Decryption. + * + * The Multiple key(a.k.a Key Rolling) or Single key + * Encrypted images will have the same format, + * such that it will have the following: + * + * Secure header --> Dummy AES Key of 32byte + + * Block 0 IV of 12byte + + * DLC for Block 0 of 4byte + + * GCM tag of 16byte(Un-Enc). + * Block N --> Boot Image Data for Block N of n size + + * Block N+1 AES key of 32byte + + * Block N+1 IV of 12byte + + * GCM tag for Block N of 16byte(Un-Enc). + * + * The Secure header and Block 0 will be decrypted using + * Device key or user provide key. + * If more than 1 blocks are found then the key and IV + * obtained from previous block will be used for decryption + * + * + * 1> Read the 1st 64bytes and decrypt 48 bytes using + * the selected Device key. + * 2> Decrypt the 0th block using the IV + Size from step 2 + * and selected device key. + * 3> After decryption we will get decrypted data+KEY+IV+Blk + * Size so store the KEY/IV into KUP/IV registers. + * 4> Using Blk size, IV and Next Block Key information + * start decrypting the next block. + * 5> if the Current Image size > Total image length, + * go to next step 8. Else go back to step 5 + * 6> If there are failures, return error code + * 7> If we have reached this step means the decryption is SUCCESS. + * + * + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * @param Src is the pointer to encrypted data source location + * @param Dst is the pointer to location where decrypted data will be written + * @param Length is the expected total length of decrypted image expected. + * + * @return u32 ErrorCode + * + ******************************************************************************/ +u32 XSecure_AesDecrypt(XSecure_Aes *InstancePtr, u8 *Dst, const u8 *Src, + u32 Length) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Dst != NULL); + Xil_AssertNonvoid(Src != NULL); + + u32 SssCfg = 0x0U; + volatile u32 Status=0x0U; + u32 ErrorCode = XSECURE_CSU_AES_DECRYPTION_DONE ; + u32 CurrentImgLen = 0x0U; + u32 NextBlkLen = 0x0U; + u32 PrevBlkLen = 0x0U; + u8 *DestAddr= 0x0U; + u8 *SrcAddr = 0x0U; + u8 *GcmTagAddr = 0x0U; + u32 BlockCnt = 0x0U; + u32 ImageLen = 0x0U; + + /* + * Configure the SSS for AES. + */ + u32 SssDma = XSecure_SssInputDstDma(XSECURE_CSU_SSS_SRC_AES); + u32 SssAes = XSecure_SssInputAes(XSECURE_CSU_SSS_SRC_SRC_DMA); + + SssCfg = SssDma|SssAes ; + + XSecure_SssSetup(SssCfg); + + /* + * Configure AES for Decryption + */ + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_AES_CFG_OFFSET, + XSECURE_CSU_AES_CFG_DEC); + + DestAddr = Dst; + ImageLen = Length; + + SrcAddr = (u8 *)Src ; + GcmTagAddr = SrcAddr + XSECURE_SECURE_HDR_SIZE; + + /* + * Clear AES contents by reseting it. + */ + XSecure_AesReset(InstancePtr); + + if(InstancePtr->KeySel == XSECURE_CSU_AES_KEY_SRC_DEV) + { + XSecure_AesKeySelNLoad(InstancePtr); + } + else + { + u32 Count=0U, Value=0U; + u32 Addr=0U; + for(Count = 0U; Count < 8U; Count++) + { + /* + * Helion AES block expects the key in big-endian. + */ + Value = Xil_Htonl(InstancePtr->Key[Count]); + + Addr = InstancePtr->BaseAddress + XSECURE_CSU_AES_KUP_0_OFFSET + + (Count * 4); + XSecure_Out32(Addr, Value); + + } + XSecure_AesKeySelNLoad(InstancePtr); + } + + do + { + PrevBlkLen = NextBlkLen; + + /* + * Start decryption of Secure-Header/Block/Footer. + */ + + Status = XSecure_AesDecryptBlk(InstancePtr, DestAddr, + (const u8 *)SrcAddr, + ((const u8 *)GcmTagAddr), + NextBlkLen, + BlockCnt); + + /* + * If decryption failed then return error. + */ + if(0U == (u32)Status) + { + ErrorCode= XSECURE_CSU_AES_GCM_TAG_MISMATCH; + goto ENDF; + } + + /* + * Find the size of next block to be decrypted. + * Size is in 32-bit words so mul it with 4 + */ + NextBlkLen = Xil_Htonl(XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_AES_IV_3_OFFSET)) * 4; + + /* + * Update the current image size. + */ + CurrentImgLen += NextBlkLen; + + if(0U == NextBlkLen) + { + if(CurrentImgLen != Length) + { + /* + * If this is the last block then check + * if the current image != size in the header + * then return error. + */ + ErrorCode = XSECURE_CSU_AES_IMAGE_LEN_MISMATCH; + goto ENDF; + } + else + { + goto ENDF; + } + } + else + { + /* + * If this is not the last block then check + * if the current image > size in the header + * then return error. + */ + if(CurrentImgLen > ImageLen) + { + ErrorCode = XSECURE_CSU_AES_IMAGE_LEN_MISMATCH; + goto ENDF; + } + } + + if(BlockCnt > 0U) + { + /* + * Update DestAddr and SrcAddr for next Block decryption. + */ + DestAddr += PrevBlkLen; + SrcAddr = (GcmTagAddr + XSECURE_SECURE_GCM_TAG_SIZE); + /* + * This means we are done with Secure header and Block 0 + * And now we can change the AES key source to KUP. + */ + InstancePtr->KeySel = XSECURE_CSU_AES_KEY_SRC_KUP; + XSecure_AesKeySelNLoad(InstancePtr); + } + else + { + /* + * Update SrcAddr for Block-0 + */ + SrcAddr = (SrcAddr + XSECURE_SECURE_HDR_SIZE + + XSECURE_SECURE_GCM_TAG_SIZE); + /* + * Point IV to the CSU IV register. + */ + InstancePtr->Iv = (u32 *)(InstancePtr->BaseAddress + + XSECURE_CSU_AES_IV_0_OFFSET); + } + + /* + * Update the GcmTagAddr to get GCM-TAG for next block. + */ + GcmTagAddr = SrcAddr + NextBlkLen + XSECURE_SECURE_HDR_SIZE; + + /* + * Update block count. + */ + BlockCnt++; + + }while(1); + +ENDF: + XSecure_AesReset(InstancePtr); + return ErrorCode; +} diff --git a/lib/sw_services/xilsecure/src/xsecure_aes.h b/lib/sw_services/xilsecure/src/xsecure_aes.h new file mode 100755 index 00000000..fa47b735 --- /dev/null +++ b/lib/sw_services/xilsecure/src/xsecure_aes.h @@ -0,0 +1,193 @@ +/****************************************************************************** +* +* (c) Copyright 2013 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +*******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xsecure_aes.h +* +* This file contains hardware interface related information for CSU AES device +* +* This driver supports the following features: +* +* - AES decryption with/without keyrolling +* - Authentication using GCM tag +* +* Initialization & Configuration +* +* The Aes driver instance can be initialized +* in the following way: +* +* - XSecure_AesInitialize(XSecure_Aes *InstancePtr, XCsuDma *CsuDmaPtr, +* u32 KeySel, u32* Iv, u32* Key) +* +* The key for decryption can be the device key or user provided key. +* KeySel variable denotes the key to be used. In case the key is user +* provided, key has to be provided in Key variable. If it is device key, +* the key variable will be ignored and device key will be used +* +* The initial Initialization vector will be used for decrypting secure header +* and block 0 of given encrypted data. +* +* +* @note +* -The format of encrypted data(boot image) has to be exactly as +* specified by the bootgen. Any encrypted data has to start with a +* secure header first and then the data blocks. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00 ba 10/10/14 Initial release +* +*+* +* +******************************************************************************/ + +#ifndef XSECURE_CSU_AES_H +#define XSECURE_CSU_AES_H + +/************************** Include Files ***********************************/ + +#include "xsecure_hw.h" +#include "../../../include/xcsudma.h" +#include "xstatus.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + +#define XSECURE_CSU_AES_STS_AES_BUSY (1U << 0) /**< AES busy */ +#define XSECURE_CSU_AES_STS_AES_READY (1U << 1) /**< Ready to Receive Data */ +#define XSECURE_CSU_AES_STS_AES_DONE (1U << 2) /**< Operation Complete */ +#define XSECURE_CSU_AES_STS_GCM_TAG_OK (1U << 3) /**< GCM Tag Passed */ +#define XSECURE_CSU_AES_STS_KEY_INIT_DONE (1U << 4) /**< Key Initialized */ +#define XSECURE_CSU_AES_STS_AES_KEY_ZERO (1U << 8) /**< AES key zeroed */ +#define XSECURE_CSU_AES_STS_KUP_ZEROED (1U << 9) /**< KUP key Zeroed */ +#define XSECURE_CSU_AES_STS_BOOT_KEY_ZERO (1U << 10) /**< Boot Key zeroed */ +#define XSECURE_CSU_AES_STS_OKR_ZERO (1U << 11) /**< Operational Key zeroed */ + +#define XSECURE_CSU_AES_KEY_SRC_KUP (0x0U) /**< KUP key source */ +#define XSECURE_CSU_AES_KEY_SRC_DEV (0x1U) /**< Device Key source */ + +#define XSECURE_CSU_AES_KEY_LOAD (1U << 0) /**< Load AES key from Source */ + +#define XSECURE_CSU_AES_START_MSG (1U << 0) /**< AES Start message */ + +#define XSECURE_CSU_AES_KUP_WR (1U << 0) /**< Direct AES Output to KUP */ +#define XSECURE_CSU_AES_IV_WR (1U << 1) + /**< Direct AES Output to IV Reg */ + +#define XSECURE_CSU_AES_RESET (1U << 0) /**< Reset Value */ + +#define XSECURE_CSU_AES_KEY_ZERO (1U << 0) /**< set AES key to zero */ +#define XSECURE_CSU_AES_KUP_ZERO (1U << 1) /**< Set KUP Reg. to zero */ + +#define XSECURE_CSU_AES_CFG_DEC (0x0U) /**< AES mode Decrypt */ +#define XSECURE_CSU_AES_CFG_ENC (0x1U) /**< AES Mode Encrypt */ + +#define XSECURE_CSU_KUP_WR (1U << 0) /**< Direct output to KUP */ +#define XSECURE_CSU_IV_WR (1U << 4) /**< image length mismatch */ + +/* + * Error Codes and Statuses + */ +#define XSECURE_CSU_AES_DECRYPTION_DONE 0U + /**< AES Decryption successful */ +#define XSECURE_CSU_AES_GCM_TAG_MISMATCH 1U /**< user provided GCM tag does + not match calculated tag */ +#define XSECURE_CSU_AES_IMAGE_LEN_MISMATCH 2U /**< image length mismatch */ + +#define XSECURE_SECURE_HDR_SIZE (48U) + /**< Secure Header Size in Bytes*/ +#define XSECURE_SECURE_GCM_TAG_SIZE (16U) /**< GCM Tag Size in Bytes */ + +/************************** Type Definitions ********************************/ + +/** + * The AES-GCM driver instance data structure. A pointer to an instance data + * structure is passed around by functions to refer to a specific driver + * instance. + */ +typedef struct { + u32 BaseAddress; /**< Device Base Address */ + XCsuDma *CsuDmaPtr; /**< CSUDMA Instance Pointer */ + u32* Iv; /**< Initialization Vector */ + u32* Key; /**< AES Key */ + u32 KeySel; /**< Key Source selection */ +} XSecure_Aes; + +/************************** Function Prototypes ******************************/ + +/* + * Initialization Functions + */ + +s32 XSecure_AesInitialize(XSecure_Aes *InstancePtr, XCsuDma *CsuDmaPtr, + u32 KeySel, u32* Iv, u32* Key); + +void XSecure_AesKeySelNLoad(XSecure_Aes *InstancePtr); + +/* + * Decryption + */ +u32 XSecure_AesDecrypt(XSecure_Aes *InstancePtr, u8 *Dst, const u8 *Src, + u32 Length); + +/* + * Encryption + */ +void XSecure_AesEncrypt(XSecure_Aes *InstancePtr, u8 *Dst, const u8 *Src, + u32 Len); + +/* + * Reset + */ +void XSecure_AesReset(XSecure_Aes *InstancePtr); + +/* + * Additional configuration + */ +void XSecure_AesKeyZero(XSecure_Aes *InstancePtr) ; + +#endif /* XSECURE_AES_H_ */ diff --git a/lib/sw_services/xilsecure/src/xsecure_hw.h b/lib/sw_services/xilsecure/src/xsecure_hw.h new file mode 100755 index 00000000..6dc1fba6 --- /dev/null +++ b/lib/sw_services/xilsecure/src/xsecure_hw.h @@ -0,0 +1,353 @@ +/****************************************************************************** + * + * (c) Copyright 2014 Xilinx, Inc. All rights reserved. + * + * This file contains confidential and proprietary information of Xilinx, Inc. + * and is protected under U.S. and international copyright and other + * intellectual property laws. + * + * DISCLAIMER + * This disclaimer is not a license and does not grant any rights to the + * materials distributed herewith. Except as otherwise provided in a valid + * license issued to you by Xilinx, and to the maximum extent permitted by + * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL + * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, + * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF + * MERCHANTABILITY, NON- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; + * and + * (2) Xilinx shall not be liable (whether in contract or tort, including + * negligence, or under any other theory of liability) for any loss or damage + * of any kind or nature related to, arising under or in connection with these + * materials, including for any direct, or any indirect, special, incidental, + * or consequential loss or damage (including loss of data, profits, + * goodwill, or any type of loss or damage suffered as a result of any + * action brought by a third party) even if such damage or loss was + * reasonably foreseeable or Xilinx had been advised of the possibility + * of the same. + * + * CRITICAL APPLICATIONS + * Xilinx products are not designed or intended to be fail- safe, or for use + * in any application requiring fail-safe performance, such as life-support + * or safety devices or systems, Class III medical devices, nuclear + * facilities, applications related to the deployment of airbags, or any + * other applications that could lead to death, personal injury, or severe + * property or environmental damage (individually and collectively, + * "Critical Applications"). Customer assumes the sole risk and liability + * of any use of Xilinx products in Critical Applications, subject only to + * applicable laws and regulations governing limitations on product liability. + * + * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART + * OF THIS FILE AT ALL TIMES. + * + ******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xsecure_hw.h +* +* This is the header file which contains definitions for the hardware +* interface of secure hardware devices. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00 ba 09/25/14 Initial release +* +*+* +* @note +* +******************************************************************************/ + +#ifndef XSECURE_HW_H +#define XSECURE_HW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_io.h" +#include "xparameters.h" +#include "xil_types.h" +#include "sleep.h" + +/************************** Constant Definitions *****************************/ + +#define XSECURE_CSU_REG_BASE_ADDR (0xFFCA0000U) /**< CSU base address */ +#define XSECURE_CSU_DMA_BASE (0xFFC80000U) /**< CSUDMA base address */ + +#define XSECURE_CSU_SHA3_BASE (XSECURE_CSU_REG_BASE_ADDR + 0x2000U) + /**< SHA3 base address */ + +#define XSECURE_CSU_CTRL_REG (XSECURE_CSU_REG_BASE_ADDR + 0x4U) /**< CSU control reg. */ +#define XSECURE_CSU_SSS_BASE (XSECURE_CSU_REG_BASE_ADDR + 0x8U) /**< CSU SSS base address */ +#define XSECURE_CSU_AES_BASE (XSECURE_CSU_REG_BASE_ADDR + 0x1000U) + /**< CSU AES base address */ + +#define XSECURE_CSU_RSA_BASE (0xFFCE0000U) + /**< RSA reg. base address */ + + +/** @name Register Map + * + * Register offsets for the SHA module. + * @{ + */ +#define XSECURE_CSU_SHA3_START_OFFSET (0x00U) /**< SHA start message */ +#define XSECURE_CSU_SHA3_RESET_OFFSET (0x04U) /**< Reset Register */ +#define XSECURE_CSU_SHA3_DONE_OFFSET (0x08U) /**< SHA Done Register */ + +#define XSECURE_CSU_SHA3_DIGEST_0_OFFSET (0x10U) /**< SHA3 Digest: Reg 0 */ +#define XSECURE_CSU_SHA3_DIGEST_11_OFFSET (0x34U) + /**< SHA3 Digest: Last Register */ +/* @} */ + +/** @name Register Map + * + * Register offsets for the AES module. + * @{ + */ +#define XSECURE_CSU_AES_STS_OFFSET (0x00U) /**< AES Status */ + +#define XSECURE_CSU_AES_KEY_SRC_OFFSET (0x04U) /**< AES Key Source */ + +#define XSECURE_CSU_AES_KEY_LOAD_OFFSET (0x08U) /**< AES Key Load Reg */ + +#define XSECURE_CSU_AES_START_MSG_OFFSET (0x0CU) /**< AES Start Message */ + +#define XSECURE_CSU_AES_RESET_OFFSET (0x10U) /**< AES Reset Register */ +#define XSECURE_CSU_AES_KEY_CLR_OFFSET (0x14U) /**< AES Key Clear */ +#define XSECURE_CSU_AES_CFG_OFFSET (0x18U) + /**< AES Operational Mode */ +#define XSECURE_CSU_AES_KUP_WR_OFFSET (0x1CU) + /**< AES KUP Write Control */ + +#define XSECURE_CSU_AES_KUP_0_OFFSET (0x20U) /**< AES Key Update 0 */ +#define XSECURE_CSU_AES_KUP_1_OFFSET (0x24U) /**< AES Key Update 1 */ +#define XSECURE_CSU_AES_KUP_2_OFFSET (0x28U) /**< AES Key Update 2 */ +#define XSECURE_CSU_AES_KUP_3_OFFSET (0x2CU) /**< AES Key Update 3 */ +#define XSECURE_CSU_AES_KUP_4_OFFSET (0x30U) /**< AES Key Update 4 */ +#define XSECURE_CSU_AES_KUP_5_OFFSET (0x34U) /**< AES Key Update 5 */ +#define XSECURE_CSU_AES_KUP_6_OFFSET (0x38U) /**< AES Key Update 6 */ +#define XSECURE_CSU_AES_KUP_7_OFFSET (0x3CU) /**< AES Key Update 7 */ + +#define XSECURE_CSU_AES_IV_0_OFFSET (0x40U) /**< AES IV 0 */ +#define XSECURE_CSU_AES_IV_1_OFFSET (0x44U) /**< AES IV 1 */ +#define XSECURE_CSU_AES_IV_2_OFFSET (0x48U) /**< AES IV 2 */ +#define XSECURE_CSU_AES_IV_3_OFFSET (0x4CU) /**< AES IV 3 */ +/* @} */ + + +/** @name Register Map + * + * Register offsets for the RSA module. + * @{ + */ +#define XSECURE_CSU_RSA_WRITE_DATA_OFFSET (0x00U) + /**< RAM write data offset */ +#define XSECURE_CSU_RSA_WRITE_ADDR_OFFSET (0x04U) + /**< RAM write address offset */ +#define XSECURE_CSU_RSA_READ_DATA_OFFSET (0x08U) + /**< RAM data read offset */ +#define XSECURE_CSU_RSA_READ_ADDR_OFFSET (0x0CU) + /**< RAM read offset */ +#define XSECURE_CSU_RSA_CONTROL_OFFSET (0x10U) + /**< RSA Control Reg */ + +#define XSECURE_CSU_RSA_STATUS_OFFSET (0x14U) + /**< Status Register */ + +#define XSECURE_CSU_RSA_MINV0_OFFSET (0x18U) + /**< RSA MINV(Mod 32 Inverse) 0 */ +#define XSECURE_CSU_RSA_MINV1_OFFSET (0x1CU) + /**< RSA MINV 1 */ +#define XSECURE_CSU_RSA_MINV2_OFFSET (0x20U) /**< RSA MINV 2 */ +#define XSECURE_CSU_RSA_MINV3_OFFSET (0x24U) /**< RSA MINV 3 */ +#define XSECURE_CSU_RSA_ZERO_OFFSET (0x28U) /**< RSA Zero offset */ + +#define XSECURE_CSU_RSA_WR_DATA_0_OFFSET (0x2cU) /**< Write Data 0 */ +#define XSECURE_CSU_RSA_WR_DATA_1_OFFSET (0x30U) /**< Write Data 1 */ +#define XSECURE_CSU_RSA_WR_DATA_2_OFFSET (0x34U) /**< Write Data 2 */ +#define XSECURE_CSU_RSA_WR_DATA_3_OFFSET (0x38U) /**< Write Data 3 */ +#define XSECURE_CSU_RSA_WR_DATA_4_OFFSET (0x3cU) /**< Write Data 4 */ +#define XSECURE_CSU_RSA_WR_DATA_5_OFFSET (0x40U) /**< Write Data 5 */ +#define XSECURE_CSU_RSA_WR_ADDR_OFFSET (0x44U) + /**< Write address in RSA RAM */ + +#define XSECURE_CSU_RSA_RD_DATA_0_OFFSET (0x48U) /**< Read Data 0 */ +#define XSECURE_CSU_RSA_RD_DATA_1_OFFSET (0x4cU) /**< Read Data 1 */ +#define XSECURE_CSU_RSA_RD_DATA_2_OFFSET (0x50U) /**< Read Data 2 */ +#define XSECURE_CSU_RSA_RD_DATA_3_OFFSET (0x54U) /**< Read Data 3 */ +#define XSECURE_CSU_RSA_RD_DATA_4_OFFSET (0x58U) /**< Read Data 4 */ +#define XSECURE_CSU_RSA_RD_DATA_5_OFFSET (0x5cU) /**< Read Data 5 */ +#define XSECURE_CSU_RSA_RD_ADDR_OFFSET (0x60U) + /**< Read address in RSA RAM */ +/* @} */ + +/**************************** Type Definitions *******************************/ + +/* + * Definition for SSS reg Source bits. + */ +typedef enum +{ + XSECURE_CSU_SSS_SRC_PCAP = 0x3U, + XSECURE_CSU_SSS_SRC_SRC_DMA = 0x5U, + XSECURE_CSU_SSS_SRC_AES = 0xAU, + XSECURE_CSU_SSS_SRC_PSTP = 0xCU, + XSECURE_CSU_SSS_SRC_NONE = 0x0U, + XSECURE_CSU_SSS_SRC_MASK = 0xFU +}XSECURE_CSU_SSS_SRC; + +/** +* Definition for SSS reg Destination bits. +*/ +typedef enum +{ + XSECURE_CSU_SSS_PCAP_SHIFT = 0U, + XSECURE_CSU_SSS_DMA_SHIFT = 4U, + XSECURE_CSU_SSS_AES_SHIFT = 8U, + XSECURE_CSU_SSS_SHA_SHIFT = 12U, + XSECURE_CSU_SSS_PSTP_SHIFT = 16U +}XSECURE_CSU_SSS_DEST_SHIFT; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* Read a CSU register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the +* device. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XSecure_ReadReg(u32 BaseAddress, int RegOffset) +* +******************************************************************************/ +#define XSecure_ReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (RegOffset)) + +/***************************************************************************/ +/** +* Write a CSU register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the +* device. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XSecure_WriteReg(u32 BaseAddress, int RegOffset, +* u16 RegisterValue) +* +******************************************************************************/ +#define XSecure_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + Xil_Out32((BaseAddress) + (RegOffset), (RegisterValue)) + +#define XSecure_In32(Addr) Xil_In32(Addr) + +#define XSecure_In64(Addr) Xil_In64(Addr) + +#define XSecure_Out32(Addr, Data) Xil_Out32(Addr, Data) + +#define XSecure_Out64(Addr, Data) Xil_Out64(Addr, Data) + +/** +* Definition for SSS inline functions +*/ + +/***************************************************************************/ +/** +* Set the SSS configuration mask for a data transfer to DMA device +* +* @param Src contains the bits for source device sending data to DMA. +* +* @return None. +* +* @note C-Style signature: +* void XSecure_SssInputDstDma(XSECURE_CSU_SSS_SRC Src) +* +******************************************************************************/ +static inline u32 XSecure_SssInputDstDma(XSECURE_CSU_SSS_SRC Src) +{ + Src &= XSECURE_CSU_SSS_SRC_MASK; + return (Src << XSECURE_CSU_SSS_DMA_SHIFT); +} + +/***************************************************************************/ +/** +* Set the SSS configuration mask for a data transfer to AES device +* +* @param Src contains the bits for AES source device +* +* @return None. +* +* @note C-Style signature: +* void XSecure_SssInputAes(XSECURE_CSU_SSS_SRC Src) +* +******************************************************************************/ +static inline u32 XSecure_SssInputAes(XSECURE_CSU_SSS_SRC Src) +{ + Src &= XSECURE_CSU_SSS_SRC_MASK; + return (Src << XSECURE_CSU_SSS_AES_SHIFT); +} + +/***************************************************************************/ +/** +* Set the SSS configuration mask for a data transfer to SHA device +* +* @param Src contains the bits for SHA source device +* +* @return None. +* +* @note C-Style signature: +* void XSecure_SssInputSha3(XSECURE_CSU_SSS_SRC Src) +* +******************************************************************************/ +static inline u32 XSecure_SssInputSha3(XSECURE_CSU_SSS_SRC Src) +{ + Src &= XSECURE_CSU_SSS_SRC_MASK; + return (Src << XSECURE_CSU_SSS_SHA_SHIFT); +} + +/***************************************************************************/ +/** +* Set up the CSU Secure Stream Switch configuration +* +* @param Cfg contains the 32 bit value to be written into SSS config +* register +* +* @return None. +* +* @note C-Style signature: +* void XSecure_SssSetup(u32 Cfg) +* +******************************************************************************/ +static inline void XSecure_SssSetup(u32 Cfg) +{ + //XSecure_Out32(XSECURE_CSU_SSS_BASE, + // (XSecure_In32(XSECURE_CSU_SSS_BASE) | Cfg)); + + XSecure_Out32(XSECURE_CSU_SSS_BASE, Cfg); + +} + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* XSECURE_HW_H */ diff --git a/lib/sw_services/xilsecure/src/xsecure_rsa.c b/lib/sw_services/xilsecure/src/xsecure_rsa.c new file mode 100755 index 00000000..814ca58e --- /dev/null +++ b/lib/sw_services/xilsecure/src/xsecure_rsa.c @@ -0,0 +1,519 @@ +/****************************************************************************** +* +* (c) Copyright 2014 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +*******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xsecure_rsa.c +* +* This file contains the implementation of the interface functions for RSA +* driver. Refer to the header file xsecure_sha.h for more detailed information. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00 ba 13/10/14 Initial release +* +*+* +* @note +* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "xsecure_rsa.h" + +/************************** Constant Definitions *****************************/ + +/* + * PKCS padding for SHA-3 + */ +static const u8 XSecure_TPadSha3[] = {0x30U, 0x41U, 0x30U, 0x0DU, 0x06U, 0x09U, + 0x60U, 0x86U, 0x48U, 0x01U, 0x65U, 0x03U, 0x04U, 0x02U, + 0x02U, 0x05U, 0x00U, 0x04U, 0x30U }; + +/* + * PKCS padding scheme for SHA-2 + */ +static const u8 XSecure_TPadSha2[] = {0x30U, 0x31U, 0x30U, 0x0DU, 0x06U, 0x09U, + 0x60U, 0x86U, 0x48U, 0x01U, 0x65U, 0x03U, 0x04U, 0x02U, + 0x01U, 0x05U, 0x00U, 0x04U, 0x20U }; + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Definitions *****************************/ + +/*****************************************************************************/ +/** + * + * Initializes a specific Xsecure_Rsa instance so that it is ready to be used. + * + * @param InstancePtr is a pointer to the XSecure_Rsa instance. + * @param EncText is the pointer to text/data to be authenticated using RSA + * @param Mod is the pointer to Modulus used for authentication + * @param ModExt is the pointer to precalculated R^2 Mod N value used for + * authentication + * @param ModExpo is the pointer to the exponent(public key) used for + * authentication + * + * @return XST_SUCCESS if initialization was successful. + * + * @note + * + * Modulus, ModExt and ModExpo are part of signature generated by bootgen + * after authentication + * + ******************************************************************************/ +s32 XSecure_RsaInitialize(XSecure_Rsa *InstancePtr, u8 *EncText, u8 *Mod, + u8 *ModExt, u8 *ModExpo) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(EncText != NULL); + Xil_AssertNonvoid(Mod != NULL); + Xil_AssertNonvoid(ModExt != NULL); + Xil_AssertNonvoid(ModExpo != NULL); + + InstancePtr->BaseAddress = XSECURE_CSU_RSA_BASE; + InstancePtr->EncText = EncText; + InstancePtr->Mod = Mod; + InstancePtr->ModExt = ModExt; + InstancePtr->ModExpo = ModExpo; + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * + * Write Data to RSA RAM at a given offset + * + * @param InstancePtr is a pointer to the XSecure_Aes instance. + * @param WrData is pointer to the data to be written to RSA RAM + * @param RamOffset is the offset for the data to be written in RSA RAM + * + * @return None + * + ******************************************************************************/ +static void XSecure_RsaWriteMem(XSecure_Rsa *InstancePtr, u32* WrData, + u8 RamOffset) +{ + + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(WrData != NULL); + + u32 Index = 0U; + u32 DataOffset = 0U; + u32 TmpIndex = 0U; + u32 Data = 0U; + + /** Each of this loop will write 192 bits of data*/ + for (DataOffset = 0U; DataOffset < 22U; DataOffset++) + { + for (Index = 0U; Index < 6U; Index++) + { + TmpIndex = (DataOffset*6) + Index; + /** + * Exponent size is only 4 bytes + * and rest of the data needs to be 0 + */ + if(XSECURE_CSU_RSA_RAM_EXPO == RamOffset) + { + if(0U == TmpIndex ) + { + Data = Xil_Htonl(*WrData); + } + else + { + Data = 0x0U; + } + } + else + { + if(TmpIndex >=128U) + { + Data = 0x0U; + } + else + { + /** + * The RSA data in Image is in Big Endian. + * So reverse it before putting in RSA memory, + * becasue RSA h/w expects it in Little endian. + */ + + Data = Xil_Htonl(WrData[127U - TmpIndex]); + } + } + XSecure_WriteReg(InstancePtr->BaseAddress, + (XSECURE_CSU_RSA_WR_DATA_0_OFFSET + (Index * 4)), + Data); + } + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_RSA_WR_ADDR_OFFSET, + ((RamOffset * 22) + DataOffset)); + } +} + +/*****************************************************************************/ +/** + * + * Read back the resulting data from RSA RAM + * + * @param InstancePtr is a pointer to the XSecure_Rsa instance. + * @param RdData is the pointer to location where the decrypted data will be + * written + * + * @return None + * + ******************************************************************************/ +static void XSecure_RsaGetData(XSecure_Rsa *InstancePtr, u32 *RdData) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(RdData != NULL); + + u32 Index = 0U; + u32 DataOffset = 0U; + int TmpIndex = 0; + + /* + * Each of this loop will write 192 bits of data + */ + for (DataOffset = 0U; DataOffset < 22U; DataOffset++) + { + XSecure_WriteReg(InstancePtr->BaseAddress, + XSECURE_CSU_RSA_RD_ADDR_OFFSET, + (XSECURE_CSU_RSA_RAM_RES_Y * 22) + DataOffset); + + Index = (DataOffset == 0U) ? 2: 0; + for (; Index < 6; Index++) + { + TmpIndex = 129 - ((DataOffset*6) + Index); + if(TmpIndex < 0) + { + break; + } + /* + * The Signature digest is compared in Big endian. + * So because RSA h/w results in Little endian, + * reverse it after reading it from RSA memory, + */ + RdData[TmpIndex] = Xil_Htonl(XSecure_ReadReg( + InstancePtr->BaseAddress, + (XSECURE_CSU_RSA_RD_DATA_0_OFFSET+ (Index * 4)))); + } + } + +} + +/***************************************************************************** + * Calculate the MINV value and put it into RSA core registers + * + * @param InstancePtr is the pointer to XSeure_Rsa instance + * + * @return None + * + * @notes MINV is the 32-bit value of "-M mod 2**32" + * where M is LSB 32 bits of the original modulus + * + ******************************************************************************/ + +static void XSecure_RsaMod32Inverse(XSecure_Rsa *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + /* + * Calculate the MINV + */ + u8 Count = 0U; + u32 *ModPtr = (u32 *)(InstancePtr->Mod); + u32 ModVal = Xil_Htonl(ModPtr[127]); + u32 Inv = 2U - ModVal; + + for (Count = 0U; Count < 4U; ++Count) + { + Inv = (Inv * (2U - ( ModVal * Inv ) ) ); + } + + Inv = -Inv; + + /* + * Put the value in MINV registers + */ + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_MINV0_OFFSET, + (Inv & 0xFF )); + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_MINV1_OFFSET, + ((Inv >> 8) & 0xFF )); + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_MINV2_OFFSET, + ((Inv >> 16) & 0xFF )); + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_MINV3_OFFSET, + ((Inv >> 24) & 0xFF )); +} + +/*****************************************************************************/ +/** + * + * Write all the RSA data used for decryption (Modulus, Exponent etc.) at + * corresponding offsets in RSA RAM. + * + * @param InstancePtr is a pointer to the XSecure_Rsa instance. + * + * @return None. + * + ******************************************************************************/ +static void XSecure_RsaPutData(XSecure_Rsa *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + /* + * Initialize Modular exponentiation + */ + XSecure_RsaWriteMem(InstancePtr, (u32 *)InstancePtr->ModExpo, + XSECURE_CSU_RSA_RAM_EXPO); + + /* + * Initialize Modular. + */ + XSecure_RsaWriteMem(InstancePtr, (u32 *)InstancePtr->Mod, + XSECURE_CSU_RSA_RAM_MOD); + + /* + * Initialize Modular extension (R*R Mod M) + */ + XSecure_RsaWriteMem(InstancePtr, (u32 *)InstancePtr->ModExt, + XSECURE_CSU_RSA_RAM_RES_Y); + + /* + * Initialize Digest + */ + XSecure_RsaWriteMem(InstancePtr, (u32 *)InstancePtr->EncText, + XSECURE_CSU_RSA_RAM_DIGEST); +} + +/*****************************************************************************/ +/** + * + * This function handles the RSA decryption from end to end + * + * @param InstancePtr is a pointer to the XSecure_Rsa instance. + * @param Result is the pointer to decrypted data generated by RSA. + * + * @return XST_SUCCESS if decryption was successful. + * + ******************************************************************************/ +s32 XSecure_RsaDecrypt(XSecure_Rsa *InstancePtr, u8 *Result) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Result != NULL); + + volatile u32 Status = 0x0U; + s32 ErrorCode = XST_SUCCESS; + + /* + * Put Modulus, exponent, Mod extension in RSA RAM + */ + XSecure_RsaPutData(InstancePtr); + + /* + * Initialize MINV values from Mod. + */ + XSecure_RsaMod32Inverse(InstancePtr); + + /* + * Start the RSA operation. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_CONTROL_OFFSET, + XSECURE_CSU_RSA_CONTROL_MASK); + + /* + * Check and wait for status + */ + do + { + Status = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_RSA_STATUS_OFFSET); + + if(XSECURE_CSU_RSA_STATUS_ERROR == + ((u32)Status & XSECURE_CSU_RSA_STATUS_ERROR)) + { + ErrorCode = XST_FAILURE; + goto END; + } + }while(XSECURE_CSU_RSA_STATUS_DONE != + ((u32)Status & XSECURE_CSU_RSA_STATUS_DONE)); + + + /* + * Copy the result + */ + XSecure_RsaGetData(InstancePtr, (u32 *)Result); + +END: + return ErrorCode; +} + +/*****************************************************************************/ +/** + * + * Match the decrypted data with expected data + * + * @param Signature is the pointer to RSA signature for data to be + * authenticated + * @param Hash is the pointer to expected hash data + * @param KeySel is the key source for decryption, can be KUP or device key + * @param HashLen is the length of Hash used. + * + * @return 0 if RSA match succeeded + * 1 if character 1 of padding does not match + * 2 if character 2 of padding does not match + * 3 if FF padding scheme does not match + * 4 if character after FF padding does not match + * 5 T_padding for given SHA algorithm does not match + * 6 if the output hash does not match + * + ******************************************************************************/ +u32 XSecure_RsaCheckPadding(u8 *Signature, u8 *Hash, u32 HashLen) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(Signature != NULL); + Xil_AssertNonvoid(Hash != NULL); + + u8 * Tpadding = (u8 *)XNULL; + u32 Pad = XSECURE_FSBL_SIG_SIZE - 3U - 19U - HashLen; + u8 * PadPtr = Signature; + u32 ii; + u32 ErrorCode = 0U; + + if(XSECURE_HASH_TYPE_SHA3 == HashLen) + { + Tpadding = (u8 *)XSecure_TPadSha3; + } + else + { + Tpadding = (u8 *)XSecure_TPadSha2; + } + + /* + * Re-Create PKCS#1v1.5 Padding + * MSB ----------------------------------------------------------------LSB + * 0x0 || 0x1 || 0xFF(for 202 bytes) || 0x0 || T_padding || SHA256/384 Hash + */ + + if (0x00U != *PadPtr) + { + ErrorCode = 1U; + goto ENDF; + } + PadPtr++; + + if (0x01U != *PadPtr) + { + ErrorCode = 2U; + goto ENDF; + } + PadPtr++; + + for (ii = 0U; ii < Pad; ii++) + { + if (0xFFU != *PadPtr) + { + ErrorCode = 3U; + goto ENDF; + } + PadPtr++; + } + + if (0x00U != *PadPtr) + { + ErrorCode = 4U; + goto ENDF; + } + PadPtr++; + + for (ii = 0U; ii < 19U; ii++) + { + if (*PadPtr != Tpadding[ii]) + { + ErrorCode = 5U; + goto ENDF; + } + PadPtr++; + } + + for (ii = 0U; ii < HashLen; ii++) + { + if (*PadPtr != Hash[ii]) + { + ErrorCode = 6U; + goto ENDF; + } + PadPtr++; + } + +ENDF: + return ErrorCode; +} diff --git a/lib/sw_services/xilsecure/src/xsecure_rsa.h b/lib/sw_services/xilsecure/src/xsecure_rsa.h new file mode 100755 index 00000000..989ef28a --- /dev/null +++ b/lib/sw_services/xilsecure/src/xsecure_rsa.h @@ -0,0 +1,179 @@ +/****************************************************************************** +* +* (c) Copyright 2012 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +*******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xsecure_rsa.h +* +* This file contains hardware interface related information for RSA device +* +* This driver supports the following features: +* +* - RSA 4096 based decryption +* - verification/authentication of decrypted data +* +* Initialization & Configuration +* +* The Rsa driver instance can be initialized +* in the following way: +* +* - XSecure_RsaInitialize(XSecure_Rsa *InstancePtr, u8* EncText, +* u8 *Mod, u8 *ModExt, u8 *ModExpo) +* +* The method used for RSA decryption needs precalculated value off R^2 mod N +* which is generated by bootgen and is present in the signature along with +* modulus and exponent. +* +* @note +* -The format of the public key( modulus, exponent and precalculated +* R^2 mod N should be same as specified by the bootgen +* +* -For matching, PKCS paddding scheme has to be applied in the manner +* specified by the bootgen. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00 ba 10/10/14 Initial release +* +*+* +* +******************************************************************************/ + +#ifndef XSECURE_RSA_H_ +#define XSECURE_RSA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xsecure_hw.h" +#include "xil_assert.h" +#include "xil_io.h" +#include "xstatus.h" +/************************** Constant Definitions ****************************/ + +/** @name Control Register + * + * The Control register (CR) controls the major functions of the device. + * It is used to set the function to be implemented by the RSA device in + * the next iteration. + * + * Control Register Bit Definition + */ +#define XSECURE_CSU_RSA_CONTROL_2048 (0xA0U) /**< RSA 2048 Length Code */ +#define XSECURE_CSU_RSA_CONTROL_4096 (0xC0U) /**< RSA 4096 Length Code */ +#define XSECURE_CSU_RSA_CONTROL_DCA (0x08U) /**< Abort Operation */ +#define XSECURE_CSU_RSA_CONTROL_NOP (0x00U) /**< No Operation */ +#define XSECURE_CSU_RSA_CONTROL_EXP (0x01U) /**< Exponentiation Opcode */ +#define XSECURE_CSU_RSA_CONTROL_EXP_PRE (0x05U) /**< Expo. using R*R mod M */ +#define XSECURE_CSU_RSA_CONTROL_MASK (XSECURE_CSU_RSA_CONTROL_4096 + \ + XSECURE_CSU_RSA_CONTROL_EXP_PRE) +/* @} */ + +/** @name RSA status Register + * + * The Status Register(SR) indicates the current state of RSA device. + * + * Status Register Bit Definition + */ +#define XSECURE_CSU_RSA_STATUS_DONE (0x1U) /**< Operation Done */ +#define XSECURE_CSU_RSA_STATUS_BUSY (0x2U) /**< RSA busy */ +#define XSECURE_CSU_RSA_STATUS_ERROR (0x4U) /**< Error */ +#define XSECURE_CSU_RSA_STATUS_PROG_CNT (0xF8U) /**< Progress Counter */ +/* @}*/ + +#define XSECURE_CSU_RSA_RAM_EXPO (0U) /**< bit for RSA RAM Exponent */ +#define XSECURE_CSU_RSA_RAM_MOD (1U) /**< bit for RSA RAM modulus */ +#define XSECURE_CSU_RSA_RAM_DIGEST (2U) /**< bit for RSA RAM Digest */ +#define XSECURE_CSU_RSA_RAM_SPAD (3U) /**< bit for RSA RAM SPAD */ +#define XSECURE_CSU_RSA_RAM_RES_Y (4U) /**< bit for RSA RAM Result(Y) */ +#define XSECURE_CSU_RSA_RAM_RES_Q (5U) /**< bit for RSA RAM Result(Q) */ + +#define XSECURE_CSU_RSA_RAM_WORDS (6U) /**< Total Locations in RSA RAM */ + +#define XSECURE_RSA_FAILED 0x1U /**< RSA Failed Error Code */ + +#define XSECURE_HASH_TYPE_SHA3 (48U) /**< SHA-3 hash size */ +#define XSECURE_HASH_TYPE_SHA2 (32U)/**< SHA-2 hash size */ +#define XSECURE_FSBL_SIG_SIZE (512U) /**< FSBL signature size */ + +/***************************** Type Definitions ******************************/ +/** + * The RSA driver instance data structure. A pointer to an instance data + * structure is passed around by functions to refer to a specific driver + * instance. + */ +typedef struct { + u32 BaseAddress; /**< Device Base Address */ + u8* EncText; /**< Data to be Encrypted */ + u8* Mod; /**< Modulus */ + u8* ModExt; /**< Precalc. R sq. mod N */ + u8* ModExpo; /**< Exponent */ +} XSecure_Rsa; + +/***************************** Function Prototypes ***************************/ + +/* + * Initialization + */ +s32 XSecure_RsaInitialize(XSecure_Rsa *InstancePtr, u8* EncText, + u8 *Mod, u8 *ModExt, u8 *ModExpo); + +/* + * RSA Decryption + */ +s32 XSecure_RsaDecrypt(XSecure_Rsa *InstancePtr, u8* Result); + +/* + * RSA Signature Validation, assuming PKCS padding + */ +u32 XSecure_RsaCheckPadding(u8 *Signature, u8 *Hash, u32 HashLen); + +#ifdef __cplusplus +extern "C" } +#endif + +#endif /* XSECURE_RSA_H_ */ diff --git a/lib/sw_services/xilsecure/src/xsecure_sha.c b/lib/sw_services/xilsecure/src/xsecure_sha.c new file mode 100755 index 00000000..25e0626b --- /dev/null +++ b/lib/sw_services/xilsecure/src/xsecure_sha.c @@ -0,0 +1,291 @@ +/****************************************************************************** +* +* (c) Copyright 2014 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +*******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xsecure_sha.c +* +* This file contains the implementation of the interface functions for SHA +* driver. Refer to the header file xsecure_sha.h for more detailed information. +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00 ba 08/10/14 Initial release +* +*+* +* @note +* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "xsecure_sha.h" +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Definitions *****************************/ + +/****************************************************************************/ +/** +* +* Initializes a specific Xsecure_Sha3 instance so that it is ready to be used. +* +* @param InstancePtr is a pointer to the XSecure_Sha3 instance. +* @param CsuDmaPtr is the pointer to the XCsuDma instance. +* +* @return +* +* - XST_SUCCESS if initialization was successful +* +* @note +* +* The base address is initialized directly with value from xsecure_hw.h +* +*****************************************************************************/ + +s32 XSecure_Sha3Initialize(XSecure_Sha3 *InstancePtr, XCsuDma* CsuDmaPtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(CsuDmaPtr != NULL); + + InstancePtr->BaseAddress = XSECURE_CSU_SHA3_BASE; + InstancePtr->Sha3Len = 0U; + InstancePtr->CsuDmaPtr = CsuDmaPtr; + return XST_SUCCESS; +} + +/***************************************************************************** + * + * @param InstancePtr is a pointer to the XSecure_Sha3 instance. + * @param Dst is the pointer to location where padding is to be applied + * @param MsgLen is the length of padding in bytes + * + * @return None + * + ******************************************************************************/ +void XSecure_Sha3Padd(XSecure_Sha3 *InstancePtr, u8 *Dst, u32 MsgLen) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Dst != NULL); + + memset(Dst, 0, MsgLen); + Dst[0] = 0x1U; + Dst[MsgLen -1U] |= 0x80U; +} +/***************************************************************************** + * + * @param InstancePtr is a pointer to the XSecure_Sha3 instance. + * + * @return None + * + ******************************************************************************/ +void XSecure_Sha3Start(XSecure_Sha3 *InstancePtr) +{ + /* + * Asserts validate the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + InstancePtr->Sha3Len = 0U; + + /* + * Reset SHA3 engine. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_SHA3_RESET_OFFSET, + XSECURE_CSU_SHA3_RESET_RESET); + + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_SHA3_RESET_OFFSET, 0U); + + /* + * Configure the SSS for SHA3 hashing. + */ + XSecure_SssSetup(XSecure_SssInputSha3(XSECURE_CSU_SSS_SRC_SRC_DMA)); + + /* + * Start SHA3 engine. + */ + XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_SHA3_START_OFFSET, + XSECURE_CSU_SHA3_START_START); +} + +/***************************************************************************** + * + * @param InstancePtr is a pointer to the XSecure_Sha3 instance. + * @param Data is the pointer to the input data for hashing + * @param The Size of the input data in bytes + * + * @return None + * + ******************************************************************************/ +void XSecure_Sha3Update(XSecure_Sha3 *InstancePtr, const u8 *Data, + const u32 Size) +{ + /* + * Asserts validate the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Data != NULL); + Xil_AssertVoid(Size != (u32)0x00U); + + InstancePtr->Sha3Len += Size; + + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + (u64)Data, (u32)Size/4, 0); + + /* + * Checking the CSU DMA done bit should be enough. + */ + XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL); +} + + +/***************************************************************************** + * + * @param InstancePtr is a pointer to the XSecure_Sha3 instance. + * + * @return None + * + ******************************************************************************/ +void XSecure_Sha3WaitForDone(XSecure_Sha3 *InstancePtr) +{ + /* + * Asserts validate the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + + volatile u32 Status; + + do + { + Status = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_SHA3_DONE_OFFSET); + } while (XSECURE_CSU_SHA3_DONE_DONE != + ((u32)Status & XSECURE_CSU_SHA3_DONE_DONE)); +} + + +/***************************************************************************** + * + * @param InstancePtr is a pointer to the XSecure_Sha3 instance. + * @param Hash is the pointer to location where resulting hash will be + * written + * + * @return None + * + *****************************************************************************/ +void XSecure_Sha3Finish(XSecure_Sha3 *InstancePtr, u8 *Hash) +{ + /* + * Asserts validate the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Hash != NULL); + + u32 *HashPtr = (u32 *)Hash; + u32 PartialLen = InstancePtr->Sha3Len % XSECURE_SHA3_BLOCK_LEN; + u8 XSecure_RsaSha3Array[512] = {0U}; + + PartialLen = (PartialLen == 0U)?(XSECURE_SHA3_BLOCK_LEN) : + (XSECURE_SHA3_BLOCK_LEN - PartialLen); + + XSecure_Sha3Padd(InstancePtr, XSecure_RsaSha3Array, PartialLen); + + XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, + (u64)XSecure_RsaSha3Array, PartialLen/4, 1); + + /* Check the SHA3 DONE bit. */ + XSecure_Sha3WaitForDone(InstancePtr); + + /* If requested, read out the Hash in reverse order. */ + if (Hash) + { + u32 Index = 0U; + u32 Val = 0U; + for (Index=0U; Index < 12U; Index++) + { + Val = XSecure_ReadReg(InstancePtr->BaseAddress, + XSECURE_CSU_SHA3_DIGEST_0_OFFSET + (Index * 4)); + HashPtr[11U - Index] = Val; + } + } + +} + +/***************************************************************************** + * + * @param InstancePtr is a pointer to the XSecure_Sha3 instance. + * @param In is the pointer to the input data for hashing + * @param Size of the input data + * @param Out is the pointer to location where resulting hash will be written + * + * @return None + * + ******************************************************************************/ +void XSecure_Sha3Digest(XSecure_Sha3 *InstancePtr, const u8 *In, const u32 Size, + u8 *Out) +{ + /* + * Asserts validate the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(In != NULL); + Xil_AssertVoid(Size != (u32)0x00U); + Xil_AssertVoid(Out != NULL); + + XSecure_Sha3Start(InstancePtr); + XSecure_Sha3Update(InstancePtr, In, Size); + XSecure_Sha3Finish(InstancePtr, Out); +} diff --git a/lib/sw_services/xilsecure/src/xsecure_sha.h b/lib/sw_services/xilsecure/src/xsecure_sha.h new file mode 100755 index 00000000..d2662a29 --- /dev/null +++ b/lib/sw_services/xilsecure/src/xsecure_sha.h @@ -0,0 +1,148 @@ +/****************************************************************************** +* +* (c) Copyright 2012 Xilinx, Inc. All rights reserved. +* +* This file contains confidential and proprietary information of Xilinx, Inc. +* and is protected under U.S. and international copyright and other +* intellectual property laws. +* +* DISCLAIMER +* This disclaimer is not a license and does not grant any rights to the +* materials distributed herewith. Except as otherwise provided in a valid +* license issued to you by Xilinx, and to the maximum extent permitted by +* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL +* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, +* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; +* and (2) Xilinx shall not be liable (whether in contract or tort, including +* negligence, or under any other theory of liability) for any loss or damage +* of any kind or nature related to, arising under or in connection with these +* materials, including for any direct, or any indirect, special, incidental, +* or consequential loss or damage (including loss of data, profits, goodwill, +* or any type of loss or damage suffered as a result of any action brought by +* a third party) even if such damage or loss was reasonably foreseeable or +* Xilinx had been advised of the possibility of the same. +* +* CRITICAL APPLICATIONS +* Xilinx products are not designed or intended to be fail-safe, or for use in +* any application requiring fail-safe performance, such as life-support or +* safety devices or systems, Class III medical devices, nuclear facilities, +* applications related to the deployment of airbags, or any other applications +* that could lead to death, personal injury, or severe property or +* environmental damage (individually and collectively, "Critical +* Applications"). Customer assumes the sole risk and liability of any use of +* Xilinx products in Critical Applications, subject only to applicable laws +* and regulations governing limitations on product liability. +* +* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE +* AT ALL TIMES. +* +*******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xsecure_sha.h +* +* This file Contains the function prototypes, defines and macros for +* the SHA-384 hardware module. +* +* This driver supports the following features: +* +* - SHA-3 hash calculation +* +* Initialization & Configuration +* +* The SHA-3 driver instance can be initialized +* in the following way: +* +* - XSecure_Sha3Initialize(XSecure_Sha3 *InstancePtr, XCsuDma *CsuDmaPtr) +* +* A pointer to CsuDma instance has to be passed in initialization as CSU +* DMA will be used for data transfers to SHA module. +* +* +* @note +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00 ba 11/05/14 Initial release +* +*+* +* @note +* +******************************************************************************/ +#ifndef XSECURE_SHA_H +#define XSECURE_SHA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xsecure_hw.h" +#include "../../../include/xcsudma.h" +#include "xil_assert.h" + +/************************** Constant Definitions ****************************/ +/** +* CSU SHA3 Memory Map +*/ +#define XSECURE_CSU_SHA3_START_START (1U << 0) /**< SHA Start Message */ + +#define XSECURE_CSU_SHA3_RESET_RESET (1U << 0) /**< SHA Reset Value */ + +#define XSECURE_CSU_SHA3_DONE_DONE (1U << 0) /**< SHA Done */ + +#define XSECURE_SHA3_BLOCK_LEN (104U) /**< SHA min block length */ + +#define XSECURE_SHA3_LAST_PACKET (0x1U) /**< Last Data Packet */ + +/***************************** Type Definitions******************************/ + +/** + * The SHA-3 driver instance data structure. A pointer to an instance data + * structure is passed around by functions to refer to a specific driver + * instance. + */ +typedef struct { + u32 BaseAddress; /**< Device Base Address */ + XCsuDma *CsuDmaPtr; /**< Pointer to CSU DMA Instance */ + u32 Sha3Len; /**< SHA3 Input Length */ +} XSecure_Sha3; + +/***************************** Function Prototypes ***************************/ +/* + * Initialization + */ +s32 XSecure_Sha3Initialize(XSecure_Sha3 *InstancePtr, XCsuDma *CsuDmaPtr); + +void XSecure_Sha3Start(XSecure_Sha3 *InstancePtr); + +/* + * Data Transfer + */ +void XSecure_Sha3Update(XSecure_Sha3 *InstancePtr, const u8 *Data, + const u32 Size); +void XSecure_Sha3Finish(XSecure_Sha3 *InstancePtr, u8 *Hash); + +/* + * Complete SHA digest calculation + */ +void XSecure_Sha3Digest(XSecure_Sha3 *InstancePtr, const u8 *In, + const u32 Size, u8 *Out); + +/* + * Utility Functions + */ +void XSecure_Sha3Padd(XSecure_Sha3 *InstancePtr, u8 *Dst, u32 MsgLen); +void XSecure_Sha3WaitForDone(XSecure_Sha3 *InstancePtr); + +#ifdef __cplusplus +extern "C" } +#endif + +#endif /** XSECURE_SHA_H */