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