wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers misc.c Source File

misc.c

00001 /* misc.c
00002  *
00003  * Copyright (C) 2006-2016 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfssl/wolfcrypt/settings.h>
00028 
00029 #ifndef WOLF_CRYPT_MISC_C
00030 #define WOLF_CRYPT_MISC_C
00031 
00032 #include <wolfssl/wolfcrypt/misc.h>
00033 
00034 /* inlining these functions is a huge speed increase and a small size decrease,
00035    because the functions are smaller than function call setup/cleanup, e.g.,
00036    md5 benchmark is twice as fast with inline.  If you don't want it, then
00037    define NO_INLINE and compile this file into wolfssl, otherwise it's used as
00038    a source header
00039  */
00040 
00041 #ifdef NO_INLINE
00042     #define STATIC
00043 #else
00044     #define STATIC static
00045 #endif
00046 
00047 /* Check for if compiling misc.c when not needed. */
00048 #if !defined(WOLFSSL_MISC_INCLUDED) && !defined(NO_INLINE)
00049     #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined)
00050 
00051 #else
00052 
00053 
00054 #if defined(__ICCARM__)
00055     #include <intrinsics.h>
00056 #endif
00057 
00058 
00059 #ifdef INTEL_INTRINSICS
00060 
00061     #include <stdlib.h>      /* get intrinsic definitions */
00062 
00063     /* for non visual studio probably need no long version, 32 bit only
00064      * i.e., _rotl and _rotr */
00065     #pragma intrinsic(_lrotl, _lrotr)
00066 
00067     STATIC INLINE word32 rotlFixed(word32 x, word32 y)
00068     {
00069         return y ? _lrotl(x, y) : x;
00070     }
00071 
00072     STATIC INLINE word32 rotrFixed(word32 x, word32 y)
00073     {
00074         return y ? _lrotr(x, y) : x;
00075     }
00076 
00077 #else /* generic */
00078 
00079     STATIC INLINE word32 rotlFixed(word32 x, word32 y)
00080     {
00081         return (x << y) | (x >> (sizeof(y) * 8 - y));
00082     }
00083 
00084 
00085     STATIC INLINE word32 rotrFixed(word32 x, word32 y)
00086     {
00087         return (x >> y) | (x << (sizeof(y) * 8 - y));
00088     }
00089 
00090 #endif
00091 
00092 
00093 STATIC INLINE word32 ByteReverseWord32(word32 value)
00094 {
00095 #ifdef PPC_INTRINSICS
00096     /* PPC: load reverse indexed instruction */
00097     return (word32)__lwbrx(&value,0);
00098 #elif defined(__ICCARM__)
00099     return (word32)__REV(value);
00100 #elif defined(KEIL_INTRINSICS)
00101     return (word32)__rev(value);
00102 #elif defined(FAST_ROTATE)
00103     /* 5 instructions with rotate instruction, 9 without */
00104     return (rotrFixed(value, 8U) & 0xff00ff00) |
00105            (rotlFixed(value, 8U) & 0x00ff00ff);
00106 #else
00107     /* 6 instructions with rotate instruction, 8 without */
00108     value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00109     return rotlFixed(value, 16U);
00110 #endif
00111 }
00112 
00113 
00114 STATIC INLINE void ByteReverseWords(word32* out, const word32* in,
00115                                     word32 byteCount)
00116 {
00117     word32 count = byteCount/(word32)sizeof(word32), i;
00118 
00119     for (i = 0; i < count; i++)
00120         out[i] = ByteReverseWord32(in[i]);
00121 
00122 }
00123 
00124 
00125 #ifdef WORD64_AVAILABLE
00126 
00127 
00128 STATIC INLINE word64 rotlFixed64(word64 x, word64 y)
00129 {
00130     return (x << y) | (x >> (sizeof(y) * 8 - y));
00131 }
00132 
00133 
00134 STATIC INLINE word64 rotrFixed64(word64 x, word64 y)
00135 {
00136     return (x >> y) | (x << (sizeof(y) * 8 - y));
00137 }
00138 
00139 
00140 STATIC INLINE word64 ByteReverseWord64(word64 value)
00141 {
00142 #if defined(WOLFCRYPT_SLOW_WORD64)
00143     return (word64)(ByteReverseWord32((word32)value)) << 32 |
00144                     ByteReverseWord32((word32)(value>>32));
00145 #else
00146     value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
00147             ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00148     value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
00149             ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00150     return rotlFixed64(value, 32U);
00151 #endif
00152 }
00153 
00154 
00155 STATIC INLINE void ByteReverseWords64(word64* out, const word64* in,
00156                                       word32 byteCount)
00157 {
00158     word32 count = byteCount/(word32)sizeof(word64), i;
00159 
00160     for (i = 0; i < count; i++)
00161         out[i] = ByteReverseWord64(in[i]);
00162 
00163 }
00164 
00165 #endif /* WORD64_AVAILABLE */
00166 
00167 
00168 STATIC INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)
00169 {
00170     word32 i;
00171 
00172     for (i = 0; i < n; i++) r[i] ^= a[i];
00173 }
00174 
00175 
00176 STATIC INLINE void xorbuf(void* buf, const void* mask, word32 count)
00177 {
00178     if (((wolfssl_word)buf | (wolfssl_word)mask | count) % WOLFSSL_WORD_SIZE == 0)
00179         XorWords( (wolfssl_word*)buf,
00180                   (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
00181     else {
00182         word32 i;
00183         byte*       b = (byte*)buf;
00184         const byte* m = (const byte*)mask;
00185 
00186         for (i = 0; i < count; i++) b[i] ^= m[i];
00187     }
00188 }
00189 
00190 
00191 /* Make sure compiler doesn't skip */
00192 STATIC INLINE void ForceZero(const void* mem, word32 len)
00193 {
00194     volatile byte* z = (volatile byte*)mem;
00195 #ifdef WOLFSSL_X86_64_BUILD
00196     volatile word64* w;
00197 
00198     for (w = (volatile word64*)z; len >= sizeof(*w); len -= sizeof(*w))
00199         *w++ = 0;
00200     z = (volatile byte*)w;
00201 #endif
00202     while (len--) *z++ = 0;
00203 }
00204 
00205 
00206 /* check all length bytes for equality, return 0 on success */
00207 STATIC INLINE int ConstantCompare(const byte* a, const byte* b, int length)
00208 {
00209     int i;
00210     int compareSum = 0;
00211 
00212     for (i = 0; i < length; i++) {
00213         compareSum |= a[i] ^ b[i];
00214     }
00215 
00216     return compareSum;
00217 }
00218 
00219 
00220 #ifndef WOLFSSL_HAVE_MIN
00221     #define WOLFSSL_HAVE_MIN
00222     #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */
00223         #define min min
00224     #endif
00225     STATIC INLINE word32 min(word32 a, word32 b)
00226     {
00227         return a > b ? b : a;
00228     }
00229 #endif /* !WOLFSSL_HAVE_MIN */
00230 
00231 #ifndef WOLFSSL_HAVE_MAX
00232     #define WOLFSSL_HAVE_MAX
00233     #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */
00234         #define max max
00235     #endif
00236     STATIC INLINE word32 max(word32 a, word32 b)
00237     {
00238         return a > b ? a : b;
00239     }
00240 #endif /* !WOLFSSL_HAVE_MAX */
00241 
00242 
00243 #undef STATIC
00244 
00245 #endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */
00246 
00247 #endif /* WOLF_CRYPT_MISC_C */
00248