1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 
6 /*************************************************************************
7 * 1. Includes
8 *************************************************************************/
9 #include <sys/param.h>
10 #include <stdint.h>
11 #include <stdint.h>
12 #include <string.h>
13 
14 #include "security_utils_hex.h"
15 
16 #ifndef MAX
17 #define MAX(a, b) ((a) > (b) ? (a) : (b))
18 #endif
19 #ifndef MIN
20 #define MIN(a, b) ((a) < (b) ? (a) : (b))
21 #endif
22 
23 
24 /*************************************************************************
25 * 2. Definition of external constants and variables
26 *************************************************************************/
27 
28 /*************************************************************************
29 * 3. File scope types, constants and variables
30 *************************************************************************/
31 static const char SecUtil_HexChars[] = {
32 	'0', '1', '2', '3', '4', '5', '6', '7',
33 	'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
34 };
35 /*************************************************************************
36 * 4. Declaration of file local functions
37 *************************************************************************/
38 
39 /*************************************************************************
40 * 5. Definition of external functions
41 *************************************************************************/
42 #if 0
43 void SecBase_HexPrintBuffer(
44 	const char *Prefix_p,
45 	const char *Postfix_p,
46 	const char *BufferName_p,
47 	const void *Buffer_p,
48 	size_t BufferLength
49 	)
50 {
51 	char LineBuf[67];
52 	size_t LinePos = 0;
53 	const uint8 *Data_p = Buffer_p;
54 	size_t n;
55 	char EmptyString[] = "";
56 
57 	if (Prefix_p == NULL)
58 		Prefix_p = EmptyString;
59 	if (Postfix_p == NULL)
60 		Postfix_p = EmptyString;
61 
62 	if (BufferName_p != NULL) {
63 		DELAY_MS(5);
64 		printf("%s%s: Size: %d%s", Prefix_p, BufferName_p, BufferLength,
65 		       Postfix_p);
66 	}
67 
68 	/* Initialize the line buffer for a new line */
69 	SEC_MEM_SET(LineBuf, ' ', sizeof(LineBuf));
70 	LineBuf[sizeof(LineBuf) - 1] = '\0';
71 	LinePos = 0;
72 	for (n = 0; n < BufferLength; n++) {
73 		char Separator;
74 		char PrintableChar;
75 
76 		if (((n + 1) % 4) == 0)
77 			Separator = ' ';
78 		else
79 			Separator = ':';
80 
81 		if (isprint(Data_p[n]))
82 			PrintableChar = (char)Data_p[n];
83 		else
84 			PrintableChar = '.';
85 
86 		LineBuf[LinePos * 3 + 0] = SecBase_HexChars[Data_p[n] >> 4];
87 		LineBuf[LinePos * 3 + 1] = SecBase_HexChars[Data_p[n] & 0x0F];
88 		LineBuf[LinePos * 3 + 2] = Separator;
89 		LineBuf[50 + LinePos] = PrintableChar;
90 
91 		LinePos++;
92 		if (LinePos == 16) {
93 			DELAY_MS(5);
94 			printf("%s%s%s", Prefix_p, LineBuf, Postfix_p);
95 			/* Initialize the line buffer for a new line */
96 			SEC_MEM_SET(LineBuf, ' ', sizeof(LineBuf));
97 			LineBuf[sizeof(LineBuf) - 1] = '\0';
98 			LinePos = 0;
99 		}
100 	}
101 	if (LinePos != 0) {
102 		DELAY_MS(5);
103 		printf("%s%s%s", Prefix_p, LineBuf, Postfix_p);
104 	}
105 	(void)fflush(stdout);
106 }
107 #endif
108 
109 #if 0
110 void SecUtil_CHexPrintBuffer(
111 	const char *Prefix_p,
112 	const char *Postfix,
113 	const void *Buffer_p,
114 	size_t BufferLength
115 	)
116 {
117 	char LineBuf[84];
118 	const uint8 *Data_p = Buffer_p;
119 	size_t n;
120 	char EmptyString[] = "";
121 	static const SecUtil_HexFormat_t HexFormat = { "0x", ", ", ", " };
122 
123 	if (Prefix_p == NULL)
124 		Prefix_p = EmptyString;
125 	if (Postfix == NULL)
126 		Postfix = EmptyString;
127 
128 	for (n = 0; n < BufferLength; n += 16) {
129 		(void)SecUtil_BufferToHex(Data_p + n, MIN(16, BufferLength - n),
130 					  &HexFormat,
131 					  LineBuf, sizeof(LineBuf));
132 		DELAY_MS(5);
133 		printf("%s%s%s", Prefix_p, LineBuf, Postfix);
134 	}
135 }
136 #endif
137 
SecUtil_BufferToHex(const void * const Buffer_p,size_t BufferLength,const SecUtil_HexFormat_t * const HexFormat_p,char * const Destination_p,const size_t DestinationLength)138 size_t SecUtil_BufferToHex(
139 	const void *const Buffer_p,
140 	size_t BufferLength,
141 	const SecUtil_HexFormat_t *const HexFormat_p,
142 	char *const Destination_p,
143 	const size_t DestinationLength
144 	)
145 {
146 	const uint8_t *Data_p = Buffer_p;
147 	size_t UsedDestLength = 0;
148 	size_t n = 0;
149 	const char *ByteSeparator_p = NULL;
150 	const char *GroupSeparator_p = NULL;
151 	const char *BytePrefix_p = NULL;
152 	size_t BytePrefixLength = 0;
153 
154 	if (DestinationLength > 1)
155 		Destination_p[0] = '\0';
156 
157 	UsedDestLength = 1;
158 
159 	if (HexFormat_p != NULL) {
160 		BytePrefix_p = HexFormat_p->BytePrefix_p;
161 		ByteSeparator_p = HexFormat_p->ByteSeparator_p;
162 		GroupSeparator_p = HexFormat_p->GroupSeparator_p;
163 	}
164 
165 	if (BytePrefix_p == NULL)
166 		BytePrefix_p = "";
167 
168 	BytePrefixLength = strlen(BytePrefix_p);
169 
170 	if (ByteSeparator_p == NULL)
171 		ByteSeparator_p = ":";
172 
173 	if (GroupSeparator_p == NULL)
174 		GroupSeparator_p = " ";
175 
176 	/*
177 	 * This for loop is unnecessarily complicated due to
178 	 * the absense of both snprintf and strlcat
179 	 */
180 	for (n = 0; n < BufferLength; n++) {
181 		const char *Separator_p = NULL;
182 		size_t SeparatorLength = 0;
183 
184 		/* Establish separator for this byte and the next */
185 		if (n == BufferLength - 1)
186 			Separator_p = "";
187 		else if ((n + 1) % 4 == 0)
188 			Separator_p = GroupSeparator_p;
189 		else
190 			Separator_p = ByteSeparator_p;
191 
192 		SeparatorLength = strlen(Separator_p);
193 
194 		/* Insert the Byte prefix */
195 		if (UsedDestLength < DestinationLength) {
196 			size_t CopyLength = 0;
197 
198 			CopyLength = MIN(BytePrefixLength,
199 					 DestinationLength - UsedDestLength);
200 			memcpy(Destination_p + UsedDestLength - 1, BytePrefix_p,
201 			       CopyLength);
202 			Destination_p[UsedDestLength - 1 + CopyLength] = '\0';
203 		}
204 		UsedDestLength += BytePrefixLength;
205 
206 		/* Insert the first nibble of the ASCII hexadecimal byte */
207 		if (UsedDestLength < DestinationLength) {
208 			Destination_p[UsedDestLength -
209 				      1] = SecUtil_HexChars[Data_p[n] >> 4];
210 			Destination_p[UsedDestLength] = '\0';
211 		}
212 		UsedDestLength++;
213 
214 		/* Insert the second nibble of the ASCII hexadecimal byte */
215 		if (UsedDestLength < DestinationLength) {
216 			Destination_p[UsedDestLength -
217 				      1] = SecUtil_HexChars[Data_p[n] & 0x0F];
218 			Destination_p[UsedDestLength] = '\0';
219 		}
220 		UsedDestLength++;
221 
222 		/* Insert the separator */
223 		if (UsedDestLength < DestinationLength) {
224 			size_t CopyLength = 0;
225 
226 			CopyLength = MIN(SeparatorLength,
227 					 DestinationLength - UsedDestLength);
228 			memcpy(Destination_p + UsedDestLength - 1, Separator_p,
229 			       CopyLength);
230 			Destination_p[UsedDestLength - 1 + CopyLength] = '\0';
231 		}
232 		UsedDestLength += SeparatorLength;
233 	}
234 	return UsedDestLength;
235 }
236 
237 /*************************************************************************
238 * 6. Definition of internal functions
239 *************************************************************************/
240