1238 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1238 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /******************************************************************************/
 | |
| /**
 | |
| * Copyright (c) 2019 - 2022 Xilinx, Inc.  All rights reserved.
 | |
| * SPDX-License-Identifier: MIT
 | |
| ******************************************************************************/
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| * @file xil_util.c
 | |
| *
 | |
| * xil_util.c file contains xil utility functions
 | |
| * Except few functions, most of these functions are wrappers to standard functions.
 | |
| * The standard string functions do not validate the input and that results into
 | |
| * buffer overflows. To avoid it, the wrapper function validates the input and
 | |
| * then passed to standard function. There are few constant time functions
 | |
| * ( xxx_CT() ) which are used to compare the data in constant time.
 | |
| * The constant time functions should be used while comparing secure data
 | |
| * like password, keys which prevent disclosing of the data using
 | |
| * timing analysis.
 | |
| *
 | |
| * <pre>
 | |
| * MODIFICATION HISTORY:
 | |
| *
 | |
| * Ver   Who      Date     Changes
 | |
| * ----- -------- -------- -----------------------------------------------
 | |
| * 6.4   mmd      04/21/19 First release.
 | |
| * 7.2   nava     08/01/20 Updated Xil_WaitForEvent() and Xil_WaitForEvents(()
 | |
| *                         API to use microsecond timeout instead of a free
 | |
| *                         counter.
 | |
| * 7.3   kal      06/30/20 Converted Xil_Ceil macro to API.
 | |
| *       rpo      08/19/20 Added function for read,modify,write
 | |
| *       kal      09/22/20 Changed the param type from const char to const char*
 | |
| *                         to avoid copying key onto stack
 | |
| *       td       10/16/20 Added Xil_Strcpy, Xil_Strcat, Xil_SecureMemCpy and
 | |
| *                         Xil_MemCmp functions
 | |
| * 7.4   am       11/26/20 Added Xil_StrCpyRange function
 | |
| * 7.6   kpt      07/15/21 Added Xil_SecureZeroize function
 | |
| * 7.7   kpt      11/09/21 Added Xil_SMemCmp, Xil_SMemCmp_CT, Xil_SMemCpy,
 | |
| *                         Xil_SMemSet, Xil_SStrCat, Xil_SStrCmp, Xil_SStrCmp_CT
 | |
| *                         Xil_SStrCpy functions
 | |
| *       kpt      11/25/21 Added strnlen function to fix ARMCC compilation
 | |
| *                         failure
 | |
| * 7.7	sk	 01/10/22 Update functions return type and update RetVal variable
 | |
| * 			  data type to fix misra_c_2012_directive_4_6 misrac
 | |
| * 			  violations.
 | |
| * 7.7	sk	 01/10/22 Update values from signed to unsigned to fix
 | |
| * 			  misra_c_2012_rule_10_4 violation.
 | |
| * 7.7	sk	 01/10/22 Add explicit parentheses to fix misra_c_2012_rule_12_1
 | |
| * 			  violation.
 | |
| * 7.7	sk	 01/10/22 Typecast character strings to u8 to fix misra_c_2012_rule_
 | |
| * 			  10_3 violation.
 | |
| * 7.7	sk	 01/10/22 Modify the code to reduce multiple break statements
 | |
| * 			  and fix misra_c_2012_rule_15_4 violation.
 | |
| * 7.7	sk	 01/10/22 Modify Xil_SMemCmp_CT and Xil_SMemCmp function argument
 | |
| * 			  type to fix misra_c_2012_rule_8_3 violation.
 | |
| * 7.7	sk	 01/10/22 Update conditional expression to fix misra_c_2012_rule_14_4
 | |
| * 			  violation.
 | |
| *       bm       01/20/22 Fix compilation warnings in Xil_SMemCpy
 | |
| *       mmd      02/28/22 Added Xil_SMemMove function
 | |
| * 7.7	sk	 03/02/22 Add explicit parentheses to fix misra_c_2012_rule_12_1
 | |
| * 			  violation.
 | |
| * 7.7	sk	 03/02/22 Add const qualifier to varaibles to fix misra_c_2012_rule_
 | |
| * 			  11_8 violation.
 | |
| * 7.7	sk	 03/02/22 Typecast expression with unsigned int to fix
 | |
| * 			  misra_c_2012_rule_10_7 violation.
 | |
| * 7.7	sk	 03/02/22 Typecast variables with unsigned or signed to fix misra_c
 | |
| * 			  _2012_rule_10_3 violation.
 | |
| * 7.7	sk	 03/02/22 Add const to unmodified variable to fix misra_c_2012
 | |
| * 			   _rule_8_13 violation.
 | |
| * 7.7	sk	 03/02/22 Typecast the function with void as return type is
 | |
| * 			  not used and fix misra_c_2012_rule_17_7 violation.
 | |
| * 7.7	sk	 03/02/22 Remove increment operations during comparision to
 | |
| * 			  fix misra_c_2012_rule_13_3 violation.
 | |
| * 7.7	sk	 03/02/22 Update values from signed to unsigned to fix
 | |
| * 			  misra_c_2012_rule_10_4 violation.
 | |
| *
 | |
| * </pre>
 | |
| *
 | |
| *****************************************************************************/
 | |
| 
 | |
| /****************************** Include Files *********************************/
 | |
| #include "xil_util.h"
 | |
| #include "sleep.h"
 | |
| 
 | |
| /************************** Constant Definitions ****************************/
 | |
| #define MAX_NIBBLES			8U
 | |
| 
 | |
| /************************** Function Prototypes *****************************/
 | |
| 
 | |
| #ifdef __ARMCC_VERSION
 | |
| /******************************************************************************/
 | |
| /**
 | |
|  *
 | |
|  * This API returns the length of the input string
 | |
|  *
 | |
|  * @param  StartPtr is the pointer to the input string
 | |
|  * @param  StrSize is the maximum length of the input string
 | |
|  *
 | |
|  * @return Returns the length of the input string
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| static size_t strnlen (const char *StartPtr, size_t StrSize)
 | |
| {
 | |
| 	const char *EndPtr = StartPtr;
 | |
| 	size_t StrLen = 0U;
 | |
| 
 | |
| 	EndPtr = memchr(StartPtr, '\0', StrSize);
 | |
| 	if (EndPtr == NULL) {
 | |
| 		StrLen = StrSize;
 | |
| 	}
 | |
| 	else {
 | |
| 		StrLen = (size_t) (EndPtr - StartPtr);
 | |
| 	}
 | |
| 
 | |
| 	return StrLen;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /******************************************************************************/
 | |
| /**
 | |
| * This API ceils the provided float value.
 | |
| *
 | |
| * @param	Value is a float variable which has to ceiled to nearest
 | |
| *		integer.
 | |
| *
 | |
| * @return	Returns ceiled value.
 | |
| *
 | |
| *******************************************************************************/
 | |
| s32 Xil_Ceil(float Value)
 | |
| {
 | |
|     s32 Result = Value;
 | |
| 
 | |
| 	if (Value > Result) {
 | |
|         Result = Result + 1;
 | |
|     }
 | |
| 
 | |
|     return Result;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
|  * Converts the char into the equivalent nibble.
 | |
|  *	Ex: 'a' -> 0xa, 'A' -> 0xa, '9'->0x9
 | |
|  *
 | |
|  * @param   InChar - Input character to be converted to nibble.
 | |
|  *                   Valid characters are between 0-9, a-f, A-F
 | |
|  * @param   Num    - Memory location where nibble is to be stored
 | |
|  *
 | |
|  * @return
 | |
|  *          XST_SUCCESS - Character converted to nibble
 | |
|  *          XST_FAILURE - Invalid input character
 | |
|  *
 | |
|  * @note    None.
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| 
 | |
| u32 Xil_ConvertCharToNibble(u8 InChar, u8 *Num)
 | |
| {
 | |
| 	u32 Status;
 | |
| 
 | |
| 	/* Convert the char to nibble */
 | |
| 	if ((InChar >= (u8)'0') && (InChar <= (u8)'9')) {
 | |
| 		*Num = InChar - (u8)'0';
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 	else if ((InChar >= (u8)'a') && (InChar <= (u8)'f')) {
 | |
| 		*Num = InChar - (u8)'a' + 10U;
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 	else if ((InChar >= (u8)'A') && (InChar <= (u8)'F')) {
 | |
| 		*Num = InChar - (u8)'A' + 10U;
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 	else {
 | |
| 		Status = XST_FAILURE;
 | |
| 	}
 | |
| 
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /*
 | |
|  * Converts the string into the equivalent Hex buffer.
 | |
|  *	Ex: "abc123" -> {0xab, 0xc1, 0x23}
 | |
|  *
 | |
|  * @param   Str - Pointer to string to be converted to Hex.
 | |
|  *                Accepted characters in string are between 0-9, a-f and A-F
 | |
|  * @param   Buf - Pointer to memory location where converted hex values are to
 | |
|  *                be stored.
 | |
|  * @param   Len - Length of input string
 | |
|  *
 | |
|  * @return
 | |
|  *          XST_SUCCESS - Input string is converted to hex
 | |
|  *          XST_FAILURE - Invalid character in inpit string
 | |
|  *
 | |
|  * @note    None.
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| u32 Xil_ConvertStringToHex(const char *Str, u32 *buf, u8 Len)
 | |
| {
 | |
| 	u32 Status = XST_FAILURE;
 | |
| 	u8 ConvertedLen = 0U, index = 0U;
 | |
| 	u8 Nibble[MAX_NIBBLES] = {0U};
 | |
| 	u8 i;
 | |
| 
 | |
| 	while (ConvertedLen < Len) {
 | |
| 		for (i = 0U; i < MAX_NIBBLES; i++) {
 | |
| 			Status = Xil_ConvertCharToNibble((u8)Str[ConvertedLen],
 | |
| 			                                &Nibble[i]);
 | |
| 			ConvertedLen = ConvertedLen +1U;
 | |
| 			if (Status != XST_SUCCESS) {
 | |
| 				/* Error converting char to nibble */
 | |
| 				goto END;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		buf[index] = (((u32)Nibble[0] << (u8)28U) | ((u32)Nibble[1] << (u8)24U) |
 | |
| 		              ((u32)Nibble[2] << (u8)20U) | ((u32)Nibble[3] << (u8)16U) |
 | |
| 		              ((u32)Nibble[4] << (u8)12U) | ((u32)Nibble[5] << (u8)8U)  |
 | |
| 		              ((u32)Nibble[6] << (u8)4U)  | (u32)Nibble[7]);
 | |
| 		index++;
 | |
| 	}
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /*
 | |
|  * Waits for the event
 | |
|  *
 | |
|  * @param   RegAddr   - Address of register to be checked for event(s) occurrence
 | |
|  * @param   EventMask - Mask indicating event(s) to be checked
 | |
|  * @param   Event     - Specific event(s) value to be checked
 | |
|  * @param   Timeout   - Max number of microseconds to wait for an event(s).
 | |
|  *
 | |
|  * @return
 | |
|  *          XST_SUCCESS - On occurrence of the event(s).
 | |
|  *          XST_FAILURE - Event did not occur before counter reaches 0
 | |
|  *
 | |
|  * @note    None.
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| u32 Xil_WaitForEvent(u32 RegAddr, u32 EventMask, u32 Event, u32 Timeout)
 | |
| {
 | |
| 	u32 EventStatus;
 | |
| 	u32 PollCount = Timeout;
 | |
| 	u32 Status = XST_FAILURE;
 | |
| 
 | |
| 	while(PollCount > 0U) {
 | |
| 		EventStatus = Xil_In32(RegAddr) & EventMask;
 | |
| 		if (EventStatus == Event) {
 | |
| 			Status = XST_SUCCESS;
 | |
| 			break;
 | |
| 		}
 | |
| 		PollCount--;
 | |
| 		usleep(1U);
 | |
| 	}
 | |
| 
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| /******************************************************************************/
 | |
| /**
 | |
|  * Waits for the events. Returns on occurrence of first event / timeout.
 | |
|  *
 | |
|  * @param   EventsRegAddr - Address of register to be checked for event(s)
 | |
|  *                          occurrence
 | |
|  * @param   EventsMask - Mask indicating event(s) to be checked
 | |
|  * @param   WaitEvents - Specific event(s) to be checked
 | |
|  * @param   Timeout    - Max number of microseconds to wait for an event(s).
 | |
|  * @param   Events     - Mask of Events occurred returned in memory pointed by
 | |
|  *                       this variable
 | |
|  *
 | |
|  * @return
 | |
|  *          XST_SUCCESS - On occurrence of the event(s).
 | |
|  *          XST_FAILURE - Event did not occur before counter reaches 0
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| u32 Xil_WaitForEvents(u32 EventsRegAddr, u32 EventsMask, u32 WaitEvents,
 | |
| 			 u32 Timeout, u32* Events)
 | |
| {
 | |
| 	u32 EventStatus;
 | |
| 	u32 PollCount = Timeout;
 | |
| 	u32 Status = XST_TIMEOUT;
 | |
| 
 | |
| 	*Events = 0x00;
 | |
| 	do {
 | |
| 		EventStatus = Xil_In32(EventsRegAddr);
 | |
| 		EventStatus &= EventsMask;
 | |
| 		if((EventStatus & WaitEvents) != 0U) {
 | |
| 			Status = XST_SUCCESS;
 | |
| 			*Events = EventStatus;
 | |
| 			break;
 | |
| 		}
 | |
| 		PollCount--;
 | |
| 		usleep(1U);
 | |
| 	}
 | |
| 	while(PollCount > 0U);
 | |
| 
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /******************************************************************************/
 | |
| /**
 | |
|  * Checks whether the passed character is a valid hex digit
 | |
|  *
 | |
|  * @param   Ch - Pointer to the input character
 | |
|  *
 | |
|  * @return
 | |
|  *          XST_SUCCESS	- on valid hex digit
 | |
|  *          XST_FAILURE - on invalid hex digit
 | |
|  *
 | |
|  * @note    None.
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| u32 Xil_IsValidHexChar(const char *Ch)
 | |
| {
 | |
| 	u32 Status = XST_FAILURE;
 | |
| 
 | |
| 	if(NULL == Ch) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 	if (((*Ch >= '0') && (*Ch <='9'))||
 | |
| 		((*Ch >= 'a') && (*Ch <='f'))||
 | |
| 		((*Ch >= 'A') && (*Ch <='F'))) {
 | |
| 
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /******************************************************************************/
 | |
| /**
 | |
|  * Validate the input string contains only hexadecimal characters
 | |
|  *
 | |
|  * @param   HexStr - Pointer to string to be validated
 | |
|  *
 | |
|  * @return
 | |
|  *          XST_SUCCESS	- On valid input hex string
 | |
|  *          XST_INVALID_PARAM - On invalid length of the input string
 | |
|  *          XST_FAILURE	- On non hexadecimal character in string
 | |
|  *
 | |
|  * @note    None
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| u32 Xil_ValidateHexStr(const char *HexStr)
 | |
| {
 | |
| 	u32 Idx;
 | |
| 	u32 Len;
 | |
| 	u32 Status = XST_INVALID_PARAM;
 | |
| 
 | |
| 	if(NULL == HexStr) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	Len = Xil_Strnlen(HexStr, XIL_MAX_HEX_STR_LEN + 1U);
 | |
| 	if (Len > XIL_MAX_HEX_STR_LEN) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	for (Idx = 0U; Idx < Len; Idx++) {
 | |
| 		Status = Xil_IsValidHexChar(&HexStr[Idx]);
 | |
| 		if (Status != XST_SUCCESS) {
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
|  * Converts the string into the equivalent Hex buffer.
 | |
|  *	Ex: "abc123" -> {0xab, 0xc1, 0x23}
 | |
|  *
 | |
|  * @param	Str is a Input String. Will support the lower and upper case values.
 | |
|  * 		Value should be between 0-9, a-f and A-F
 | |
|  * @param	Buf is Output buffer.
 | |
|  * @param	Len of the input string. Should have even values
 | |
|  *
 | |
|  * @return
 | |
|  * 		- XST_SUCCESS no errors occurred.
 | |
|  *		- XST_FAILURE an error when input parameters are not valid
 | |
|  *		- an error when input buffer has invalid values
 | |
|  *
 | |
|  *	TDD Test Cases:
 | |
|  *	---Initialization---
 | |
|  *	Len is odd
 | |
|  *	Len is zero
 | |
|  *	Str is NULL
 | |
|  *	Buf is NULL
 | |
|  *	---Functionality---
 | |
|  *	Str input with only numbers
 | |
|  *	Str input with All values in A-F
 | |
|  *	Str input with All values in a-f
 | |
|  *	Str input with values in a-f, 0-9, A-F
 | |
|  *	Str input with values in a-z, 0-9, A-Z
 | |
|  *	Boundary Cases
 | |
|  *	Memory Bounds of buffer checking
 | |
|  * ****************************************************************************/
 | |
| u32 Xil_ConvertStringToHexBE(const char *Str, u8 *Buf, u32 Len)
 | |
| {
 | |
| 	u32 ConvertedLen;
 | |
| 	u8 LowerNibble = 0U;
 | |
| 	u8 UpperNibble = 0U;
 | |
| 	u32 Status = (u32)XST_FAILURE;
 | |
| 
 | |
| 	if ((Str == NULL) || (Buf == NULL)) {
 | |
| 		Status = (u32)XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	if ((Len == 0U) || ((Len % XIL_SIZE_OF_BYTE_IN_BITS) != 0U)) {
 | |
| 		Status = (u32)XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	if(Len != (strlen(Str) * XIL_SIZE_OF_NIBBLE_IN_BITS)) {
 | |
| 		Status = (u32)XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	ConvertedLen = 0U;
 | |
| 	while (ConvertedLen < (Len / XIL_SIZE_OF_NIBBLE_IN_BITS)) {
 | |
| 		if ((Xil_ConvertCharToNibble(((u8)Str[ConvertedLen]),&UpperNibble)
 | |
| 			== (u32)XST_SUCCESS) && (Xil_ConvertCharToNibble(((u8)Str[ConvertedLen+1U]),
 | |
| 				&LowerNibble) == (u32)XST_SUCCESS)) {
 | |
| 				Buf[ConvertedLen/2U] =
 | |
| 				(UpperNibble << XIL_SIZE_OF_NIBBLE_IN_BITS) |
 | |
| 								LowerNibble;
 | |
| 		}
 | |
| 		else {
 | |
| 			Status = (u32)XST_INVALID_PARAM;
 | |
| 			goto END;
 | |
| 		}
 | |
| 		ConvertedLen += 2U;
 | |
| 	}
 | |
| 	Status = (u32)XST_SUCCESS;
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /******************************************************************************/
 | |
| /**
 | |
|  * Converts the string into the equivalent Hex buffer.
 | |
|  *	Ex: "abc123" -> {0x23, 0xc1, 0xab}
 | |
|  *
 | |
|  * @param   Str - Input String to be converted to hex number in little
 | |
|  *                endian format. Valid characters of input strin are between
 | |
|  *                0-9, a-f and A-F
 | |
|  * @param   Buf - Pointer to memory location where converted hex numbers are to
 | |
|  *                be stored.
 | |
|  * @param   Len - Expected number of output bits
 | |
|  *
 | |
|  * @return
 | |
|  *          XST_SUCCESS - Input string is converted to hex number(s)
 | |
|  *          XST_FAILURE - Invalid input character detected in input string
 | |
|  *
 | |
|  * @note
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| u32 Xil_ConvertStringToHexLE(const char *Str, u8 *Buf, u32 Len)
 | |
| {
 | |
| 	u32 ConvertedLen;
 | |
| 	u8 LowerNibble = 0U;
 | |
| 	u8 UpperNibble = 0U;
 | |
| 	u32 StrIndex;
 | |
| 	u32 Status = XST_FAILURE;
 | |
| 
 | |
| 	if ((NULL == Str) || (NULL == Buf)) {
 | |
| 		Status = XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	if ((Len == 0U) || ((Len % XIL_SIZE_OF_BYTE_IN_BITS) != 0U)) {
 | |
| 		Status = XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	if(Len != (strlen(Str) * XIL_SIZE_OF_NIBBLE_IN_BITS)) {
 | |
| 		Status = XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	StrIndex = (Len / XIL_SIZE_OF_BYTE_IN_BITS) - 1U;
 | |
| 	ConvertedLen = 0U;
 | |
| 	while (ConvertedLen < (Len / XIL_SIZE_OF_NIBBLE_IN_BITS)) {
 | |
| 		if ((Xil_ConvertCharToNibble(((u8)Str[ConvertedLen]),
 | |
| 						&UpperNibble) == XST_SUCCESS) &&
 | |
| 			(Xil_ConvertCharToNibble(((u8)Str[ConvertedLen + 1U]),
 | |
| 						&LowerNibble) == XST_SUCCESS)) {
 | |
| 				Buf[StrIndex] =
 | |
| 				   (UpperNibble << XIL_SIZE_OF_NIBBLE_IN_BITS) |
 | |
| 				   LowerNibble;
 | |
| 				StrIndex = StrIndex - 1U;
 | |
| 		}
 | |
| 		else {
 | |
| 			Status = XST_INVALID_PARAM;
 | |
| 			goto END;
 | |
| 		}
 | |
| 		ConvertedLen += 2U;
 | |
| 	}
 | |
| 
 | |
| 	Status = XST_SUCCESS;
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /******************************************************************************/
 | |
| /**
 | |
|  * Returns the length of input string.
 | |
|  *
 | |
|  * @param   Str - Input string
 | |
|  * @param   MaxLen - Maximum expected length of the input string
 | |
|  *
 | |
|  * @return
 | |
|  *          Returns length of the input string if length is less than MaxLen.
 | |
|  *          Returns MaxLen if the length of the input string is >= MaxLen.
 | |
|  *
 | |
|  * @note
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| u32 Xil_Strnlen(const char *Str, u32 MaxLen)
 | |
| {
 | |
| 	const char *InStr = Str;
 | |
| 	u32 StrLen = 0U;
 | |
| 
 | |
| 	if (NULL == Str) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	while(StrLen < MaxLen) {
 | |
| 		if ('\0' == *InStr) {
 | |
| 			break;
 | |
| 		}
 | |
| 		StrLen++;
 | |
| 		InStr++;
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return StrLen;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function will Read, Modify and Write to an address.
 | |
|  *
 | |
|  * @param	Addr denotes Address
 | |
|  * @param	Mask denotes the bits to be modified
 | |
|  * @param	Value is the value to be written to the address
 | |
|  *
 | |
|  * @return	None
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| void Xil_UtilRMW32(u32 Addr, u32 Mask, u32 Value)
 | |
| {
 | |
| 	u32 Val;
 | |
| 
 | |
| 	Val = Xil_In32(Addr);
 | |
| 	Val = (Val & (~Mask)) | (Mask & Value);
 | |
| 	Xil_Out32(Addr, Val);
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This functions copies source string to destination string. This
 | |
|  * 			function is a safe version of strcpy
 | |
|  *
 | |
|  * @param	DestPtr is pointer to destination string
 | |
|  * @param	SrcPtr is pointer to source string
 | |
|  * @param	Size is the maximum number of bytes of the source string
 | |
|  *			to be copied
 | |
|  *
 | |
|  * @return	XST_SUCCESS on success and error code on failure
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| int Xil_Strcpy(char *DestPtr, const char *SrcPtr, const u32 Size)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u32 Count;
 | |
| 
 | |
| 	if ((SrcPtr == NULL) || (DestPtr == NULL) || (Size == 0U)) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	for (Count = 0U; (SrcPtr[Count] != '\0') && (Count < Size); ++Count) {
 | |
| 		DestPtr[Count] = SrcPtr[Count];
 | |
| 	}
 | |
| 	if (Count == Size) {
 | |
| 		DestPtr[0U] = '\0';
 | |
| 		goto END;
 | |
| 	}
 | |
| 	DestPtr[Count] = '\0';
 | |
| 	Status = XST_SUCCESS;
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
|  * @brief	Copies specified range from source string to destination string
 | |
|  *
 | |
|  * @param	Src  is a pointer to source string
 | |
|  * @param	Dest  is a pointer to destination string
 | |
|  * @param	From is 0 based index from where string copy starts
 | |
|  * @param	To   is 0 based index till which string is copied
 | |
|  * @param	MaxSrcLen is the maximum length of source string
 | |
|  * @param	MaxDstLen is the maximum length of destination string
 | |
|  *
 | |
|  * @return	XST_SUCCESS on success
 | |
|  * 		XST_FAILURE on failure
 | |
|  *
 | |
|  * @note	None
 | |
|  *
 | |
|  ****************************************************************************/
 | |
| int Xil_StrCpyRange(const u8 *Src, u8 *Dest, u32 From, u32 To, u32 MaxSrcLen,
 | |
| 	u32 MaxDstLen)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u32 SrcLength;
 | |
| 	u32 Index;
 | |
| 
 | |
| 	if ((Src == NULL) || (Dest == NULL)) {
 | |
| 		Status = XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	if ((To >= MaxSrcLen) || (To < From)) {
 | |
| 		Status = XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	if ((To - From + 1U) >= MaxDstLen) {
 | |
| 		Status = XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	SrcLength = Xil_Strnlen((const char *)Src, MaxSrcLen);
 | |
| 	if (To >= SrcLength) {
 | |
| 		Status = XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	for (Index = From; (Index <= To) && (Src[Index]!= (u8)'\0'); Index++) {
 | |
| 		Dest[Index - From] = Src[Index];
 | |
| 	}
 | |
| 
 | |
| 	Dest[Index - From] = (u8)'\0';
 | |
| 	Status = XST_SUCCESS;
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function appends string2 to string1. This function is a safe
 | |
|  * 			version of strcat
 | |
|  *
 | |
|  * @param	Str1Ptr is pointer to string1
 | |
|  * @param	Str2Ptr is pointer to string2
 | |
|  * @param	Size is the maximum number of bytes Str1 can hold
 | |
|  *
 | |
|  * @return	XST_SUCCESS on success and error code on failure
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| int Xil_Strcat(char* Str1Ptr, const char* Str2Ptr, const u32 Size)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u32 Count = 0U;
 | |
| 	u32 CountTmp = 0U;
 | |
| 
 | |
| 	if ((Str1Ptr == NULL) || (Str2Ptr == NULL) || (Size == 0U)) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	while ((Count < Size) && (Str1Ptr[Count] != '\0')) {
 | |
| 		Count++;
 | |
| 	}
 | |
| 
 | |
| 	while ((Str2Ptr[CountTmp] != '\0') && (Count < Size)) {
 | |
| 		Str1Ptr[Count] = Str2Ptr[CountTmp];
 | |
| 		Count++;
 | |
| 		CountTmp++;
 | |
| 	}
 | |
| 	if (Count == Size) {
 | |
| 		Str1Ptr[0U] = '\0';
 | |
| 		goto END;
 | |
| 	}
 | |
| 	Str1Ptr[Count] = '\0';
 | |
| 	Status = XST_SUCCESS;
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function copies Len bytes from source memory to destination
 | |
|  *			memory. If Len is greater than DestPtrLen, then DestPtr is also
 | |
|  *			filled with 0s till DestPtrLen bytes and is considered as a failure.
 | |
|  *			This function is a secure implementation of memcpy
 | |
|  *
 | |
|  * @param	DestPtr is pointer to destination address
 | |
|  * @param	DestPtrLen is the memory alloted to the destination buffer
 | |
|  * @param	SrcPtr is pointer to source address
 | |
|  * @param	Len is number of bytes to be copied
 | |
|  *
 | |
|  * @return	XST_SUCCESS on success and error code on failure
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| int Xil_SecureMemCpy(void * DestPtr, u32 DestPtrLen, const void * SrcPtr, u32 Len)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u8 *Dest = (u8 *)DestPtr;
 | |
| 	const u8 *Src = (const u8 *)SrcPtr;
 | |
| 
 | |
| 	if ((DestPtr == NULL) || (SrcPtr == NULL)) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	if (Len > DestPtrLen) {
 | |
| 		while (DestPtrLen != 0U) {
 | |
| 			*Dest = 0U;
 | |
| 			Dest++;
 | |
| 			DestPtrLen--;
 | |
| 		}
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	/* Loop and copy.  */
 | |
| 	while (Len != 0U) {
 | |
| 		*Dest = *Src;
 | |
| 		Dest++;
 | |
| 		Src++;
 | |
| 		Len--;
 | |
| 	}
 | |
| 	Status = XST_SUCCESS;
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function compares Len bytes from memory1 and memory2. This
 | |
|  * 			function is a secure implementation of memcmp
 | |
|  *
 | |
|  * @param	Buf1Ptr is pointer to memory1
 | |
|  * @param	Buf2Ptr is pointer to memory2
 | |
|  * @param	Len is number of byets to be compared
 | |
|  *
 | |
|  * @return	0 if contents of both the memory regions are same,
 | |
|  * 			-1 if first non-matching character has lower value in Buf1Ptr
 | |
|  * 			1 if first non-matching character is greater value in Buf1Ptr
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| int Xil_MemCmp(const void * Buf1Ptr, const void * Buf2Ptr, u32 Len)
 | |
| {
 | |
| 	volatile int RetVal = 1;
 | |
| 	const u8 *Buf1 = Buf1Ptr;
 | |
| 	const u8 *Buf2 = Buf2Ptr;
 | |
| 	u32 Size = Len;
 | |
| 
 | |
| 	/* Assert validates the input arguments */
 | |
| 	if ((Buf1 == NULL) || (Buf2 == NULL) || (Len == 0x0U)) {
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	/* Loop and compare */
 | |
| 	while (Size != 0U) {
 | |
| 		if (*Buf1 > *Buf2) {
 | |
| 			RetVal = 1;
 | |
| 			goto END;
 | |
| 		} else if (*Buf1 < *Buf2) {
 | |
| 			RetVal = -1;
 | |
| 			goto END;
 | |
| 		} else {
 | |
| 			Buf1++;
 | |
| 			Buf2++;
 | |
| 			Size--;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* Make sure size is zero to know the whole of data is compared */
 | |
| 	if (Size == 0U) {
 | |
| 		RetVal = 0;
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return RetVal;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function is used to zeroize the memory
 | |
|  *
 | |
|  * @param	DataPtr Pointer to the memory which need to be zeroized.
 | |
|  * @param	Length	Length of the data in bytes.
 | |
|  *
 | |
|  * @return
 | |
|  *		- XST_SUCCESS: If Zeroization is successful.
 | |
|  *		- XST_FAILURE: If Zeroization is not successful.
 | |
|  ********************************************************************************/
 | |
| int Xil_SecureZeroize(u8 *DataPtr, const u32 Length)
 | |
| {
 | |
| 	u32 Index;
 | |
| 	int Status = XST_FAILURE;
 | |
| 
 | |
| 	/* Clear the data */
 | |
| 	(void)memset(DataPtr, 0, Length);
 | |
| 
 | |
| 	/* Read it back to verify */
 | |
| 	 for (Index = 0U; Index < Length; Index++) {
 | |
| 		if (DataPtr[Index] != 0x00U) {
 | |
| 			goto END;
 | |
| 		}
 | |
| 	}
 | |
| 	if (Index == Length) {
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function compares two memory regions for specified number
 | |
|  *		of bytes. This function takes size of two memory regions to
 | |
|  *		make sure not to read from or write to out of bound memory
 | |
|  *		region.
 | |
|  *
 | |
|  * @param	Src1     - Pointer to first memory range
 | |
|  * @param	Src1Size - Maximum size of first memory range
 | |
|  * @param	Src2     - Pointer to second memory range
 | |
|  * @param	Src2Size - Maximum size of second memory range
 | |
|  * @param	CmpLen   - Number of bytes to be compared
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - If specified number of bytes matches
 | |
|  * 		XST_FAILURE - If there is a mistmatch found during comparison
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SMemCmp(const void *Src1, const u32 Src1Size,
 | |
| 	const void *Src2, const u32 Src2Size, const u32 CmpLen)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 
 | |
| 	if ((Src1 == NULL) || (Src2 == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if ((CmpLen == 0U) || (Src1Size < CmpLen) || (Src2Size < CmpLen)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else {
 | |
| 		Status = memcmp (Src1, Src2, CmpLen);
 | |
| 		if (Status != 0) {
 | |
| 			Status = XST_FAILURE;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function compares two memory regions for specified number
 | |
|  *		of bytes. This function takes size of two memory regions to
 | |
|  *		make sure not to read from or write to out of bound memory
 | |
|  *		region.
 | |
|  *		Note that this function compares till end to make it execute
 | |
|  *		in constant time irrespective of the content of input memory.
 | |
|  *
 | |
|  * @param	Src1     - Pointer to first memory range
 | |
|  * @param	Src1Size - Maximum size of first memory range
 | |
|  * @param	Src2     - Pointer to second memory range
 | |
|  * @param	Src2Size - Maximum size of second memory range
 | |
|  * @param	CmpLen   - Number of bytes to be compared
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - If specified number of bytes matches
 | |
|  * 		XST_FAILURE - If mistmatch
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SMemCmp_CT(const void *Src1, const u32 Src1Size,
 | |
| 	const void *Src2, const u32 Src2Size, const u32 CmpLen)
 | |
| {
 | |
| 	volatile int Status = XST_FAILURE;
 | |
| 	volatile int StatusRedundant = XST_FAILURE;
 | |
| 	volatile u32 Data = 0U;
 | |
| 	volatile u32 DataRedundant = 0xFFFFFFFFU;
 | |
| 	u32 Cnt = CmpLen;
 | |
| 	const u8 *Src_1 = (const u8 *)Src1;
 | |
| 	const u8 *Src_2 = (const u8 *)Src2;
 | |
| 
 | |
| 
 | |
| 	if ((Src1 == NULL) || (Src2 == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if ((CmpLen == 0U) || (Src1Size < CmpLen) || (Src2Size < CmpLen)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else {
 | |
| 		while (Cnt >= sizeof(u32)) {
 | |
| 			Data |= (*(const u32 *)Src_1 ^ *(const u32 *)Src_2);
 | |
| 			DataRedundant &= ~Data;
 | |
| 			Src_1 += sizeof(u32);
 | |
| 			Src_2 += sizeof(u32);
 | |
| 			Cnt -= sizeof(u32);
 | |
| 		}
 | |
| 
 | |
| 		while (Cnt > 0U) {
 | |
| 			Data |= (u32)(*Src_1 ^ *Src_2);
 | |
| 			DataRedundant &= ~Data;
 | |
| 			Src_1++;
 | |
| 			Src_2++;
 | |
| 			Cnt--;
 | |
| 		}
 | |
| 
 | |
| 		if ((Data == 0U) && (DataRedundant == 0xFFFFFFFFU)) {
 | |
| 			Status = XST_SUCCESS;
 | |
| 			StatusRedundant = XST_SUCCESS;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return (Status | StatusRedundant);
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This is wrapper function to memcpy function. This function
 | |
|  *		takes size of two memory regions to make sure not read from
 | |
|  *		or write to out of bound memory region.
 | |
|  *
 | |
|  * @param	Dest      - Pointer to destination memory
 | |
|  * @param	DestSize  - Memory available at destination
 | |
|  * @param	Src       - Pointer to source memory
 | |
|  * @param	SrcSize   - Maximum data that can be copied from source
 | |
|  * @param	CopyLen   - Number of bytes to be copied
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - Copy is successful
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SMemCpy(void *Dest, const u32 DestSize,
 | |
| 	const void *Src, const u32 SrcSize, const u32 CopyLen)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	const u8 *Src8 = (const u8 *) Src;
 | |
| 	const u8 *Dst8 = (u8 *) Dest;
 | |
| 	void * volatile DestTemp = Dest;
 | |
| 	const void * volatile SrcTemp = Src;
 | |
| 
 | |
| 	if ((Dest == NULL) || (Src == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if ((CopyLen == 0U) || (DestSize < CopyLen) || (SrcSize < CopyLen)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	/* Return error for overlap string */
 | |
| 	else if ((Src8 < Dst8) && (&Src8[CopyLen - 1U] >= Dst8)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if ((Dst8 < Src8) && (&Dst8[CopyLen - 1U] >= Src8)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else {
 | |
| 		(void)memcpy(DestTemp, SrcTemp, CopyLen);
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This is wrapper function to memset function. This function
 | |
|  *		writes specified byte to destination specified number of times.
 | |
|  *		This function also takes maximum string size that destination
 | |
|  *		holds to make sure not to write out of bound area.
 | |
|  *
 | |
|  * @param	Dest     - Pointer to destination memory
 | |
|  * @param	DestSize - Memory available at destination
 | |
|  * @param	Data     - Any value from 0 to 255
 | |
|  * @param	Len      - Number of bytes to be copied
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - Copy is successful
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SMemSet(void *Dest, const u32 DestSize,
 | |
| 	const u8 Data, const u32 Len)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 
 | |
| 	if ((Dest == NULL) || (DestSize < Len) || (Len == 0U)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else {
 | |
| 		(void)memset(Dest, (s32)Data, Len);
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function concatenates two strings. This function
 | |
|  *		takes size of both strings to make sure not to read from /
 | |
|  *		write to out of bound area.
 | |
|  *
 | |
|  * @param	DestStr  - Pointer to destination string
 | |
|  * @param	DestSize - Maximum string size that detination can hold
 | |
|  * @param	SrcStr   - Pointer to source string
 | |
|  * @param	SrcSize  - Maximum string size that source can hold
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - Copy is successful
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SStrCat (u8 *DestStr, const u32 DestSize,
 | |
| 	const u8 *SrcStr, const u32 SrcSize)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u32 SrcLen;
 | |
| 	u32 DstLen;
 | |
| 
 | |
| 	if ((DestStr == NULL) || (SrcStr == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	SrcLen = strnlen((const char*)SrcStr, SrcSize);
 | |
| 	DstLen = strnlen((const char*)DestStr, DestSize);
 | |
| 
 | |
| 	if ((DestSize <= DstLen) || (SrcSize <= SrcLen)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if (DestSize <= (SrcLen + DstLen)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else {
 | |
| 		(void)strcat((char*)DestStr, (const char*)SrcStr);
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function compares two strings. It also takes maximum string
 | |
|  *		size that Src1 and Src2 can hold to make sure not to read out of
 | |
|  *		bound data for comparison.
 | |
|  *
 | |
|  * @param	Str1     - Pointer to first string
 | |
|  * @param	Str1Size - Maximum string size that Str1 can hold
 | |
|  * @param	Str2     - Pointer to second string
 | |
|  * @param	Str2Size - Maximum string size that Str2 can hold
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - If both strings are same
 | |
|  *		XST_FAILURE - If there is difference between two strings
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SStrCmp(const u8 *Str1, const u32 Str1Size,
 | |
| 	const u8 *Str2, const u32 Str2Size)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u32 Str1Len = 0U;
 | |
| 	u32 Str2Len = 0U;
 | |
| 
 | |
| 	if ((Str1 == NULL) || (Str2 == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	Str1Len = strnlen((const char*)Str1, Str1Size);
 | |
| 	Str2Len = strnlen((const char*)Str2, Str2Size);
 | |
| 
 | |
| 	if ((Str1Size <= Str1Len) || (Str2Size <= Str2Len)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if ((Str1Len < Str2Len) || (Str1Len > Str2Len)) {
 | |
| 		Status = XST_FAILURE;
 | |
| 	}
 | |
| 	else {
 | |
| 		Status = memcmp(Str1, Str2, Str1Len);
 | |
| 		if (Status != 0) {
 | |
| 			Status = XST_FAILURE;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function compares two strings. It also takes maximum string
 | |
|  *		size that Src1 and Src2 can hold to make sure not to read out of
 | |
|  *		bound data for comparison. This function compares each character
 | |
|  *		of the strings so that execution time of the function is not
 | |
|  *		dependent on the content of two input strings. The execution
 | |
|  *		time is constant when string size are same.
 | |
|  *
 | |
|  * @param	Str1     - Pointer to first string
 | |
|  * @param	Str1Size - Maximum string size that Str1 can hold
 | |
|  * @param	Str2     - Pointer to second string
 | |
|  * @param	Str2Size - Maximum string size that Str2 can hold
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - If both strings are same
 | |
|  *		XST_FAILURE - If there is difference between two strings
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SStrCmp_CT (const u8 *Str1, const u32 Str1Size,
 | |
| 	const u8 *Str2, const u32 Str2Size)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u32 Str1Len = 0U;
 | |
| 	u32 Str2Len = 0U;
 | |
| 
 | |
| 	if ((Str1 == NULL) || (Str2 == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	Str1Len = strnlen((const char*)Str1, Str1Size);
 | |
| 	Str2Len = strnlen((const char*)Str2, Str2Size);
 | |
| 
 | |
| 	if ((Str1Size <= Str1Len) || (Str2Size <= Str2Len)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if (Str1Len != Str2Len) {
 | |
| 		Status = XST_FAILURE;
 | |
| 	}
 | |
| 	else {
 | |
| 		Status = Xil_SMemCmp_CT (Str1, Str1Size, Str2, Str2Size, Str1Len);
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This function copies one string to other. This function
 | |
|  *		takes size of both strings to make sure not to read from /
 | |
|  *		write to out of bound area.
 | |
|  *
 | |
|  * @param	DestStr  - Pointer to destination string
 | |
|  * @param	DestSize - Maximum string size that detination can hold
 | |
|  * @param	SrcStr   - Pointer to source string
 | |
|  * @param	SrcSize  - Maximum string size that source can hold
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - Copy is successful
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SStrCpy(u8 *DestStr, const u32 DestSize,
 | |
| 	const u8 *SrcStr, const u32 SrcSize)
 | |
| {
 | |
| 	int Status = XST_FAILURE;
 | |
| 	u32 SrcLen = 0U;
 | |
| 
 | |
| 	if ((DestStr == NULL) || (SrcStr == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 		goto END;
 | |
| 	}
 | |
| 
 | |
| 	SrcLen = strnlen((const char*)SrcStr, SrcSize);
 | |
| 
 | |
| 	if ((DestSize <= SrcLen) || (SrcSize <= SrcLen)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else {
 | |
| 		(void)memcpy(DestStr, SrcStr, SrcLen + 1U);
 | |
| 		Status = XST_SUCCESS;
 | |
| 	}
 | |
| 
 | |
| END:
 | |
| 	return Status;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /**
 | |
|  * @brief	This is wrapper function to memmove function. This function
 | |
|  *		takes size of two memory regions to avoid out of bound memory region.
 | |
|  *
 | |
|  * @param	Dest      - Pointer to destination memory
 | |
|  * @param	DestSize  - Memory available at destination
 | |
|  * @param	Src       - Pointer to source memory
 | |
|  * @param	SrcSize   - Maximum data that can be copied from source
 | |
|  * @param	CopyLen   - Number of bytes to be copied
 | |
|  *
 | |
|  * @return
 | |
|  *		XST_SUCCESS - Copy is successful
 | |
|  * 		XST_INVALID_PARAM - Invalid inputs
 | |
|  *
 | |
|  *****************************************************************************/
 | |
| int Xil_SMemMove(void *Dest, const u32 DestSize,
 | |
| 	const void *Src, const u32 SrcSize, const u32 CopyLen)
 | |
| {
 | |
| 	volatile int Status = XST_FAILURE;
 | |
| 	void *Output = NULL;
 | |
| 
 | |
| 	if ((Dest == NULL) || (Src == NULL)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else if ((CopyLen == 0U) || (DestSize < CopyLen) || (SrcSize < CopyLen)) {
 | |
| 		Status =  XST_INVALID_PARAM;
 | |
| 	}
 | |
| 	else {
 | |
| 		Output = memmove(Dest, Src, CopyLen);
 | |
| 		if (Output != NULL) {
 | |
| 			Status = XST_SUCCESS;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return Status;
 | |
| } |