[457] | 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 | */
|
---|
[464] | 21 | /*
|
---|
[457] | 22 |
|
---|
[464] | 23 | DESCRIPTION
|
---|
| 24 | This module implements the arithmetic-shift right, left, byte swapping, XOR,
|
---|
| 25 | masking and clearing memory logic.
|
---|
[457] | 26 |
|
---|
[464] | 27 | */
|
---|
[457] | 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 */
|
---|
[464] | 85 | /* This routine performs a left circular arithmetic shift of <x> by <y> value. */
|
---|
[457] | 86 |
|
---|
| 87 | WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
|
---|
| 88 | {
|
---|
| 89 | return (x << y) | (x >> (sizeof(y) * 8 - y));
|
---|
| 90 | }
|
---|
| 91 |
|
---|
[464] | 92 | /* This routine performs a right circular arithmetic shift of <x> by <y> value. */
|
---|
[457] | 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 |
|
---|
[464] | 100 | #ifdef WC_RC2
|
---|
[457] | 101 |
|
---|
[464] | 102 | /* This routine performs a left circular arithmetic shift of <x> by <y> value */
|
---|
| 103 | WC_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 */
|
---|
| 110 | WC_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. */
|
---|
[457] | 118 | WC_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);
|
---|
[464] | 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;
|
---|
[457] | 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 | }
|
---|
[464] | 156 | /* This routine performs a byte swap of words array of a given count. */
|
---|
[457] | 157 | WC_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 |
|
---|
| 170 | WC_STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)
|
---|
| 171 | {
|
---|
| 172 | return (x << y) | (x >> (sizeof(y) * 8 - y));
|
---|
| 173 | }
|
---|
| 174 |
|
---|
| 175 |
|
---|
| 176 | WC_STATIC WC_INLINE word64 rotrFixed64(word64 x, word64 y)
|
---|
| 177 | {
|
---|
| 178 | return (x >> y) | (x << (sizeof(y) * 8 - y));
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 |
|
---|
| 182 | WC_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 |
|
---|
| 199 | WC_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
|
---|
[464] | 212 | /* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
|
---|
| 213 | of wolfssl_words, placing the result in <*r>. */
|
---|
| 214 | WC_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
|
---|
| 223 | counts, placing the result in <*buf>. */
|
---|
| 224 |
|
---|
| 225 | WC_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
|
---|
| 243 | of wolfssl_words, placing the result in <*r>. */
|
---|
[457] | 244 | WC_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 |
|
---|
[464] | 251 | /* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
|
---|
| 252 | counts, placing the result in <*buf>. */
|
---|
[457] | 253 |
|
---|
| 254 | WC_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
|
---|
[464] | 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 */
|
---|
[457] | 272 | WC_STATIC WC_INLINE void ForceZero(const void* mem, word32 len)
|
---|
| 273 | {
|
---|
| 274 | volatile byte* z = (volatile byte*)mem;
|
---|
| 275 |
|
---|
[464] | 276 | #if (defined(WOLFSSL_X86_64_BUILD) || defined(WOLFSSL_AARCH64_BUILD)) \
|
---|
| 277 | && defined(WORD64_AVAILABLE)
|
---|
[457] | 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 */
|
---|
| 299 | WC_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
|
---|
[464] | 318 | /* returns the smaller of a and b */
|
---|
[457] | 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 */
|
---|
| 338 | WC_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 */
|
---|
| 346 | WC_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 */
|
---|
| 353 | WC_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 */
|
---|
| 364 | WC_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 */
|
---|
| 371 | WC_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 */
|
---|
| 377 | WC_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 */
|
---|
| 383 | WC_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 |
|
---|
| 389 | WC_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. */
|
---|
| 398 | WC_STATIC WC_INLINE byte ctMaskGT(int a, int b)
|
---|
| 399 | {
|
---|
[464] | 400 | return (byte)((((word32)a - b - 1) >> 31) - 1);
|
---|
[457] | 401 | }
|
---|
| 402 |
|
---|
| 403 | /* Constant time - mask set when a >= b. */
|
---|
| 404 | WC_STATIC WC_INLINE byte ctMaskGTE(int a, int b)
|
---|
| 405 | {
|
---|
[464] | 406 | return (byte)((((word32)a - b ) >> 31) - 1);
|
---|
[457] | 407 | }
|
---|
| 408 |
|
---|
| 409 | /* Constant time - mask set when a >= b. */
|
---|
| 410 | WC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b)
|
---|
| 411 | {
|
---|
[464] | 412 | return (int)((((word32)a - b ) >> 31) - 1);
|
---|
[457] | 413 | }
|
---|
| 414 |
|
---|
| 415 | /* Constant time - mask set when a < b. */
|
---|
| 416 | WC_STATIC WC_INLINE byte ctMaskLT(int a, int b)
|
---|
| 417 | {
|
---|
[464] | 418 | return (byte)((((word32)b - a - 1) >> 31) - 1);
|
---|
[457] | 419 | }
|
---|
| 420 |
|
---|
| 421 | /* Constant time - mask set when a <= b. */
|
---|
| 422 | WC_STATIC WC_INLINE byte ctMaskLTE(int a, int b)
|
---|
| 423 | {
|
---|
[464] | 424 | return (byte)((((word32)b - a ) >> 31) - 1);
|
---|
[457] | 425 | }
|
---|
| 426 |
|
---|
| 427 | /* Constant time - mask set when a == b. */
|
---|
| 428 | WC_STATIC WC_INLINE byte ctMaskEq(int a, int b)
|
---|
| 429 | {
|
---|
[464] | 430 | return (byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b));
|
---|
[457] | 431 | }
|
---|
| 432 |
|
---|
[464] | 433 | /* Constant time - sets 16 bit integer mask when a > b */
|
---|
[457] | 434 | WC_STATIC WC_INLINE word16 ctMask16GT(int a, int b)
|
---|
| 435 | {
|
---|
[464] | 436 | return (word16)((((word32)a - b - 1) >> 31) - 1);
|
---|
[457] | 437 | }
|
---|
| 438 |
|
---|
[464] | 439 | /* Constant time - sets 16 bit integer mask when a >= b */
|
---|
| 440 | WC_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. */
|
---|
[457] | 446 | WC_STATIC WC_INLINE word16 ctMask16LT(int a, int b)
|
---|
| 447 | {
|
---|
[464] | 448 | return (word16)((((word32)b - a - 1) >> 31) - 1);
|
---|
[457] | 449 | }
|
---|
| 450 |
|
---|
[464] | 451 | /* Constant time - sets 16 bit integer mask when a <= b. */
|
---|
| 452 | WC_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. */
|
---|
[457] | 458 | WC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b)
|
---|
| 459 | {
|
---|
[464] | 460 | return (word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b));
|
---|
[457] | 461 | }
|
---|
| 462 |
|
---|
| 463 | /* Constant time - mask set when a != b. */
|
---|
| 464 | WC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b)
|
---|
| 465 | {
|
---|
[464] | 466 | return (byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b);
|
---|
[457] | 467 | }
|
---|
| 468 |
|
---|
| 469 | /* Constant time - select a when mask is set and b otherwise. */
|
---|
| 470 | WC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b)
|
---|
| 471 | {
|
---|
[464] | 472 | return (byte)((b & ((byte)~(word32)m)) | (a & m));
|
---|
[457] | 473 | }
|
---|
| 474 |
|
---|
| 475 | /* Constant time - select integer a when mask is set and integer b otherwise. */
|
---|
| 476 | WC_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. */
|
---|
| 483 | WC_STATIC WC_INLINE byte ctSetLTE(int a, int b)
|
---|
| 484 | {
|
---|
[464] | 485 | return (byte)(((word32)a - b - 1) >> 31);
|
---|
[457] | 486 | }
|
---|
| 487 | #endif
|
---|
| 488 |
|
---|
| 489 |
|
---|
| 490 | #undef WC_STATIC
|
---|
| 491 |
|
---|
| 492 | #endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */
|
---|
| 493 |
|
---|
| 494 | #endif /* WOLF_CRYPT_MISC_C */
|
---|