misc.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. /* misc.c
  2. *
  3. * Copyright (C) 2006-2022 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. DESCRIPTION
  23. This module implements the arithmetic-shift right, left, byte swapping, XOR,
  24. masking and clearing memory logic.
  25. */
  26. #ifdef HAVE_CONFIG_H
  27. #include <config.h>
  28. #endif
  29. #include <wolfssl/wolfcrypt/settings.h>
  30. #ifndef WOLF_CRYPT_MISC_C
  31. #define WOLF_CRYPT_MISC_C
  32. #include <wolfssl/wolfcrypt/misc.h>
  33. /* inlining these functions is a huge speed increase and a small size decrease,
  34. because the functions are smaller than function call setup/cleanup, e.g.,
  35. md5 benchmark is twice as fast with inline. If you don't want it, then
  36. define NO_INLINE and compile this file into wolfssl, otherwise it's used as
  37. a source header
  38. */
  39. #ifdef NO_INLINE
  40. #define WC_STATIC
  41. #else
  42. #define WC_STATIC static
  43. #endif
  44. /* Check for if compiling misc.c when not needed. */
  45. #if !defined(WOLFSSL_MISC_INCLUDED) && !defined(NO_INLINE)
  46. #ifndef WOLFSSL_IGNORE_FILE_WARN
  47. #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined)
  48. #endif
  49. #else
  50. #if defined(__ICCARM__)
  51. #include <intrinsics.h>
  52. #endif
  53. #ifdef INTEL_INTRINSICS
  54. #include <stdlib.h> /* get intrinsic definitions */
  55. /* for non visual studio probably need no long version, 32 bit only
  56. * i.e., _rotl and _rotr */
  57. #pragma intrinsic(_lrotl, _lrotr)
  58. WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
  59. {
  60. return y ? _lrotl(x, y) : x;
  61. }
  62. WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
  63. {
  64. return y ? _lrotr(x, y) : x;
  65. }
  66. #elif defined(__CCRX__)
  67. #include <builtin.h> /* get intrinsic definitions */
  68. #if !defined(NO_INLINE)
  69. #define rotlFixed(x, y) _builtin_rotl(x, y)
  70. #define rotrFixed(x, y) _builtin_rotr(x, y)
  71. #else /* create real function */
  72. WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
  73. {
  74. return _builtin_rotl(x, y);
  75. }
  76. WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
  77. {
  78. return _builtin_rotr(x, y);
  79. }
  80. #endif
  81. #else /* generic */
  82. /* This routine performs a left circular arithmetic shift of <x> by <y> value. */
  83. WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
  84. {
  85. return (x << y) | (x >> (sizeof(y) * 8 - y));
  86. }
  87. /* This routine performs a right circular arithmetic shift of <x> by <y> value. */
  88. WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
  89. {
  90. return (x >> y) | (x << (sizeof(y) * 8 - y));
  91. }
  92. #endif
  93. #ifdef WC_RC2
  94. /* This routine performs a left circular arithmetic shift of <x> by <y> value */
  95. WC_STATIC WC_INLINE word16 rotlFixed16(word16 x, word16 y)
  96. {
  97. return (x << y) | (x >> (sizeof(y) * 8 - y));
  98. }
  99. /* This routine performs a right circular arithmetic shift of <x> by <y> value */
  100. WC_STATIC WC_INLINE word16 rotrFixed16(word16 x, word16 y)
  101. {
  102. return (x >> y) | (x << (sizeof(y) * 8 - y));
  103. }
  104. #endif /* WC_RC2 */
  105. /* This routine performs a byte swap of 32-bit word value. */
  106. #if defined(__CCRX__) && !defined(NO_INLINE) /* shortest version for CC-RX */
  107. #define ByteReverseWord32(value) _builtin_revl(value)
  108. #else
  109. WC_STATIC WC_INLINE word32 ByteReverseWord32(word32 value)
  110. {
  111. #ifdef PPC_INTRINSICS
  112. /* PPC: load reverse indexed instruction */
  113. return (word32)__lwbrx(&value,0);
  114. #elif defined(__ICCARM__)
  115. return (word32)__REV(value);
  116. #elif defined(KEIL_INTRINSICS)
  117. return (word32)__rev(value);
  118. #elif defined(__CCRX__)
  119. return (word32)_builtin_revl(value);
  120. #elif defined(WOLF_ALLOW_BUILTIN) && \
  121. defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
  122. return (word32)__builtin_bswap32(value);
  123. #elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
  124. defined(__aarch64__)
  125. __asm__ volatile (
  126. "REV32 %0, %0 \n"
  127. : "+r" (value)
  128. :
  129. );
  130. return value;
  131. #elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
  132. (defined(__thumb__) || defined(__arm__))
  133. __asm__ volatile (
  134. "REV %0, %0 \n"
  135. : "+r" (value)
  136. :
  137. );
  138. return value;
  139. #elif defined(FAST_ROTATE)
  140. /* 5 instructions with rotate instruction, 9 without */
  141. return (rotrFixed(value, 8U) & 0xff00ff00) |
  142. (rotlFixed(value, 8U) & 0x00ff00ff);
  143. #else
  144. /* 6 instructions with rotate instruction, 8 without */
  145. value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
  146. return rotlFixed(value, 16U);
  147. #endif
  148. }
  149. #endif /* __CCRX__ */
  150. /* This routine performs a byte swap of words array of a given count. */
  151. WC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,
  152. word32 byteCount)
  153. {
  154. word32 count, i;
  155. #ifdef WOLFSSL_USE_ALIGN
  156. if ((((size_t)in & 0x3) == 0) &&
  157. (((size_t)out & 0x3) == 0))
  158. {
  159. #endif
  160. count = byteCount/(word32)sizeof(word32);
  161. for (i = 0; i < count; i++)
  162. out[i] = ByteReverseWord32(in[i]);
  163. #ifdef WOLFSSL_USE_ALIGN
  164. }
  165. else {
  166. byte *in_bytes = (byte *)in;
  167. byte *out_bytes = (byte *)out;
  168. word32 scratch;
  169. byteCount &= ~0x3U;
  170. for (i = 0; i < byteCount; i += sizeof(word32)) {
  171. XMEMCPY(&scratch, in_bytes + i, sizeof(scratch));
  172. scratch = ByteReverseWord32(scratch);
  173. XMEMCPY(out_bytes + i, &scratch, sizeof(scratch));
  174. }
  175. }
  176. #endif
  177. }
  178. #if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)
  179. WC_STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)
  180. {
  181. return (x << y) | (x >> (sizeof(y) * 8 - y));
  182. }
  183. WC_STATIC WC_INLINE word64 rotrFixed64(word64 x, word64 y)
  184. {
  185. return (x >> y) | (x << (sizeof(y) * 8 - y));
  186. }
  187. WC_STATIC WC_INLINE word64 ByteReverseWord64(word64 value)
  188. {
  189. #if defined(WOLF_ALLOW_BUILTIN) && defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
  190. return (word64)__builtin_bswap64(value);
  191. #elif defined(WOLFCRYPT_SLOW_WORD64)
  192. return (word64)((word64)ByteReverseWord32((word32) value)) << 32 |
  193. (word64)ByteReverseWord32((word32)(value >> 32));
  194. #else
  195. value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
  196. ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
  197. value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
  198. ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
  199. return rotlFixed64(value, 32U);
  200. #endif
  201. }
  202. WC_STATIC WC_INLINE void ByteReverseWords64(word64* out, const word64* in,
  203. word32 byteCount)
  204. {
  205. word32 count = byteCount/(word32)sizeof(word64), i;
  206. for (i = 0; i < count; i++)
  207. out[i] = ByteReverseWord64(in[i]);
  208. }
  209. #endif /* WORD64_AVAILABLE && !WOLFSSL_NO_WORD64_OPS */
  210. #ifndef WOLFSSL_NO_XOR_OPS
  211. /* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
  212. of wolfssl_words, placing the result in <*r>. */
  213. WC_STATIC WC_INLINE void XorWordsOut(wolfssl_word* r, const wolfssl_word* a,
  214. const wolfssl_word* b, word32 n)
  215. {
  216. word32 i;
  217. for (i = 0; i < n; i++) r[i] = a[i] ^ b[i];
  218. }
  219. /* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
  220. counts, placing the result in <*buf>. */
  221. WC_STATIC WC_INLINE void xorbufout(void*out, const void* buf, const void* mask,
  222. word32 count)
  223. {
  224. if (((wc_ptr_t)out | (wc_ptr_t)buf | (wc_ptr_t)mask | count) %
  225. WOLFSSL_WORD_SIZE == 0)
  226. XorWordsOut( (wolfssl_word*)out, (wolfssl_word*)buf,
  227. (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
  228. else {
  229. word32 i;
  230. byte* o = (byte*)out;
  231. byte* b = (byte*)buf;
  232. const byte* m = (const byte*)mask;
  233. for (i = 0; i < count; i++) o[i] = b[i] ^ m[i];
  234. }
  235. }
  236. /* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
  237. of wolfssl_words, placing the result in <*r>. */
  238. WC_STATIC WC_INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)
  239. {
  240. word32 i;
  241. for (i = 0; i < n; i++) r[i] ^= a[i];
  242. }
  243. /* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
  244. counts, placing the result in <*buf>. */
  245. WC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
  246. {
  247. if (((wc_ptr_t)buf | (wc_ptr_t)mask | count) % WOLFSSL_WORD_SIZE == 0)
  248. XorWords( (wolfssl_word*)buf,
  249. (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
  250. else {
  251. word32 i;
  252. byte* b = (byte*)buf;
  253. const byte* m = (const byte*)mask;
  254. for (i = 0; i < count; i++) b[i] ^= m[i];
  255. }
  256. }
  257. #endif
  258. #ifndef WOLFSSL_NO_FORCE_ZERO
  259. /* This routine fills the first len bytes of the memory area pointed by mem
  260. with zeros. It ensures compiler optimizations doesn't skip it */
  261. WC_STATIC WC_INLINE void ForceZero(void* mem, word32 len)
  262. {
  263. volatile byte* z = (volatile byte*)mem;
  264. #if (defined(WOLFSSL_X86_64_BUILD) || defined(WOLFSSL_AARCH64_BUILD)) \
  265. && defined(WORD64_AVAILABLE)
  266. volatile word64* w;
  267. #ifndef WOLFSSL_UNALIGNED_64BIT_ACCESS
  268. word32 l = (sizeof(word64) - ((size_t)z & (sizeof(word64)-1))) &
  269. (sizeof(word64)-1);
  270. if (len < l) l = len;
  271. len -= l;
  272. while (l--) *z++ = 0;
  273. #endif
  274. for (w = (volatile word64*)z; len >= sizeof(*w); len -= sizeof(*w))
  275. *w++ = 0;
  276. z = (volatile byte*)w;
  277. #endif
  278. while (len--) *z++ = 0;
  279. }
  280. #endif
  281. #ifndef WOLFSSL_NO_CONST_CMP
  282. /* check all length bytes for equality, return 0 on success */
  283. WC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, int length)
  284. {
  285. int i;
  286. int compareSum = 0;
  287. for (i = 0; i < length; i++) {
  288. compareSum |= a[i] ^ b[i];
  289. }
  290. return compareSum;
  291. }
  292. #endif
  293. #ifndef WOLFSSL_HAVE_MIN
  294. #define WOLFSSL_HAVE_MIN
  295. #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */
  296. #define min min
  297. #endif
  298. /* returns the smaller of a and b */
  299. WC_STATIC WC_INLINE word32 min(word32 a, word32 b)
  300. {
  301. return a > b ? b : a;
  302. }
  303. #endif /* !WOLFSSL_HAVE_MIN */
  304. #ifndef WOLFSSL_HAVE_MAX
  305. #define WOLFSSL_HAVE_MAX
  306. #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */
  307. #define max max
  308. #endif
  309. WC_STATIC WC_INLINE word32 max(word32 a, word32 b)
  310. {
  311. return a > b ? a : b;
  312. }
  313. #endif /* !WOLFSSL_HAVE_MAX */
  314. #ifndef WOLFSSL_NO_INT_ENCODE
  315. /* converts a 32 bit integer to 24 bit */
  316. WC_STATIC WC_INLINE void c32to24(word32 in, word24 out)
  317. {
  318. out[0] = (in >> 16) & 0xff;
  319. out[1] = (in >> 8) & 0xff;
  320. out[2] = in & 0xff;
  321. }
  322. /* convert 16 bit integer to opaque */
  323. WC_STATIC WC_INLINE void c16toa(word16 wc_u16, byte* c)
  324. {
  325. c[0] = (wc_u16 >> 8) & 0xff;
  326. c[1] = wc_u16 & 0xff;
  327. }
  328. /* convert 32 bit integer to opaque */
  329. WC_STATIC WC_INLINE void c32toa(word32 wc_u32, byte* c)
  330. {
  331. c[0] = (wc_u32 >> 24) & 0xff;
  332. c[1] = (wc_u32 >> 16) & 0xff;
  333. c[2] = (wc_u32 >> 8) & 0xff;
  334. c[3] = wc_u32 & 0xff;
  335. }
  336. #endif
  337. #ifndef WOLFSSL_NO_INT_DECODE
  338. /* convert a 24 bit integer into a 32 bit one */
  339. WC_STATIC WC_INLINE void c24to32(const word24 wc_u24, word32* wc_u32)
  340. {
  341. *wc_u32 = ((word32)wc_u24[0] << 16) | (wc_u24[1] << 8) | wc_u24[2];
  342. }
  343. /* convert opaque to 24 bit integer */
  344. WC_STATIC WC_INLINE void ato24(const byte* c, word32* wc_u24)
  345. {
  346. *wc_u24 = ((word32)c[0] << 16) | (c[1] << 8) | c[2];
  347. }
  348. /* convert opaque to 16 bit integer */
  349. WC_STATIC WC_INLINE void ato16(const byte* c, word16* wc_u16)
  350. {
  351. *wc_u16 = (word16) ((c[0] << 8) | (c[1]));
  352. }
  353. /* convert opaque to 32 bit integer */
  354. WC_STATIC WC_INLINE void ato32(const byte* c, word32* wc_u32)
  355. {
  356. *wc_u32 = ((word32)c[0] << 24) | ((word32)c[1] << 16) | (c[2] << 8) | c[3];
  357. }
  358. WC_STATIC WC_INLINE word32 btoi(byte b)
  359. {
  360. return (word32)(b - 0x30);
  361. }
  362. #endif
  363. WC_STATIC WC_INLINE signed char HexCharToByte(char ch)
  364. {
  365. signed char ret = (signed char)ch;
  366. if (ret >= '0' && ret <= '9')
  367. ret -= '0';
  368. else if (ret >= 'A' && ret <= 'F')
  369. ret -= 'A' - 10;
  370. else if (ret >= 'a' && ret <= 'f')
  371. ret -= 'a' - 10;
  372. else
  373. ret = -1; /* error case - return code must be signed */
  374. return ret;
  375. }
  376. WC_STATIC WC_INLINE char ByteToHex(byte in)
  377. {
  378. static const char kHexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
  379. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  380. return (char)(kHexChar[in & 0xF]);
  381. }
  382. WC_STATIC WC_INLINE int ByteToHexStr(byte in, char* out)
  383. {
  384. if (out == NULL)
  385. return -1;
  386. out[0] = ByteToHex(in >> 4);
  387. out[1] = ByteToHex(in & 0xf);
  388. return 0;
  389. }
  390. #ifndef WOLFSSL_NO_CT_OPS
  391. /* Constant time - mask set when a > b. */
  392. WC_STATIC WC_INLINE byte ctMaskGT(int a, int b)
  393. {
  394. return (byte)((((word32)a - b - 1) >> 31) - 1);
  395. }
  396. /* Constant time - mask set when a >= b. */
  397. WC_STATIC WC_INLINE byte ctMaskGTE(int a, int b)
  398. {
  399. return (byte)((((word32)a - b ) >> 31) - 1);
  400. }
  401. /* Constant time - mask set when a >= b. */
  402. WC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b)
  403. {
  404. return (int)((((word32)a - b ) >> 31) - 1);
  405. }
  406. /* Constant time - mask set when a < b. */
  407. WC_STATIC WC_INLINE byte ctMaskLT(int a, int b)
  408. {
  409. return (byte)((((word32)b - a - 1) >> 31) - 1);
  410. }
  411. /* Constant time - mask set when a <= b. */
  412. WC_STATIC WC_INLINE byte ctMaskLTE(int a, int b)
  413. {
  414. return (byte)((((word32)b - a ) >> 31) - 1);
  415. }
  416. /* Constant time - mask set when a == b. */
  417. WC_STATIC WC_INLINE byte ctMaskEq(int a, int b)
  418. {
  419. return (byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b));
  420. }
  421. /* Constant time - sets 16 bit integer mask when a > b */
  422. WC_STATIC WC_INLINE word16 ctMask16GT(int a, int b)
  423. {
  424. return (word16)((((word32)a - b - 1) >> 31) - 1);
  425. }
  426. /* Constant time - sets 16 bit integer mask when a >= b */
  427. WC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b)
  428. {
  429. return (word16)((((word32)a - b ) >> 31) - 1);
  430. }
  431. /* Constant time - sets 16 bit integer mask when a < b. */
  432. WC_STATIC WC_INLINE word16 ctMask16LT(int a, int b)
  433. {
  434. return (word16)((((word32)b - a - 1) >> 31) - 1);
  435. }
  436. /* Constant time - sets 16 bit integer mask when a <= b. */
  437. WC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b)
  438. {
  439. return (word16)((((word32)b - a ) >> 31) - 1);
  440. }
  441. /* Constant time - sets 16 bit integer mask when a == b. */
  442. WC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b)
  443. {
  444. return (word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b));
  445. }
  446. /* Constant time - mask set when a != b. */
  447. WC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b)
  448. {
  449. return (byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b);
  450. }
  451. /* Constant time - select a when mask is set and b otherwise. */
  452. WC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b)
  453. {
  454. return (byte)((b & ((byte)~(word32)m)) | (a & m));
  455. }
  456. /* Constant time - select integer a when mask is set and integer b otherwise. */
  457. WC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b)
  458. {
  459. return (b & (~(signed int)(signed char)m)) |
  460. (a & ( (signed int)(signed char)m));
  461. }
  462. /* Constant time - bit set when a <= b. */
  463. WC_STATIC WC_INLINE byte ctSetLTE(int a, int b)
  464. {
  465. return (byte)(((word32)a - b - 1) >> 31);
  466. }
  467. /* Constant time - conditionally copy size bytes from src to dst if mask is set
  468. */
  469. WC_STATIC WC_INLINE void ctMaskCopy(byte mask, byte* dst, byte* src,
  470. word16 size)
  471. {
  472. int i;
  473. for (i = 0; i < size; ++i) {
  474. *(dst + i) ^= (*(dst + i) ^ *(src + i)) & mask;
  475. }
  476. }
  477. #endif
  478. #if defined(WOLFSSL_W64_WRAPPER)
  479. #if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_W64_WRAPPER_TEST)
  480. WC_STATIC WC_INLINE void w64Increment(w64wrapper *n) {
  481. n->n++;
  482. }
  483. WC_STATIC WC_INLINE void w64Decrement(w64wrapper *n) {
  484. n->n--;
  485. }
  486. WC_STATIC WC_INLINE byte w64Equal(w64wrapper a, w64wrapper b) {
  487. return (a.n == b.n);
  488. }
  489. WC_STATIC WC_INLINE word32 w64GetLow32(w64wrapper n) {
  490. return (word32)n.n;
  491. }
  492. WC_STATIC WC_INLINE word32 w64GetHigh32(w64wrapper n) {
  493. return (word32)(n.n >> 32);
  494. }
  495. WC_STATIC WC_INLINE void w64SetLow32(w64wrapper *n, word32 low) {
  496. n->n = (n->n & (~(word64)(0xffffffff))) | low;
  497. }
  498. WC_STATIC WC_INLINE w64wrapper w64Add32(w64wrapper a, word32 b, byte *wrap) {
  499. a.n = a.n + b;
  500. if (a.n < b && wrap != NULL)
  501. *wrap = 1;
  502. return a;
  503. }
  504. WC_STATIC WC_INLINE w64wrapper w64Sub32(w64wrapper a, word32 b, byte *wrap)
  505. {
  506. if (a.n < b && wrap != NULL)
  507. *wrap = 1;
  508. a.n = a.n - b;
  509. return a;
  510. }
  511. WC_STATIC WC_INLINE byte w64GT(w64wrapper a, w64wrapper b)
  512. {
  513. return a.n > b.n;
  514. }
  515. WC_STATIC WC_INLINE byte w64IsZero(w64wrapper a)
  516. {
  517. return a.n == 0;
  518. }
  519. WC_STATIC WC_INLINE void c64toa(const w64wrapper *a, byte *out)
  520. {
  521. #ifdef BIG_ENDIAN_ORDER
  522. XMEMCPY(out, &a->n, sizeof(a->n));
  523. #else
  524. word64 _out;
  525. _out = ByteReverseWord64(a->n);
  526. XMEMCPY(out, &_out, sizeof(_out));
  527. #endif /* BIG_ENDIAN_ORDER */
  528. }
  529. WC_STATIC WC_INLINE void ato64(const byte *in, w64wrapper *w64)
  530. {
  531. #ifdef BIG_ENDIAN_ORDER
  532. XMEMCPY(&w64->n, in, sizeof(w64->n));
  533. #else
  534. word64 _in;
  535. XMEMCPY(&_in, in, sizeof(_in));
  536. w64->n = ByteReverseWord64(_in);
  537. #endif /* BIG_ENDIAN_ORDER */
  538. }
  539. WC_STATIC WC_INLINE w64wrapper w64From32(word32 hi, word32 lo)
  540. {
  541. w64wrapper ret;
  542. ret.n = ((word64)hi << 32) | lo;
  543. return ret;
  544. }
  545. WC_STATIC WC_INLINE byte w64GTE(w64wrapper a, w64wrapper b)
  546. {
  547. return a.n >= b.n;
  548. }
  549. WC_STATIC WC_INLINE byte w64LT(w64wrapper a, w64wrapper b)
  550. {
  551. return a.n < b.n;
  552. }
  553. WC_STATIC WC_INLINE w64wrapper w64Sub(w64wrapper a, w64wrapper b)
  554. {
  555. a.n -= b.n;
  556. return a;
  557. }
  558. WC_STATIC WC_INLINE void w64Zero(w64wrapper *a)
  559. {
  560. a->n = 0;
  561. }
  562. #else
  563. WC_STATIC WC_INLINE void w64Increment(w64wrapper *n)
  564. {
  565. n->n[1]++;
  566. if (n->n[1] == 0)
  567. n->n[0]++;
  568. }
  569. WC_STATIC WC_INLINE void w64Decrement(w64wrapper *n) {
  570. if (n->n[1] == 0)
  571. n->n[0]--;
  572. n->n[1]--;
  573. }
  574. WC_STATIC WC_INLINE byte w64Equal(w64wrapper a, w64wrapper b)
  575. {
  576. return (a.n[0] == b.n[0] && a.n[1] == b.n[1]);
  577. }
  578. WC_STATIC WC_INLINE word32 w64GetLow32(w64wrapper n) {
  579. return n.n[1];
  580. }
  581. WC_STATIC WC_INLINE word32 w64GetHigh32(w64wrapper n) {
  582. return n.n[0];
  583. }
  584. WC_STATIC WC_INLINE void w64SetLow32(w64wrapper *n, word32 low)
  585. {
  586. n->n[1] = low;
  587. }
  588. WC_STATIC WC_INLINE w64wrapper w64Add32(w64wrapper a, word32 b, byte *wrap)
  589. {
  590. a.n[1] = a.n[1] + b;
  591. if (a.n[1] < b) {
  592. a.n[0]++;
  593. if (wrap != NULL && a.n[0] == 0)
  594. *wrap = 1;
  595. }
  596. return a;
  597. }
  598. WC_STATIC WC_INLINE w64wrapper w64Sub32(w64wrapper a, word32 b, byte *wrap)
  599. {
  600. byte _underflow = 0;
  601. if (a.n[1] < b)
  602. _underflow = 1;
  603. a.n[1] -= b;
  604. if (_underflow) {
  605. if (a.n[0] == 0 && wrap != NULL)
  606. *wrap = 1;
  607. a.n[0]--;
  608. }
  609. return a;
  610. }
  611. WC_STATIC WC_INLINE w64wrapper w64Sub(w64wrapper a, w64wrapper b)
  612. {
  613. if (a.n[1] < b.n[1])
  614. a.n[0]--;
  615. a.n[1] -= b.n[1];
  616. a.n[0] -= b.n[0];
  617. return a;
  618. }
  619. WC_STATIC WC_INLINE void w64Zero(w64wrapper *a)
  620. {
  621. a->n[0] = a->n[1] = 0;
  622. }
  623. WC_STATIC WC_INLINE byte w64GT(w64wrapper a, w64wrapper b)
  624. {
  625. if (a.n[0] > b.n[0])
  626. return 1;
  627. if (a.n[0] == b.n[0])
  628. return a.n[1] > b.n[1];
  629. return 0;
  630. }
  631. WC_STATIC WC_INLINE byte w64GTE(w64wrapper a, w64wrapper b)
  632. {
  633. if (a.n[0] > b.n[0])
  634. return 1;
  635. if (a.n[0] == b.n[0])
  636. return a.n[1] >= b.n[1];
  637. return 0;
  638. }
  639. WC_STATIC WC_INLINE byte w64IsZero(w64wrapper a)
  640. {
  641. return a.n[0] == 0 && a.n[1] == 0;
  642. }
  643. WC_STATIC WC_INLINE void c64toa(w64wrapper *a, byte *out)
  644. {
  645. #ifdef BIG_ENDIAN_ORDER
  646. word32 *_out = (word32*)(out);
  647. _out[0] = a->n[0];
  648. _out[1] = a->n[1];
  649. #else
  650. c32toa(a->n[0], out);
  651. c32toa(a->n[1], out + 4);
  652. #endif /* BIG_ENDIAN_ORDER */
  653. }
  654. WC_STATIC WC_INLINE void ato64(const byte *in, w64wrapper *w64)
  655. {
  656. #ifdef BIG_ENDIAN_ORDER
  657. const word32 *_in = (const word32*)(in);
  658. w64->n[0] = *_in;
  659. w64->n[1] = *(_in + 1);
  660. #else
  661. ato32(in, &w64->n[0]);
  662. ato32(in + 4, &w64->n[1]);
  663. #endif /* BIG_ENDIAN_ORDER */
  664. }
  665. WC_STATIC WC_INLINE w64wrapper w64From32(word32 hi, word32 lo)
  666. {
  667. w64wrapper w64;
  668. w64.n[0] = hi;
  669. w64.n[1] = lo;
  670. return w64;
  671. }
  672. WC_STATIC WC_INLINE byte w64LT(w64wrapper a, w64wrapper b)
  673. {
  674. if (a.n[0] < b.n[0])
  675. return 1;
  676. if (a.n[0] == b.n[0])
  677. return a.n[1] < b.n[1];
  678. return 0;
  679. }
  680. #endif /* WORD64_AVAILABLE && !WOLFSSL_W64_WRAPPER_TEST */
  681. #endif /* WOLFSSL_W64_WRAPPER */
  682. #if defined(HAVE_SESSION_TICKET) || !defined(NO_CERTS) || \
  683. !defined(NO_SESSION_CACHE)
  684. /* Make a word from the front of random hash */
  685. WC_STATIC WC_INLINE word32 MakeWordFromHash(const byte* hashID)
  686. {
  687. return ((word32)hashID[0] << 24) | ((word32)hashID[1] << 16) |
  688. ((word32)hashID[2] << 8) | (word32)hashID[3];
  689. }
  690. #endif /* HAVE_SESSION_TICKET || !NO_CERTS || !NO_SESSION_CACHE */
  691. #if !defined(WOLFCRYPT_ONLY) && (!defined(NO_SESSION_CACHE) || \
  692. defined(HAVE_SESSION_TICKET))
  693. #include <wolfssl/wolfcrypt/hash.h>
  694. /* some session IDs aren't random after all, let's make them random */
  695. WC_STATIC WC_INLINE word32 HashObject(const byte* o, word32 len, int* error)
  696. {
  697. byte digest[WC_MAX_DIGEST_SIZE];
  698. #ifndef NO_MD5
  699. *error = wc_Md5Hash(o, len, digest);
  700. #elif !defined(NO_SHA)
  701. *error = wc_ShaHash(o, len, digest);
  702. #elif !defined(NO_SHA256)
  703. *error = wc_Sha256Hash(o, len, digest);
  704. #else
  705. #error "We need a digest to hash the session IDs"
  706. #endif
  707. return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
  708. }
  709. #endif /* WOLFCRYPT_ONLY && (!NO_SESSION_CACHE || HAVE_SESSION_TICKET) */
  710. #undef WC_STATIC
  711. #endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */
  712. #endif /* WOLF_CRYPT_MISC_C */