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