source: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfcrypt/src/misc.c@ 464

Last change on this file since 464 was 464, checked in by coas-nagasima, 3 years ago

WolfSSLとAzure IoT SDKを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.6 KB
Line 
1/* misc.c
2 *
3 * Copyright (C) 2006-2020 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
23DESCRIPTION
24This module implements the arithmetic-shift right, left, byte swapping, XOR,
25masking 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
74 WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
75 {
76 return y ? _lrotl(x, y) : x;
77 }
78
79 WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
80 {
81 return y ? _lrotr(x, y) : x;
82 }
83
84#else /* generic */
85/* This routine performs a left circular arithmetic shift of <x> by <y> value. */
86
87 WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
88 {
89 return (x << y) | (x >> (sizeof(y) * 8 - y));
90 }
91
92/* This routine performs a right circular arithmetic shift of <x> by <y> value. */
93 WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
94 {
95 return (x >> y) | (x << (sizeof(y) * 8 - y));
96 }
97
98#endif
99
100#ifdef WC_RC2
101
102/* This routine performs a left circular arithmetic shift of <x> by <y> value */
103WC_STATIC WC_INLINE word16 rotlFixed16(word16 x, word16 y)
104{
105 return (x << y) | (x >> (sizeof(y) * 8 - y));
106}
107
108
109/* This routine performs a right circular arithmetic shift of <x> by <y> value */
110WC_STATIC WC_INLINE word16 rotrFixed16(word16 x, word16 y)
111{
112 return (x >> y) | (x << (sizeof(y) * 8 - y));
113}
114
115#endif /* WC_RC2 */
116
117/* This routine performs a byte swap of 32-bit word value. */
118WC_STATIC WC_INLINE word32 ByteReverseWord32(word32 value)
119{
120#ifdef PPC_INTRINSICS
121 /* PPC: load reverse indexed instruction */
122 return (word32)__lwbrx(&value,0);
123#elif defined(__ICCARM__)
124 return (word32)__REV(value);
125#elif defined(KEIL_INTRINSICS)
126 return (word32)__rev(value);
127#elif defined(WOLF_ALLOW_BUILTIN) && \
128 defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
129 return (word32)__builtin_bswap32(value);
130#elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
131 defined(__aarch64__)
132 __asm__ volatile (
133 "REV32 %0, %0 \n"
134 : "+r" (value)
135 :
136 );
137 return value;
138#elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
139 (defined(__thumb__) || defined(__arm__))
140 __asm__ volatile (
141 "REV %0, %0 \n"
142 : "+r" (value)
143 :
144 );
145 return value;
146#elif defined(FAST_ROTATE)
147 /* 5 instructions with rotate instruction, 9 without */
148 return (rotrFixed(value, 8U) & 0xff00ff00) |
149 (rotlFixed(value, 8U) & 0x00ff00ff);
150#else
151 /* 6 instructions with rotate instruction, 8 without */
152 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
153 return rotlFixed(value, 16U);
154#endif
155}
156/* This routine performs a byte swap of words array of a given count. */
157WC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,
158 word32 byteCount)
159{
160 word32 count = byteCount/(word32)sizeof(word32), i;
161
162 for (i = 0; i < count; i++)
163 out[i] = ByteReverseWord32(in[i]);
164
165}
166
167#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)
168
169
170WC_STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)
171{
172 return (x << y) | (x >> (sizeof(y) * 8 - y));
173}
174
175
176WC_STATIC WC_INLINE word64 rotrFixed64(word64 x, word64 y)
177{
178 return (x >> y) | (x << (sizeof(y) * 8 - y));
179}
180
181
182WC_STATIC WC_INLINE word64 ByteReverseWord64(word64 value)
183{
184#if defined(WOLF_ALLOW_BUILTIN) && defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
185 return (word64)__builtin_bswap64(value);
186#elif defined(WOLFCRYPT_SLOW_WORD64)
187 return (word64)((word64)ByteReverseWord32((word32) value)) << 32 |
188 (word64)ByteReverseWord32((word32)(value >> 32));
189#else
190 value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
191 ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
192 value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
193 ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
194 return rotlFixed64(value, 32U);
195#endif
196}
197
198
199WC_STATIC WC_INLINE void ByteReverseWords64(word64* out, const word64* in,
200 word32 byteCount)
201{
202 word32 count = byteCount/(word32)sizeof(word64), i;
203
204 for (i = 0; i < count; i++)
205 out[i] = ByteReverseWord64(in[i]);
206
207}
208
209#endif /* WORD64_AVAILABLE && !WOLFSSL_NO_WORD64_OPS */
210
211#ifndef WOLFSSL_NO_XOR_OPS
212/* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
213of wolfssl_words, placing the result in <*r>. */
214WC_STATIC WC_INLINE void XorWordsOut(wolfssl_word* r, const wolfssl_word* a,
215 const wolfssl_word* b, word32 n)
216{
217 word32 i;
218
219 for (i = 0; i < n; i++) r[i] = a[i] ^ b[i];
220}
221
222/* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
223counts, placing the result in <*buf>. */
224
225WC_STATIC WC_INLINE void xorbufout(void*out, const void* buf, const void* mask,
226 word32 count)
227{
228 if (((wolfssl_word)out | (wolfssl_word)buf | (wolfssl_word)mask | count) % \
229 WOLFSSL_WORD_SIZE == 0)
230 XorWordsOut( (wolfssl_word*)out, (wolfssl_word*)buf,
231 (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
232 else {
233 word32 i;
234 byte* o = (byte*)out;
235 byte* b = (byte*)buf;
236 const byte* m = (const byte*)mask;
237
238 for (i = 0; i < count; i++) o[i] = b[i] ^ m[i];
239 }
240}
241
242/* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
243of wolfssl_words, placing the result in <*r>. */
244WC_STATIC WC_INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)
245{
246 word32 i;
247
248 for (i = 0; i < n; i++) r[i] ^= a[i];
249}
250
251/* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
252counts, placing the result in <*buf>. */
253
254WC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
255{
256 if (((wolfssl_word)buf | (wolfssl_word)mask | count) % WOLFSSL_WORD_SIZE == 0)
257 XorWords( (wolfssl_word*)buf,
258 (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
259 else {
260 word32 i;
261 byte* b = (byte*)buf;
262 const byte* m = (const byte*)mask;
263
264 for (i = 0; i < count; i++) b[i] ^= m[i];
265 }
266}
267#endif
268
269#ifndef WOLFSSL_NO_FORCE_ZERO
270/* This routine fills the first len bytes of the memory area pointed by mem
271 with zeros. It ensures compiler optimizations doesn't skip it */
272WC_STATIC WC_INLINE void ForceZero(const void* mem, word32 len)
273{
274 volatile byte* z = (volatile byte*)mem;
275
276#if (defined(WOLFSSL_X86_64_BUILD) || defined(WOLFSSL_AARCH64_BUILD)) \
277 && defined(WORD64_AVAILABLE)
278 volatile word64* w;
279 #ifndef WOLFSSL_UNALIGNED_64BIT_ACCESS
280 word32 l = (sizeof(word64) - ((size_t)z & (sizeof(word64)-1))) &
281 (sizeof(word64)-1);
282
283 if (len < l) l = len;
284 len -= l;
285 while (l--) *z++ = 0;
286 #endif
287 for (w = (volatile word64*)z; len >= sizeof(*w); len -= sizeof(*w))
288 *w++ = 0;
289 z = (volatile byte*)w;
290#endif
291
292 while (len--) *z++ = 0;
293}
294#endif
295
296
297#ifndef WOLFSSL_NO_CONST_CMP
298/* check all length bytes for equality, return 0 on success */
299WC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, int length)
300{
301 int i;
302 int compareSum = 0;
303
304 for (i = 0; i < length; i++) {
305 compareSum |= a[i] ^ b[i];
306 }
307
308 return compareSum;
309}
310#endif
311
312
313#ifndef WOLFSSL_HAVE_MIN
314 #define WOLFSSL_HAVE_MIN
315 #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */
316 #define min min
317 #endif
318 /* returns the smaller of a and b */
319 WC_STATIC WC_INLINE word32 min(word32 a, word32 b)
320 {
321 return a > b ? b : a;
322 }
323#endif /* !WOLFSSL_HAVE_MIN */
324
325#ifndef WOLFSSL_HAVE_MAX
326 #define WOLFSSL_HAVE_MAX
327 #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */
328 #define max max
329 #endif
330 WC_STATIC WC_INLINE word32 max(word32 a, word32 b)
331 {
332 return a > b ? a : b;
333 }
334#endif /* !WOLFSSL_HAVE_MAX */
335
336#ifndef WOLFSSL_NO_INT_ENCODE
337/* converts a 32 bit integer to 24 bit */
338WC_STATIC WC_INLINE void c32to24(word32 in, word24 out)
339{
340 out[0] = (in >> 16) & 0xff;
341 out[1] = (in >> 8) & 0xff;
342 out[2] = in & 0xff;
343}
344
345/* convert 16 bit integer to opaque */
346WC_STATIC WC_INLINE void c16toa(word16 wc_u16, byte* c)
347{
348 c[0] = (wc_u16 >> 8) & 0xff;
349 c[1] = wc_u16 & 0xff;
350}
351
352/* convert 32 bit integer to opaque */
353WC_STATIC WC_INLINE void c32toa(word32 wc_u32, byte* c)
354{
355 c[0] = (wc_u32 >> 24) & 0xff;
356 c[1] = (wc_u32 >> 16) & 0xff;
357 c[2] = (wc_u32 >> 8) & 0xff;
358 c[3] = wc_u32 & 0xff;
359}
360#endif
361
362#ifndef WOLFSSL_NO_INT_DECODE
363/* convert a 24 bit integer into a 32 bit one */
364WC_STATIC WC_INLINE void c24to32(const word24 wc_u24, word32* wc_u32)
365{
366 *wc_u32 = ((word32)wc_u24[0] << 16) | (wc_u24[1] << 8) | wc_u24[2];
367}
368
369
370/* convert opaque to 24 bit integer */
371WC_STATIC WC_INLINE void ato24(const byte* c, word32* wc_u24)
372{
373 *wc_u24 = ((word32)c[0] << 16) | (c[1] << 8) | c[2];
374}
375
376/* convert opaque to 16 bit integer */
377WC_STATIC WC_INLINE void ato16(const byte* c, word16* wc_u16)
378{
379 *wc_u16 = (word16) ((c[0] << 8) | (c[1]));
380}
381
382/* convert opaque to 32 bit integer */
383WC_STATIC WC_INLINE void ato32(const byte* c, word32* wc_u32)
384{
385 *wc_u32 = ((word32)c[0] << 24) | ((word32)c[1] << 16) | (c[2] << 8) | c[3];
386}
387
388
389WC_STATIC WC_INLINE word32 btoi(byte b)
390{
391 return (word32)(b - 0x30);
392}
393#endif
394
395
396#ifndef WOLFSSL_NO_CT_OPS
397/* Constant time - mask set when a > b. */
398WC_STATIC WC_INLINE byte ctMaskGT(int a, int b)
399{
400 return (byte)((((word32)a - b - 1) >> 31) - 1);
401}
402
403/* Constant time - mask set when a >= b. */
404WC_STATIC WC_INLINE byte ctMaskGTE(int a, int b)
405{
406 return (byte)((((word32)a - b ) >> 31) - 1);
407}
408
409/* Constant time - mask set when a >= b. */
410WC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b)
411{
412 return (int)((((word32)a - b ) >> 31) - 1);
413}
414
415/* Constant time - mask set when a < b. */
416WC_STATIC WC_INLINE byte ctMaskLT(int a, int b)
417{
418 return (byte)((((word32)b - a - 1) >> 31) - 1);
419}
420
421/* Constant time - mask set when a <= b. */
422WC_STATIC WC_INLINE byte ctMaskLTE(int a, int b)
423{
424 return (byte)((((word32)b - a ) >> 31) - 1);
425}
426
427/* Constant time - mask set when a == b. */
428WC_STATIC WC_INLINE byte ctMaskEq(int a, int b)
429{
430 return (byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b));
431}
432
433/* Constant time - sets 16 bit integer mask when a > b */
434WC_STATIC WC_INLINE word16 ctMask16GT(int a, int b)
435{
436 return (word16)((((word32)a - b - 1) >> 31) - 1);
437}
438
439/* Constant time - sets 16 bit integer mask when a >= b */
440WC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b)
441{
442 return (word16)((((word32)a - b ) >> 31) - 1);
443}
444
445/* Constant time - sets 16 bit integer mask when a < b. */
446WC_STATIC WC_INLINE word16 ctMask16LT(int a, int b)
447{
448 return (word16)((((word32)b - a - 1) >> 31) - 1);
449}
450
451/* Constant time - sets 16 bit integer mask when a <= b. */
452WC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b)
453{
454 return (word16)((((word32)b - a ) >> 31) - 1);
455}
456
457/* Constant time - sets 16 bit integer mask when a == b. */
458WC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b)
459{
460 return (word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b));
461}
462
463/* Constant time - mask set when a != b. */
464WC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b)
465{
466 return (byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b);
467}
468
469/* Constant time - select a when mask is set and b otherwise. */
470WC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b)
471{
472 return (byte)((b & ((byte)~(word32)m)) | (a & m));
473}
474
475/* Constant time - select integer a when mask is set and integer b otherwise. */
476WC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b)
477{
478 return (b & (~(signed int)(signed char)m)) |
479 (a & ( (signed int)(signed char)m));
480}
481
482/* Constant time - bit set when a <= b. */
483WC_STATIC WC_INLINE byte ctSetLTE(int a, int b)
484{
485 return (byte)(((word32)a - b - 1) >> 31);
486}
487#endif
488
489
490#undef WC_STATIC
491
492#endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */
493
494#endif /* WOLF_CRYPT_MISC_C */
Note: See TracBrowser for help on using the repository browser.