1 /* misc.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21 /*
22
23 DESCRIPTION
24 This module implements the arithmetic-shift right, left, byte swapping, XOR,
25 masking and clearing memory logic.
26
27 */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <wolfssl/wolfcrypt/settings.h>
33
34 #ifndef WOLF_CRYPT_MISC_C
35 #define WOLF_CRYPT_MISC_C
36
37 #include <wolfssl/wolfcrypt/misc.h>
38
39 /* inlining these functions is a huge speed increase and a small size decrease,
40 because the functions are smaller than function call setup/cleanup, e.g.,
41 md5 benchmark is twice as fast with inline. If you don't want it, then
42 define NO_INLINE and compile this file into wolfssl, otherwise it's used as
43 a source header
44 */
45
46 #ifdef NO_INLINE
47 #define WC_STATIC
48 #else
49 #define WC_STATIC static
50 #endif
51
52 /* Check for if compiling misc.c when not needed. */
53 #if !defined(WOLFSSL_MISC_INCLUDED) && !defined(NO_INLINE)
54 #ifndef WOLFSSL_IGNORE_FILE_WARN
55 #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined)
56 #endif
57
58 #else
59
60
61 #if defined(__ICCARM__)
62 #include <intrinsics.h>
63 #endif
64
65
66 #ifdef INTEL_INTRINSICS
67
68 #include <stdlib.h> /* get intrinsic definitions */
69
70 /* for non visual studio probably need no long version, 32 bit only
71 * i.e., _rotl and _rotr */
72 #pragma intrinsic(_lrotl, _lrotr)
73
rotlFixed(word32 x,word32 y)74 WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
75 {
76 return y ? _lrotl(x, y) : x;
77 }
78
rotrFixed(word32 x,word32 y)79 WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
80 {
81 return y ? _lrotr(x, y) : x;
82 }
83
84 #elif defined(__CCRX__)
85
86 #include <builtin.h> /* get intrinsic definitions */
87
88 #if !defined(NO_INLINE)
89
90 #define rotlFixed(x, y) _builtin_rotl(x, y)
91
92 #define rotrFixed(x, y) _builtin_rotr(x, y)
93
94 #else /* create real function */
95
rotlFixed(word32 x,word32 y)96 WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
97 {
98 return _builtin_rotl(x, y);
99 }
100
rotrFixed(word32 x,word32 y)101 WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
102 {
103 return _builtin_rotr(x, y);
104 }
105
106 #endif
107
108 #else /* generic */
109 /* This routine performs a left circular arithmetic shift of <x> by <y> value. */
110
rotlFixed(word32 x,word32 y)111 WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
112 {
113 return (x << y) | (x >> (sizeof(y) * 8 - y));
114 }
115
116 /* This routine performs a right circular arithmetic shift of <x> by <y> value. */
rotrFixed(word32 x,word32 y)117 WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
118 {
119 return (x >> y) | (x << (sizeof(y) * 8 - y));
120 }
121
122 #endif
123
124 #ifdef WC_RC2
125
126 /* This routine performs a left circular arithmetic shift of <x> by <y> value */
rotlFixed16(word16 x,word16 y)127 WC_STATIC WC_INLINE word16 rotlFixed16(word16 x, word16 y)
128 {
129 return (x << y) | (x >> (sizeof(y) * 8 - y));
130 }
131
132
133 /* This routine performs a right circular arithmetic shift of <x> by <y> value */
rotrFixed16(word16 x,word16 y)134 WC_STATIC WC_INLINE word16 rotrFixed16(word16 x, word16 y)
135 {
136 return (x >> y) | (x << (sizeof(y) * 8 - y));
137 }
138
139 #endif /* WC_RC2 */
140
141 /* This routine performs a byte swap of 32-bit word value. */
142 #if defined(__CCRX__) && !defined(NO_INLINE) /* shortest version for CC-RX */
143 #define ByteReverseWord32(value) _builtin_revl(value)
144 #else
ByteReverseWord32(word32 value)145 WC_STATIC WC_INLINE word32 ByteReverseWord32(word32 value)
146 {
147 #ifdef PPC_INTRINSICS
148 /* PPC: load reverse indexed instruction */
149 return (word32)__lwbrx(&value,0);
150 #elif defined(__ICCARM__)
151 return (word32)__REV(value);
152 #elif defined(KEIL_INTRINSICS)
153 return (word32)__rev(value);
154 #elif defined(__CCRX__)
155 return (word32)_builtin_revl(value);
156 #elif defined(WOLF_ALLOW_BUILTIN) && \
157 defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
158 return (word32)__builtin_bswap32(value);
159 #elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
160 defined(__aarch64__)
161 __asm__ volatile (
162 "REV32 %0, %0 \n"
163 : "+r" (value)
164 :
165 );
166 return value;
167 #elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
168 (defined(__thumb__) || defined(__arm__))
169 __asm__ volatile (
170 "REV %0, %0 \n"
171 : "+r" (value)
172 :
173 );
174 return value;
175 #elif defined(FAST_ROTATE)
176 /* 5 instructions with rotate instruction, 9 without */
177 return (rotrFixed(value, 8U) & 0xff00ff00) |
178 (rotlFixed(value, 8U) & 0x00ff00ff);
179 #else
180 /* 6 instructions with rotate instruction, 8 without */
181 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
182 return rotlFixed(value, 16U);
183 #endif
184 }
185 #endif /* __CCRX__ */
186 /* This routine performs a byte swap of words array of a given count. */
ByteReverseWords(word32 * out,const word32 * in,word32 byteCount)187 WC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,
188 word32 byteCount)
189 {
190 word32 count = byteCount/(word32)sizeof(word32), i;
191
192 for (i = 0; i < count; i++)
193 out[i] = ByteReverseWord32(in[i]);
194
195 }
196
197 #if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)
198
199
rotlFixed64(word64 x,word64 y)200 WC_STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)
201 {
202 return (x << y) | (x >> (sizeof(y) * 8 - y));
203 }
204
205
rotrFixed64(word64 x,word64 y)206 WC_STATIC WC_INLINE word64 rotrFixed64(word64 x, word64 y)
207 {
208 return (x >> y) | (x << (sizeof(y) * 8 - y));
209 }
210
211
ByteReverseWord64(word64 value)212 WC_STATIC WC_INLINE word64 ByteReverseWord64(word64 value)
213 {
214 #if defined(WOLF_ALLOW_BUILTIN) && defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
215 return (word64)__builtin_bswap64(value);
216 #elif defined(WOLFCRYPT_SLOW_WORD64)
217 return (word64)((word64)ByteReverseWord32((word32) value)) << 32 |
218 (word64)ByteReverseWord32((word32)(value >> 32));
219 #else
220 value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
221 ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
222 value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
223 ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
224 return rotlFixed64(value, 32U);
225 #endif
226 }
227
228
ByteReverseWords64(word64 * out,const word64 * in,word32 byteCount)229 WC_STATIC WC_INLINE void ByteReverseWords64(word64* out, const word64* in,
230 word32 byteCount)
231 {
232 word32 count = byteCount/(word32)sizeof(word64), i;
233
234 for (i = 0; i < count; i++)
235 out[i] = ByteReverseWord64(in[i]);
236
237 }
238
239 #endif /* WORD64_AVAILABLE && !WOLFSSL_NO_WORD64_OPS */
240
241 #ifndef WOLFSSL_NO_XOR_OPS
242 /* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
243 of wolfssl_words, placing the result in <*r>. */
XorWordsOut(wolfssl_word * r,const wolfssl_word * a,const wolfssl_word * b,word32 n)244 WC_STATIC WC_INLINE void XorWordsOut(wolfssl_word* r, const wolfssl_word* a,
245 const wolfssl_word* b, word32 n)
246 {
247 word32 i;
248
249 for (i = 0; i < n; i++) r[i] = a[i] ^ b[i];
250 }
251
252 /* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
253 counts, placing the result in <*buf>. */
254
xorbufout(void * out,const void * buf,const void * mask,word32 count)255 WC_STATIC WC_INLINE void xorbufout(void*out, const void* buf, const void* mask,
256 word32 count)
257 {
258 if (((wc_ptr_t)out | (wc_ptr_t)buf | (wc_ptr_t)mask | count) %
259 WOLFSSL_WORD_SIZE == 0)
260 XorWordsOut( (wolfssl_word*)out, (wolfssl_word*)buf,
261 (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
262 else {
263 word32 i;
264 byte* o = (byte*)out;
265 byte* b = (byte*)buf;
266 const byte* m = (const byte*)mask;
267
268 for (i = 0; i < count; i++) o[i] = b[i] ^ m[i];
269 }
270 }
271
272 /* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
273 of wolfssl_words, placing the result in <*r>. */
XorWords(wolfssl_word * r,const wolfssl_word * a,word32 n)274 WC_STATIC WC_INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)
275 {
276 word32 i;
277
278 for (i = 0; i < n; i++) r[i] ^= a[i];
279 }
280
281 /* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
282 counts, placing the result in <*buf>. */
283
xorbuf(void * buf,const void * mask,word32 count)284 WC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
285 {
286 if (((wc_ptr_t)buf | (wc_ptr_t)mask | count) % WOLFSSL_WORD_SIZE == 0)
287 XorWords( (wolfssl_word*)buf,
288 (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
289 else {
290 word32 i;
291 byte* b = (byte*)buf;
292 const byte* m = (const byte*)mask;
293
294 for (i = 0; i < count; i++) b[i] ^= m[i];
295 }
296 }
297 #endif
298
299 #ifndef WOLFSSL_NO_FORCE_ZERO
300 /* This routine fills the first len bytes of the memory area pointed by mem
301 with zeros. It ensures compiler optimizations doesn't skip it */
ForceZero(void * mem,word32 len)302 WC_STATIC WC_INLINE void ForceZero(void* mem, word32 len)
303 {
304 volatile byte* z = (volatile byte*)mem;
305
306 #if (defined(WOLFSSL_X86_64_BUILD) || defined(WOLFSSL_AARCH64_BUILD)) \
307 && defined(WORD64_AVAILABLE)
308 volatile word64* w;
309 #ifndef WOLFSSL_UNALIGNED_64BIT_ACCESS
310 word32 l = (sizeof(word64) - ((size_t)z & (sizeof(word64)-1))) &
311 (sizeof(word64)-1);
312
313 if (len < l) l = len;
314 len -= l;
315 while (l--) *z++ = 0;
316 #endif
317 for (w = (volatile word64*)z; len >= sizeof(*w); len -= sizeof(*w))
318 *w++ = 0;
319 z = (volatile byte*)w;
320 #endif
321
322 while (len--) *z++ = 0;
323 }
324 #endif
325
326
327 #ifndef WOLFSSL_NO_CONST_CMP
328 /* check all length bytes for equality, return 0 on success */
ConstantCompare(const byte * a,const byte * b,int length)329 WC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, int length)
330 {
331 int i;
332 int compareSum = 0;
333
334 for (i = 0; i < length; i++) {
335 compareSum |= a[i] ^ b[i];
336 }
337
338 return compareSum;
339 }
340 #endif
341
342
343 #ifndef WOLFSSL_HAVE_MIN
344 #define WOLFSSL_HAVE_MIN
345 #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */
346 #define min min
347 #endif
348 /* returns the smaller of a and b */
min(word32 a,word32 b)349 WC_STATIC WC_INLINE word32 min(word32 a, word32 b)
350 {
351 return a > b ? b : a;
352 }
353 #endif /* !WOLFSSL_HAVE_MIN */
354
355 #ifndef WOLFSSL_HAVE_MAX
356 #define WOLFSSL_HAVE_MAX
357 #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */
358 #define max max
359 #endif
max(word32 a,word32 b)360 WC_STATIC WC_INLINE word32 max(word32 a, word32 b)
361 {
362 return a > b ? a : b;
363 }
364 #endif /* !WOLFSSL_HAVE_MAX */
365
366 #ifndef WOLFSSL_NO_INT_ENCODE
367 /* converts a 32 bit integer to 24 bit */
c32to24(word32 in,word24 out)368 WC_STATIC WC_INLINE void c32to24(word32 in, word24 out)
369 {
370 out[0] = (in >> 16) & 0xff;
371 out[1] = (in >> 8) & 0xff;
372 out[2] = in & 0xff;
373 }
374
375 /* convert 16 bit integer to opaque */
c16toa(word16 wc_u16,byte * c)376 WC_STATIC WC_INLINE void c16toa(word16 wc_u16, byte* c)
377 {
378 c[0] = (wc_u16 >> 8) & 0xff;
379 c[1] = wc_u16 & 0xff;
380 }
381
382 /* convert 32 bit integer to opaque */
c32toa(word32 wc_u32,byte * c)383 WC_STATIC WC_INLINE void c32toa(word32 wc_u32, byte* c)
384 {
385 c[0] = (wc_u32 >> 24) & 0xff;
386 c[1] = (wc_u32 >> 16) & 0xff;
387 c[2] = (wc_u32 >> 8) & 0xff;
388 c[3] = wc_u32 & 0xff;
389 }
390 #endif
391
392 #ifndef WOLFSSL_NO_INT_DECODE
393 /* convert a 24 bit integer into a 32 bit one */
c24to32(const word24 wc_u24,word32 * wc_u32)394 WC_STATIC WC_INLINE void c24to32(const word24 wc_u24, word32* wc_u32)
395 {
396 *wc_u32 = ((word32)wc_u24[0] << 16) | (wc_u24[1] << 8) | wc_u24[2];
397 }
398
399
400 /* convert opaque to 24 bit integer */
ato24(const byte * c,word32 * wc_u24)401 WC_STATIC WC_INLINE void ato24(const byte* c, word32* wc_u24)
402 {
403 *wc_u24 = ((word32)c[0] << 16) | (c[1] << 8) | c[2];
404 }
405
406 /* convert opaque to 16 bit integer */
ato16(const byte * c,word16 * wc_u16)407 WC_STATIC WC_INLINE void ato16(const byte* c, word16* wc_u16)
408 {
409 *wc_u16 = (word16) ((c[0] << 8) | (c[1]));
410 }
411
412 /* convert opaque to 32 bit integer */
ato32(const byte * c,word32 * wc_u32)413 WC_STATIC WC_INLINE void ato32(const byte* c, word32* wc_u32)
414 {
415 *wc_u32 = ((word32)c[0] << 24) | ((word32)c[1] << 16) | (c[2] << 8) | c[3];
416 }
417
418
btoi(byte b)419 WC_STATIC WC_INLINE word32 btoi(byte b)
420 {
421 return (word32)(b - 0x30);
422 }
423 #endif
424
HexCharToByte(char ch)425 WC_STATIC WC_INLINE signed char HexCharToByte(char ch)
426 {
427 signed char ret = (signed char)ch;
428 if (ret >= '0' && ret <= '9')
429 ret -= '0';
430 else if (ret >= 'A' && ret <= 'F')
431 ret -= 'A' - 10;
432 else if (ret >= 'a' && ret <= 'f')
433 ret -= 'a' - 10;
434 else
435 ret = -1; /* error case - return code must be signed */
436 return ret;
437 }
438
ByteToHex(byte in)439 WC_STATIC WC_INLINE char ByteToHex(byte in)
440 {
441 static const char kHexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
442 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
443 return (char)(kHexChar[in & 0xF]);
444 }
445
ByteToHexStr(byte in,char * out)446 WC_STATIC WC_INLINE int ByteToHexStr(byte in, char* out)
447 {
448 if (out == NULL)
449 return -1;
450
451 out[0] = ByteToHex(in >> 4);
452 out[1] = ByteToHex(in & 0xf);
453 return 0;
454 }
455
456 #ifndef WOLFSSL_NO_CT_OPS
457 /* Constant time - mask set when a > b. */
ctMaskGT(int a,int b)458 WC_STATIC WC_INLINE byte ctMaskGT(int a, int b)
459 {
460 return (byte)((((word32)a - b - 1) >> 31) - 1);
461 }
462
463 /* Constant time - mask set when a >= b. */
ctMaskGTE(int a,int b)464 WC_STATIC WC_INLINE byte ctMaskGTE(int a, int b)
465 {
466 return (byte)((((word32)a - b ) >> 31) - 1);
467 }
468
469 /* Constant time - mask set when a >= b. */
ctMaskIntGTE(int a,int b)470 WC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b)
471 {
472 return (int)((((word32)a - b ) >> 31) - 1);
473 }
474
475 /* Constant time - mask set when a < b. */
ctMaskLT(int a,int b)476 WC_STATIC WC_INLINE byte ctMaskLT(int a, int b)
477 {
478 return (byte)((((word32)b - a - 1) >> 31) - 1);
479 }
480
481 /* Constant time - mask set when a <= b. */
ctMaskLTE(int a,int b)482 WC_STATIC WC_INLINE byte ctMaskLTE(int a, int b)
483 {
484 return (byte)((((word32)b - a ) >> 31) - 1);
485 }
486
487 /* Constant time - mask set when a == b. */
ctMaskEq(int a,int b)488 WC_STATIC WC_INLINE byte ctMaskEq(int a, int b)
489 {
490 return (byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b));
491 }
492
493 /* Constant time - sets 16 bit integer mask when a > b */
ctMask16GT(int a,int b)494 WC_STATIC WC_INLINE word16 ctMask16GT(int a, int b)
495 {
496 return (word16)((((word32)a - b - 1) >> 31) - 1);
497 }
498
499 /* Constant time - sets 16 bit integer mask when a >= b */
ctMask16GTE(int a,int b)500 WC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b)
501 {
502 return (word16)((((word32)a - b ) >> 31) - 1);
503 }
504
505 /* Constant time - sets 16 bit integer mask when a < b. */
ctMask16LT(int a,int b)506 WC_STATIC WC_INLINE word16 ctMask16LT(int a, int b)
507 {
508 return (word16)((((word32)b - a - 1) >> 31) - 1);
509 }
510
511 /* Constant time - sets 16 bit integer mask when a <= b. */
ctMask16LTE(int a,int b)512 WC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b)
513 {
514 return (word16)((((word32)b - a ) >> 31) - 1);
515 }
516
517 /* Constant time - sets 16 bit integer mask when a == b. */
ctMask16Eq(int a,int b)518 WC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b)
519 {
520 return (word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b));
521 }
522
523 /* Constant time - mask set when a != b. */
ctMaskNotEq(int a,int b)524 WC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b)
525 {
526 return (byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b);
527 }
528
529 /* Constant time - select a when mask is set and b otherwise. */
ctMaskSel(byte m,byte a,byte b)530 WC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b)
531 {
532 return (byte)((b & ((byte)~(word32)m)) | (a & m));
533 }
534
535 /* Constant time - select integer a when mask is set and integer b otherwise. */
ctMaskSelInt(byte m,int a,int b)536 WC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b)
537 {
538 return (b & (~(signed int)(signed char)m)) |
539 (a & ( (signed int)(signed char)m));
540 }
541
542 /* Constant time - bit set when a <= b. */
ctSetLTE(int a,int b)543 WC_STATIC WC_INLINE byte ctSetLTE(int a, int b)
544 {
545 return (byte)(((word32)a - b - 1) >> 31);
546 }
547 #endif
548
549 #undef WC_STATIC
550
551 #endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */
552
553 #endif /* WOLF_CRYPT_MISC_C */
554