xref: /freebsd/crypto/libecc/src/utils/utils.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1 /*
2  *  Copyright (C) 2017 - This file is part of libecc project
3  *
4  *  Authors:
5  *      Ryad BENADJILA <ryadbenadjila@gmail.com>
6  *      Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7  *      Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8  *
9  *  Contributors:
10  *      Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11  *      Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12  *
13  *  This software is licensed under a dual BSD and GPL v2 license.
14  *  See LICENSE file at the root folder of the project.
15  */
16 #include <libecc/utils/utils.h>
17 
18 /*
19  * Return 1 in 'check' if first 'len' bytes of both buffers a and b are equal, 0 otherwise.
20  * It returns 0 if success, -1 on error. 'check' is only relevant on success.
21  *
22  * The test is done in constant time.
23  */
are_equal(const void * a,const void * b,u32 len,int * check)24 int are_equal(const void *a, const void *b, u32 len, int *check)
25 {
26 	const u8 *la = (const u8*)a, *lb = (const u8*)b;
27 	int ret;
28 	u32 i;
29 
30 	MUST_HAVE((a != NULL) && (b != NULL) && (check != NULL), ret, err);
31 
32 	*check = 1;
33 	for (i = 0; i < len; i++) {
34 		(*check) &= (*la == *lb);
35 		la++;
36 		lb++;
37 	}
38 
39 	ret = 0;
40 
41 err:
42 	return ret;
43 }
44 
45 /*
46  * This function is a simple (non-optimized) reimplementation of memcpy()
47  * Returns 0 on success, -1 on error.
48  */
local_memcpy(void * dst,const void * src,u32 n)49 int local_memcpy(void *dst, const void *src, u32 n)
50 {
51 	const u8 *lsrc = (const u8*)src;
52 	u8 *ldst = (u8*)dst;
53 	u32 i;
54 	int ret;
55 
56 	MUST_HAVE((dst != NULL) && (src != NULL), ret, err);
57 
58 	for (i = 0; i < n; i++) {
59 		*ldst = *lsrc;
60 		ldst++;
61 		lsrc++;
62 	}
63 
64 	ret = 0;
65 
66 err:
67 	return ret;
68 }
69 
70 /*
71  * This function is a simple (non-optimized) reimplementation of memset()
72  * Returns 0 on success, -1 on error.
73  */
local_memset(void * v,u8 c,u32 n)74 int local_memset(void *v, u8 c, u32 n)
75 {
76 	volatile u8 *p = (volatile u8*)v;
77 	u32 i;
78 	int ret;
79 
80 	MUST_HAVE((v != NULL), ret, err);
81 
82 	for (i = 0; i < n; i++) {
83 		*p = c;
84 		p++;
85 	}
86 
87 	ret = 0;
88 
89 err:
90 	return ret;
91 }
92 
93 /*
94  * Return 1 in 'check' if strings are equal, 0 otherwise.
95  * It returns 0 if success, -1 on error. 'check' is only relevant on success.
96  *
97  */
are_str_equal(const char * s1,const char * s2,int * check)98 int are_str_equal(const char *s1, const char *s2, int *check)
99 {
100 	const char *ls1 = s1, *ls2 = s2;
101 	int ret;
102 
103 	MUST_HAVE((s1 != NULL) && (s2 != NULL) && (check != NULL), ret, err);
104 
105 	while (*ls1 && (*ls1 == *ls2)) {
106 		ls1++;
107 		ls2++;
108 	}
109 
110 	(*check) = (*ls1 == *ls2);
111 
112 	ret = 0;
113 
114 err:
115 	return ret;
116 }
117 
118 /*
119  * Return 1 in 'check' if strings are equal up to maxlen, 0 otherwise.
120  * It returns 0 if success, -1 on error. 'check' is only relevant on success.
121  *
122  */
are_str_equal_nlen(const char * s1,const char * s2,u32 maxlen,int * check)123 int are_str_equal_nlen(const char *s1, const char *s2, u32 maxlen, int *check)
124 {
125 	const char *ls1 = s1, *ls2 = s2;
126 	u32 i = 0;
127 	int ret;
128 
129 	MUST_HAVE((s1 != NULL) && (s2 != NULL) && (check != NULL), ret, err);
130 
131 	while (*ls1 && (*ls1 == *ls2) && (i < maxlen)) {
132 		ls1++;
133 		ls2++;
134 		i++;
135 	}
136 
137 	(*check) = (*ls1 == *ls2);
138 	ret = 0;
139 
140 err:
141 	return ret;
142 }
143 
144 
145 
146 /*
147  * This function is a simple (non-optimized) reimplementation of strlen()
148  * Returns the lenth in 'len'.
149  * It returns 0 if success, -1 on error. 'len' is only relevant on success.
150  */
local_strlen(const char * s,u32 * len)151 int local_strlen(const char *s, u32 *len)
152 {
153 	u32 i = 0;
154 	int ret;
155 
156 	MUST_HAVE((s != NULL) && (len != NULL), ret, err);
157 
158 	while (s[i]) {
159 		i++;
160 	}
161 	(*len) = i;
162 
163 	ret = 0;
164 
165 err:
166 	return ret;
167 }
168 
169 /*
170  * This function is a simple (non-optimized) reimplementation of strnlen()
171  * Returns the lenth in 'len'.
172  * It returns 0 if success, -1 on error. 'len' is only relevant on success.
173  */
local_strnlen(const char * s,u32 maxlen,u32 * len)174 int local_strnlen(const char *s, u32 maxlen, u32 *len)
175 {
176 	u32 i = 0;
177 	int ret;
178 
179 	MUST_HAVE((s != NULL) && (len != NULL), ret, err);
180 
181 	while ((i < maxlen) && s[i]) {
182 		i++;
183 	}
184 	(*len) = i;
185 
186 	ret = 0;
187 
188 err:
189 	return ret;
190 }
191 
192 /*
193  * This functin is a simple (non-optimized) reimplementation of strncpy()
194  */
local_strncpy(char * dst,const char * src,u32 n)195 int local_strncpy(char *dst, const char *src, u32 n)
196 {
197 	u32 i;
198 	int ret;
199 
200 	MUST_HAVE((dst != NULL) && (src != NULL), ret, err);
201 
202 	for (i = 0; (i < n) && src[i]; i++) {
203 		dst[i] = src[i];
204 	}
205 	for (; i < n; i++) {
206 		dst[i] = 0;
207 	}
208 
209 	ret = 0;
210 err:
211 	return ret;
212 }
213 
214 /*
215  * This functin is a simple (non-optimized) reimplementation of strncat()
216  */
local_strncat(char * dst,const char * src,u32 n)217 int local_strncat(char *dst, const char *src, u32 n)
218 {
219 	u32 dst_len, i;
220 	int ret;
221 
222 	MUST_HAVE((dst != NULL) && (src != NULL), ret, err);
223 
224 	ret = local_strlen(dst, &dst_len); EG(ret, err);
225 	for (i = 0; (i < n) && src[i]; i++) {
226 		dst[dst_len + i] = src[i];
227 	}
228 	dst[dst_len + i] = 0;
229 
230 	ret = 0;
231 err:
232 	return ret;
233 }
234