1
0

misc.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  1. /* misc.c
  2. *
  3. * Copyright (C) 2006-2024 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. /* Check for if compiling misc.c when not needed. */
  40. #if !defined(WOLFSSL_MISC_INCLUDED) && !defined(NO_INLINE)
  41. #ifndef WOLFSSL_IGNORE_FILE_WARN
  42. #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined)
  43. #endif
  44. #else
  45. #if defined(__ICCARM__)
  46. #include <intrinsics.h>
  47. #endif
  48. #ifdef INTEL_INTRINSICS
  49. #include <stdlib.h> /* get intrinsic definitions */
  50. /* for non visual studio probably need no long version, 32 bit only
  51. * i.e., _rotl and _rotr */
  52. #pragma intrinsic(_lrotl, _lrotr)
  53. WC_MISC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
  54. {
  55. return y ? _lrotl(x, y) : x;
  56. }
  57. WC_MISC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
  58. {
  59. return y ? _lrotr(x, y) : x;
  60. }
  61. #elif defined(__CCRX__)
  62. #include <builtin.h> /* get intrinsic definitions */
  63. #if !defined(NO_INLINE)
  64. #define rotlFixed(x, y) _builtin_rotl(x, y)
  65. #define rotrFixed(x, y) _builtin_rotr(x, y)
  66. #else /* create real function */
  67. WC_MISC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
  68. {
  69. return _builtin_rotl(x, y);
  70. }
  71. WC_MISC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
  72. {
  73. return _builtin_rotr(x, y);
  74. }
  75. #endif
  76. #else /* generic */
  77. /* This routine performs a left circular arithmetic shift of <x> by <y> value. */
  78. WC_MISC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
  79. {
  80. return (x << y) | (x >> (sizeof(x) * 8 - y));
  81. }
  82. /* This routine performs a right circular arithmetic shift of <x> by <y> value. */
  83. WC_MISC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
  84. {
  85. return (x >> y) | (x << (sizeof(x) * 8 - y));
  86. }
  87. #endif
  88. /* This routine performs a left circular arithmetic shift of <x> by <y> value */
  89. WC_MISC_STATIC WC_INLINE word16 rotlFixed16(word16 x, word16 y)
  90. {
  91. return (x << y) | (x >> (sizeof(x) * 8 - y));
  92. }
  93. /* This routine performs a right circular arithmetic shift of <x> by <y> value */
  94. WC_MISC_STATIC WC_INLINE word16 rotrFixed16(word16 x, word16 y)
  95. {
  96. return (x >> y) | (x << (sizeof(x) * 8 - y));
  97. }
  98. /* This routine performs a byte swap of 32-bit word value. */
  99. #if defined(__CCRX__) && !defined(NO_INLINE) /* shortest version for CC-RX */
  100. #define ByteReverseWord32(value) _builtin_revl(value)
  101. #else
  102. WC_MISC_STATIC WC_INLINE word32 ByteReverseWord32(word32 value)
  103. {
  104. #ifdef PPC_INTRINSICS
  105. /* PPC: load reverse indexed instruction */
  106. return (word32)__lwbrx(&value,0);
  107. #elif defined(__ICCARM__)
  108. return (word32)__REV(value);
  109. #elif defined(KEIL_INTRINSICS)
  110. return (word32)__rev(value);
  111. #elif defined(__CCRX__)
  112. return (word32)_builtin_revl(value);
  113. #elif defined(WOLF_ALLOW_BUILTIN) && \
  114. defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
  115. return (word32)__builtin_bswap32(value);
  116. #elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
  117. defined(__aarch64__)
  118. __asm__ volatile (
  119. "REV32 %0, %0 \n"
  120. : "+r" (value)
  121. :
  122. );
  123. return value;
  124. #elif defined(WOLFSSL_BYTESWAP32_ASM) && defined(__GNUC__) && \
  125. (defined(__thumb__) || defined(__arm__))
  126. __asm__ volatile (
  127. "REV %0, %0 \n"
  128. : "+r" (value)
  129. :
  130. );
  131. return value;
  132. #elif defined(FAST_ROTATE)
  133. /* 5 instructions with rotate instruction, 9 without */
  134. return (rotrFixed(value, 8U) & 0xff00ff00) |
  135. (rotlFixed(value, 8U) & 0x00ff00ff);
  136. #else
  137. /* 6 instructions with rotate instruction, 8 without */
  138. value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
  139. return rotlFixed(value, 16U);
  140. #endif
  141. }
  142. #endif /* __CCRX__ */
  143. /* This routine performs a byte swap of words array of a given count. */
  144. WC_MISC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,
  145. word32 byteCount)
  146. {
  147. word32 i;
  148. #ifdef WOLFSSL_USE_ALIGN
  149. if ((((size_t)in & 0x3) == 0) &&
  150. (((size_t)out & 0x3) == 0))
  151. #endif
  152. {
  153. word32 count = byteCount/(word32)sizeof(word32);
  154. for (i = 0; i < count; i++)
  155. out[i] = ByteReverseWord32(in[i]);
  156. }
  157. #ifdef WOLFSSL_USE_ALIGN
  158. else {
  159. byte *in_bytes = (byte *)in;
  160. byte *out_bytes = (byte *)out;
  161. word32 scratch;
  162. byteCount &= ~0x3U;
  163. for (i = 0; i < byteCount; i += sizeof(word32)) {
  164. XMEMCPY(&scratch, in_bytes + i, sizeof(scratch));
  165. scratch = ByteReverseWord32(scratch);
  166. XMEMCPY(out_bytes + i, &scratch, sizeof(scratch));
  167. }
  168. }
  169. #endif
  170. }
  171. WC_MISC_STATIC WC_INLINE word32 readUnalignedWord32(const byte *in)
  172. {
  173. if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0)
  174. return *(word32 *)in;
  175. else {
  176. word32 out = 0; /* else CONFIG_FORTIFY_SOURCE -Wmaybe-uninitialized */
  177. XMEMCPY(&out, in, sizeof(out));
  178. return out;
  179. }
  180. }
  181. WC_MISC_STATIC WC_INLINE word32 writeUnalignedWord32(void *out, word32 in)
  182. {
  183. if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0)
  184. *(word32 *)out = in;
  185. else {
  186. XMEMCPY(out, &in, sizeof(in));
  187. }
  188. return in;
  189. }
  190. WC_MISC_STATIC WC_INLINE void readUnalignedWords32(word32 *out, const byte *in,
  191. size_t count)
  192. {
  193. if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0) {
  194. const word32 *in_word32 = (const word32 *)in;
  195. while (count-- > 0)
  196. *out++ = *in_word32++;
  197. }
  198. else {
  199. XMEMCPY(out, in, count * sizeof(*out));
  200. }
  201. }
  202. WC_MISC_STATIC WC_INLINE void writeUnalignedWords32(byte *out, const word32 *in,
  203. size_t count)
  204. {
  205. if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0) {
  206. word32 *out_word32 = (word32 *)out;
  207. while (count-- > 0)
  208. *out_word32++ = *in++;
  209. }
  210. else {
  211. XMEMCPY(out, in, count * sizeof(*in));
  212. }
  213. }
  214. #if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)
  215. WC_MISC_STATIC WC_INLINE word64 readUnalignedWord64(const byte *in)
  216. {
  217. if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0)
  218. return *(word64 *)in;
  219. else {
  220. word64 out = 0; /* else CONFIG_FORTIFY_SOURCE -Wmaybe-uninitialized */
  221. XMEMCPY(&out, in, sizeof(out));
  222. return out;
  223. }
  224. }
  225. WC_MISC_STATIC WC_INLINE word64 writeUnalignedWord64(void *out, word64 in)
  226. {
  227. if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0)
  228. *(word64 *)out = in;
  229. else {
  230. XMEMCPY(out, &in, sizeof(in));
  231. }
  232. return in;
  233. }
  234. WC_MISC_STATIC WC_INLINE void readUnalignedWords64(word64 *out, const byte *in,
  235. size_t count)
  236. {
  237. if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0) {
  238. const word64 *in_word64 = (const word64 *)in;
  239. while (count-- > 0)
  240. *out++ = *in_word64++;
  241. }
  242. else {
  243. XMEMCPY(out, in, count * sizeof(*out));
  244. }
  245. }
  246. WC_MISC_STATIC WC_INLINE void writeUnalignedWords64(byte *out, const word64 *in,
  247. size_t count)
  248. {
  249. if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0) {
  250. word64 *out_word64 = (word64 *)out;
  251. while (count-- > 0)
  252. *out_word64++ = *in++;
  253. }
  254. else {
  255. XMEMCPY(out, in, count * sizeof(*in));
  256. }
  257. }
  258. WC_MISC_STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)
  259. {
  260. return (x << y) | (x >> (sizeof(y) * 8 - y));
  261. }
  262. WC_MISC_STATIC WC_INLINE word64 rotrFixed64(word64 x, word64 y)
  263. {
  264. return (x >> y) | (x << (sizeof(y) * 8 - y));
  265. }
  266. WC_MISC_STATIC WC_INLINE word64 ByteReverseWord64(word64 value)
  267. {
  268. #if defined(WOLF_ALLOW_BUILTIN) && defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
  269. return (word64)__builtin_bswap64(value);
  270. #elif defined(WOLFCRYPT_SLOW_WORD64)
  271. return (word64)((word64)ByteReverseWord32((word32) value)) << 32 |
  272. (word64)ByteReverseWord32((word32)(value >> 32));
  273. #else
  274. value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
  275. ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
  276. value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
  277. ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
  278. return rotlFixed64(value, 32U);
  279. #endif
  280. }
  281. WC_MISC_STATIC WC_INLINE void ByteReverseWords64(word64* out, const word64* in,
  282. word32 byteCount)
  283. {
  284. word32 count = byteCount/(word32)sizeof(word64), i;
  285. for (i = 0; i < count; i++)
  286. out[i] = ByteReverseWord64(in[i]);
  287. }
  288. #endif /* WORD64_AVAILABLE && !WOLFSSL_NO_WORD64_OPS */
  289. #ifndef WOLFSSL_NO_XOR_OPS
  290. /* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
  291. of wolfssl_words, placing the result in <*r>. */
  292. WC_MISC_STATIC WC_INLINE void XorWordsOut(wolfssl_word** r,
  293. const wolfssl_word** a, const wolfssl_word** b, word32 n)
  294. {
  295. word32 i;
  296. for (i = 0; i < n; i++)
  297. *((*r)++) = *((*a)++) ^ *((*b)++);
  298. }
  299. /* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
  300. counts, placing the result in <*buf>. */
  301. WC_MISC_STATIC WC_INLINE void xorbufout(void* out, const void* buf,
  302. const void* mask, word32 count)
  303. {
  304. word32 i;
  305. byte* o;
  306. const byte* b;
  307. const byte* m;
  308. o = (byte*)out;
  309. b = (const byte*)buf;
  310. m = (const byte*)mask;
  311. if (((wc_ptr_t)o) % WOLFSSL_WORD_SIZE ==
  312. ((wc_ptr_t)b) % WOLFSSL_WORD_SIZE &&
  313. ((wc_ptr_t)b) % WOLFSSL_WORD_SIZE ==
  314. ((wc_ptr_t)m) % WOLFSSL_WORD_SIZE) {
  315. /* type-punning helpers */
  316. union {
  317. byte* bp;
  318. wolfssl_word* wp;
  319. } tpo;
  320. union {
  321. const byte* bp;
  322. const wolfssl_word* wp;
  323. } tpb, tpm;
  324. /* Alignment checks out. Possible to XOR words. */
  325. /* Move alignment so that it lines up with a
  326. * WOLFSSL_WORD_SIZE boundary */
  327. while (((wc_ptr_t)b) % WOLFSSL_WORD_SIZE != 0 && count > 0) {
  328. *(o++) = (byte)(*(b++) ^ *(m++));
  329. count--;
  330. }
  331. tpo.bp = o;
  332. tpb.bp = b;
  333. tpm.bp = m;
  334. XorWordsOut( &tpo.wp, &tpb.wp, &tpm.wp, count / WOLFSSL_WORD_SIZE);
  335. o = tpo.bp;
  336. b = tpb.bp;
  337. m = tpm.bp;
  338. count %= WOLFSSL_WORD_SIZE;
  339. }
  340. for (i = 0; i < count; i++)
  341. o[i] = (byte)(b[i] ^ m[i]);
  342. }
  343. /* This routine performs a bitwise XOR operation of <*r> and <*a> for <n> number
  344. of wolfssl_words, placing the result in <*r>. */
  345. WC_MISC_STATIC WC_INLINE void XorWords(wolfssl_word** r, const wolfssl_word** a,
  346. word32 n)
  347. {
  348. word32 i;
  349. for (i = 0; i < n; i++)
  350. *((*r)++) ^= *((*a)++);
  351. }
  352. /* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
  353. counts, placing the result in <*buf>. */
  354. WC_MISC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
  355. {
  356. word32 i;
  357. byte* b;
  358. const byte* m;
  359. b = (byte*)buf;
  360. m = (const byte*)mask;
  361. if (((wc_ptr_t)b) % WOLFSSL_WORD_SIZE ==
  362. ((wc_ptr_t)m) % WOLFSSL_WORD_SIZE) {
  363. /* type-punning helpers */
  364. union {
  365. byte* bp;
  366. wolfssl_word* wp;
  367. } tpb;
  368. union {
  369. const byte* bp;
  370. const wolfssl_word* wp;
  371. } tpm;
  372. /* Alignment checks out. Possible to XOR words. */
  373. /* Move alignment so that it lines up with a
  374. * WOLFSSL_WORD_SIZE boundary */
  375. while (((wc_ptr_t)buf) % WOLFSSL_WORD_SIZE != 0 && count > 0) {
  376. *(b++) ^= *(m++);
  377. count--;
  378. }
  379. tpb.bp = b;
  380. tpm.bp = m;
  381. XorWords( &tpb.wp, &tpm.wp, count / WOLFSSL_WORD_SIZE);
  382. b = tpb.bp;
  383. m = tpm.bp;
  384. count %= WOLFSSL_WORD_SIZE;
  385. }
  386. for (i = 0; i < count; i++)
  387. b[i] ^= m[i];
  388. }
  389. #endif
  390. #ifndef WOLFSSL_NO_FORCE_ZERO
  391. /* This routine fills the first len bytes of the memory area pointed by mem
  392. with zeros. It ensures compiler optimizations doesn't skip it */
  393. WC_MISC_STATIC WC_INLINE void ForceZero(void* mem, word32 len)
  394. {
  395. volatile byte* z = (volatile byte*)mem;
  396. #if (defined(WOLFSSL_X86_64_BUILD) || defined(WOLFSSL_AARCH64_BUILD)) \
  397. && defined(WORD64_AVAILABLE)
  398. volatile word64* w;
  399. #ifndef WOLFSSL_UNALIGNED_64BIT_ACCESS
  400. word32 l = (sizeof(word64) - ((size_t)z & (sizeof(word64)-1))) &
  401. (sizeof(word64)-1);
  402. if (len < l) l = len;
  403. len -= l;
  404. while (l--) *z++ = 0;
  405. #endif
  406. for (w = (volatile word64*)z;
  407. len >= sizeof(*w);
  408. len -= (word32)sizeof(*w))
  409. {
  410. *w++ = 0;
  411. }
  412. z = (volatile byte*)w;
  413. #endif
  414. while (len--) *z++ = 0;
  415. }
  416. #endif
  417. #ifndef WOLFSSL_NO_CONST_CMP
  418. /* check all length bytes for equality, return 0 on success */
  419. WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b,
  420. int length)
  421. {
  422. int i;
  423. int compareSum = 0;
  424. for (i = 0; i < length; i++) {
  425. compareSum |= a[i] ^ b[i];
  426. }
  427. return compareSum;
  428. }
  429. #endif
  430. #ifndef WOLFSSL_HAVE_MIN
  431. #define WOLFSSL_HAVE_MIN
  432. #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */
  433. #define min min
  434. #endif
  435. /* returns the smaller of a and b */
  436. WC_MISC_STATIC WC_INLINE word32 min(word32 a, word32 b)
  437. {
  438. return a > b ? b : a;
  439. }
  440. #endif /* !WOLFSSL_HAVE_MIN */
  441. #ifndef WOLFSSL_HAVE_MAX
  442. #define WOLFSSL_HAVE_MAX
  443. #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */
  444. #define max max
  445. #endif
  446. WC_MISC_STATIC WC_INLINE word32 max(word32 a, word32 b)
  447. {
  448. return a > b ? a : b;
  449. }
  450. #endif /* !WOLFSSL_HAVE_MAX */
  451. #ifndef WOLFSSL_NO_INT_ENCODE
  452. /* converts a 32 bit integer to 24 bit */
  453. WC_MISC_STATIC WC_INLINE void c32to24(word32 in, word24 out)
  454. {
  455. out[0] = (byte)((in >> 16) & 0xff);
  456. out[1] = (byte)((in >> 8) & 0xff);
  457. out[2] = (byte)(in & 0xff);
  458. }
  459. /* convert 16 bit integer to opaque */
  460. WC_MISC_STATIC WC_INLINE void c16toa(word16 wc_u16, byte* c)
  461. {
  462. c[0] = (byte)((wc_u16 >> 8) & 0xff);
  463. c[1] = (byte)(wc_u16 & 0xff);
  464. }
  465. /* convert 32 bit integer to opaque */
  466. WC_MISC_STATIC WC_INLINE void c32toa(word32 wc_u32, byte* c)
  467. {
  468. #ifdef WOLFSSL_USE_ALIGN
  469. c[0] = (byte)((wc_u32 >> 24) & 0xff);
  470. c[1] = (byte)((wc_u32 >> 16) & 0xff);
  471. c[2] = (byte)((wc_u32 >> 8) & 0xff);
  472. c[3] = (byte)(wc_u32 & 0xff);
  473. #elif defined(LITTLE_ENDIAN_ORDER)
  474. *(word32*)c = ByteReverseWord32(wc_u32);
  475. #else
  476. *(word32*)c = wc_u32;
  477. #endif
  478. }
  479. #endif
  480. #ifndef WOLFSSL_NO_INT_DECODE
  481. /* convert a 24 bit integer into a 32 bit one */
  482. WC_MISC_STATIC WC_INLINE void c24to32(const word24 wc_u24, word32* wc_u32)
  483. {
  484. *wc_u32 = ((word32)wc_u24[0] << 16) |
  485. ((word32)wc_u24[1] << 8) |
  486. (word32)wc_u24[2];
  487. }
  488. /* convert opaque to 24 bit integer */
  489. WC_MISC_STATIC WC_INLINE void ato24(const byte* c, word32* wc_u24)
  490. {
  491. *wc_u24 = ((word32)c[0] << 16) | ((word32)c[1] << 8) | c[2];
  492. }
  493. /* convert opaque to 16 bit integer */
  494. WC_MISC_STATIC WC_INLINE void ato16(const byte* c, word16* wc_u16)
  495. {
  496. *wc_u16 = (word16) ((c[0] << 8) | (c[1]));
  497. }
  498. /* convert opaque to 32 bit integer */
  499. WC_MISC_STATIC WC_INLINE void ato32(const byte* c, word32* wc_u32)
  500. {
  501. #ifdef WOLFSSL_USE_ALIGN
  502. *wc_u32 = ((word32)c[0] << 24) |
  503. ((word32)c[1] << 16) |
  504. ((word32)c[2] << 8) |
  505. (word32)c[3];
  506. #elif defined(LITTLE_ENDIAN_ORDER)
  507. *wc_u32 = ByteReverseWord32(*(word32*)c);
  508. #else
  509. *wc_u32 = *(word32*)c;
  510. #endif
  511. }
  512. /* convert opaque to 32 bit integer. Interpret as little endian. */
  513. WC_MISC_STATIC WC_INLINE void ato32le(const byte* c, word32* wc_u32)
  514. {
  515. *wc_u32 = (word32)c[0] |
  516. ((word32)c[1] << 8) |
  517. ((word32)c[2] << 16) |
  518. ((word32)c[3] << 24);
  519. }
  520. WC_MISC_STATIC WC_INLINE word32 btoi(byte b)
  521. {
  522. return (word32)(b - 0x30);
  523. }
  524. #endif
  525. WC_MISC_STATIC WC_INLINE signed char HexCharToByte(char ch)
  526. {
  527. signed char ret = (signed char)ch;
  528. if (ret >= '0' && ret <= '9')
  529. ret -= '0';
  530. else if (ret >= 'A' && ret <= 'F')
  531. ret -= 'A' - 10;
  532. else if (ret >= 'a' && ret <= 'f')
  533. ret -= 'a' - 10;
  534. else
  535. ret = -1; /* error case - return code must be signed */
  536. return ret;
  537. }
  538. WC_MISC_STATIC WC_INLINE char ByteToHex(byte in)
  539. {
  540. static const char kHexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
  541. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  542. return (char)(kHexChar[in & 0xF]);
  543. }
  544. WC_MISC_STATIC WC_INLINE int ByteToHexStr(byte in, char* out)
  545. {
  546. if (out == NULL)
  547. return -1;
  548. out[0] = ByteToHex((byte)(in >> 4));
  549. out[1] = ByteToHex((byte)(in & 0xf));
  550. return 0;
  551. }
  552. WC_MISC_STATIC WC_INLINE int CharIsWhiteSpace(char ch)
  553. {
  554. switch (ch) {
  555. case ' ':
  556. case '\t':
  557. case '\n':
  558. return 1;
  559. default:
  560. return 0;
  561. }
  562. }
  563. #ifndef WOLFSSL_NO_CT_OPS
  564. /* Constant time - mask set when a > b. */
  565. WC_MISC_STATIC WC_INLINE byte ctMaskGT(int a, int b)
  566. {
  567. return (byte)((((word32)a - (word32)b - 1) >> 31) - 1);
  568. }
  569. /* Constant time - mask set when a >= b. */
  570. WC_MISC_STATIC WC_INLINE byte ctMaskGTE(int a, int b)
  571. {
  572. return (byte)((((word32)a - (word32)b) >> 31) - 1);
  573. }
  574. /* Constant time - mask set when a >= b. */
  575. WC_MISC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b)
  576. {
  577. return (int)((((word32)a - (word32)b) >> 31) - 1);
  578. }
  579. /* Constant time - mask set when a < b. */
  580. WC_MISC_STATIC WC_INLINE byte ctMaskLT(int a, int b)
  581. {
  582. return (byte)((((word32)b - (word32)a - 1) >> 31) - 1);
  583. }
  584. /* Constant time - mask set when a <= b. */
  585. WC_MISC_STATIC WC_INLINE byte ctMaskLTE(int a, int b)
  586. {
  587. return (byte)((((word32)b - (word32)a) >> 31) - 1);
  588. }
  589. /* Constant time - mask set when a == b. */
  590. WC_MISC_STATIC WC_INLINE byte ctMaskEq(int a, int b)
  591. {
  592. return (byte)((byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b)));
  593. }
  594. /* Constant time - sets 16 bit integer mask when a > b */
  595. WC_MISC_STATIC WC_INLINE word16 ctMask16GT(int a, int b)
  596. {
  597. return (word16)((((word32)a - (word32)b - 1) >> 31) - 1);
  598. }
  599. /* Constant time - sets 16 bit integer mask when a >= b */
  600. WC_MISC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b)
  601. {
  602. return (word16)((((word32)a - (word32)b) >> 31) - 1);
  603. }
  604. /* Constant time - sets 16 bit integer mask when a < b. */
  605. WC_MISC_STATIC WC_INLINE word16 ctMask16LT(int a, int b)
  606. {
  607. return (word16)((((word32)b - (word32)a - 1) >> 31) - 1);
  608. }
  609. /* Constant time - sets 16 bit integer mask when a <= b. */
  610. WC_MISC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b)
  611. {
  612. return (word16)((((word32)b - (word32)a) >> 31) - 1);
  613. }
  614. /* Constant time - sets 16 bit integer mask when a == b. */
  615. WC_MISC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b)
  616. {
  617. return (word16)((word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b)));
  618. }
  619. /* Constant time - mask set when a != b. */
  620. WC_MISC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b)
  621. {
  622. return (byte)((byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b));
  623. }
  624. /* Constant time - select a when mask is set and b otherwise. */
  625. WC_MISC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b)
  626. {
  627. return (byte)((b & ((byte)~(word32)m)) | (a & m));
  628. }
  629. /* Constant time - select integer a when mask is set and integer b otherwise. */
  630. WC_MISC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b)
  631. {
  632. return (b & (~(signed int)(signed char)m)) |
  633. (a & ( (signed int)(signed char)m));
  634. }
  635. /* Constant time - select word32 a when mask is set and word32 b otherwise. */
  636. WC_MISC_STATIC WC_INLINE word32 ctMaskSelWord32(byte m, word32 a, word32 b)
  637. {
  638. return (((word32)b & (word32)(~(signed int)(signed char)m)) |
  639. ((word32)a & (word32)( (signed int)(signed char)m)));
  640. }
  641. /* Constant time - bit set when a <= b. */
  642. WC_MISC_STATIC WC_INLINE byte ctSetLTE(int a, int b)
  643. {
  644. return (byte)(((word32)a - (word32)b - 1) >> 31);
  645. }
  646. /* Constant time - conditionally copy size bytes from src to dst if mask is set
  647. */
  648. WC_MISC_STATIC WC_INLINE void ctMaskCopy(byte mask, byte* dst, byte* src,
  649. word16 size)
  650. {
  651. int i;
  652. for (i = 0; i < size; ++i) {
  653. dst[i] ^= (dst[i] ^ src[i]) & mask;
  654. }
  655. }
  656. #endif
  657. #if defined(WOLFSSL_W64_WRAPPER)
  658. #if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_W64_WRAPPER_TEST)
  659. WC_MISC_STATIC WC_INLINE void w64Increment(w64wrapper *n) {
  660. n->n++;
  661. }
  662. WC_MISC_STATIC WC_INLINE void w64Decrement(w64wrapper *n) {
  663. n->n--;
  664. }
  665. WC_MISC_STATIC WC_INLINE byte w64Equal(w64wrapper a, w64wrapper b) {
  666. return (a.n == b.n);
  667. }
  668. WC_MISC_STATIC WC_INLINE word32 w64GetLow32(w64wrapper n) {
  669. return (word32)n.n;
  670. }
  671. WC_MISC_STATIC WC_INLINE word32 w64GetHigh32(w64wrapper n) {
  672. return (word32)(n.n >> 32);
  673. }
  674. WC_MISC_STATIC WC_INLINE void w64SetLow32(w64wrapper *n, word32 low) {
  675. n->n = (n->n & (~(word64)(0xffffffff))) | low;
  676. }
  677. WC_MISC_STATIC WC_INLINE w64wrapper w64Add32(w64wrapper a, word32 b, byte *wrap)
  678. {
  679. a.n += b;
  680. if (a.n < b && wrap != NULL)
  681. *wrap = 1;
  682. return a;
  683. }
  684. WC_MISC_STATIC WC_INLINE w64wrapper w64Add(w64wrapper a, w64wrapper b,
  685. byte *wrap)
  686. {
  687. a.n += b.n;
  688. if (a.n < b.n && wrap != NULL)
  689. *wrap = 1;
  690. return a;
  691. }
  692. WC_MISC_STATIC WC_INLINE w64wrapper w64Sub32(w64wrapper a, word32 b, byte *wrap)
  693. {
  694. if (a.n < b && wrap != NULL)
  695. *wrap = 1;
  696. a.n = a.n - b;
  697. return a;
  698. }
  699. WC_MISC_STATIC WC_INLINE byte w64GT(w64wrapper a, w64wrapper b)
  700. {
  701. return a.n > b.n;
  702. }
  703. WC_MISC_STATIC WC_INLINE byte w64IsZero(w64wrapper a)
  704. {
  705. return a.n == 0;
  706. }
  707. WC_MISC_STATIC WC_INLINE void c64toa(const w64wrapper *a, byte *out)
  708. {
  709. #ifdef BIG_ENDIAN_ORDER
  710. XMEMCPY(out, &a->n, sizeof(a->n));
  711. #else
  712. word64 _out;
  713. _out = ByteReverseWord64(a->n);
  714. XMEMCPY(out, &_out, sizeof(_out));
  715. #endif /* BIG_ENDIAN_ORDER */
  716. }
  717. WC_MISC_STATIC WC_INLINE void ato64(const byte *in, w64wrapper *w64)
  718. {
  719. #ifdef BIG_ENDIAN_ORDER
  720. XMEMCPY(&w64->n, in, sizeof(w64->n));
  721. #else
  722. word64 _in;
  723. XMEMCPY(&_in, in, sizeof(_in));
  724. w64->n = ByteReverseWord64(_in);
  725. #endif /* BIG_ENDIAN_ORDER */
  726. }
  727. WC_MISC_STATIC WC_INLINE w64wrapper w64From32(word32 hi, word32 lo)
  728. {
  729. w64wrapper ret;
  730. ret.n = ((word64)hi << 32) | lo;
  731. return ret;
  732. }
  733. WC_MISC_STATIC WC_INLINE byte w64GTE(w64wrapper a, w64wrapper b)
  734. {
  735. return a.n >= b.n;
  736. }
  737. WC_MISC_STATIC WC_INLINE byte w64LT(w64wrapper a, w64wrapper b)
  738. {
  739. return a.n < b.n;
  740. }
  741. WC_MISC_STATIC WC_INLINE w64wrapper w64Sub(w64wrapper a, w64wrapper b)
  742. {
  743. a.n -= b.n;
  744. return a;
  745. }
  746. WC_MISC_STATIC WC_INLINE void w64Zero(w64wrapper *a)
  747. {
  748. a->n = 0;
  749. }
  750. WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftRight(w64wrapper a, int shift)
  751. {
  752. a.n >>= shift;
  753. return a;
  754. }
  755. WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftLeft(w64wrapper a, int shift)
  756. {
  757. a.n <<= shift;
  758. return a;
  759. }
  760. WC_MISC_STATIC WC_INLINE w64wrapper w64Mul(word32 a, word32 b)
  761. {
  762. w64wrapper ret;
  763. ret.n = (word64)a * (word64)b;
  764. return ret;
  765. }
  766. #else
  767. WC_MISC_STATIC WC_INLINE void w64Increment(w64wrapper *n)
  768. {
  769. n->n[1]++;
  770. if (n->n[1] == 0)
  771. n->n[0]++;
  772. }
  773. WC_MISC_STATIC WC_INLINE void w64Decrement(w64wrapper *n) {
  774. if (n->n[1] == 0)
  775. n->n[0]--;
  776. n->n[1]--;
  777. }
  778. WC_MISC_STATIC WC_INLINE byte w64Equal(w64wrapper a, w64wrapper b)
  779. {
  780. return (a.n[0] == b.n[0] && a.n[1] == b.n[1]);
  781. }
  782. WC_MISC_STATIC WC_INLINE word32 w64GetLow32(w64wrapper n) {
  783. return n.n[1];
  784. }
  785. WC_MISC_STATIC WC_INLINE word32 w64GetHigh32(w64wrapper n) {
  786. return n.n[0];
  787. }
  788. WC_MISC_STATIC WC_INLINE void w64SetLow32(w64wrapper *n, word32 low)
  789. {
  790. n->n[1] = low;
  791. }
  792. WC_MISC_STATIC WC_INLINE w64wrapper w64Add32(w64wrapper a, word32 b, byte *wrap)
  793. {
  794. a.n[1] += b;
  795. if (a.n[1] < b) {
  796. a.n[0]++;
  797. if (wrap != NULL && a.n[0] == 0)
  798. *wrap = 1;
  799. }
  800. return a;
  801. }
  802. WC_MISC_STATIC WC_INLINE w64wrapper w64Add(w64wrapper a, w64wrapper b,
  803. byte *wrap)
  804. {
  805. a.n[1] += b.n[1];
  806. if (a.n[1] < b.n[1]) {
  807. a.n[0]++;
  808. if (wrap != NULL && a.n[0] == 0)
  809. *wrap = 1;
  810. }
  811. a.n[0] += b.n[0];
  812. if (wrap != NULL && a.n[0] < b.n[0]) {
  813. *wrap = 1;
  814. }
  815. return a;
  816. }
  817. WC_MISC_STATIC WC_INLINE w64wrapper w64Sub32(w64wrapper a, word32 b, byte *wrap)
  818. {
  819. byte _underflow = 0;
  820. if (a.n[1] < b)
  821. _underflow = 1;
  822. a.n[1] -= b;
  823. if (_underflow) {
  824. if (a.n[0] == 0 && wrap != NULL)
  825. *wrap = 1;
  826. a.n[0]--;
  827. }
  828. return a;
  829. }
  830. WC_MISC_STATIC WC_INLINE w64wrapper w64Sub(w64wrapper a, w64wrapper b)
  831. {
  832. if (a.n[1] < b.n[1])
  833. a.n[0]--;
  834. a.n[1] -= b.n[1];
  835. a.n[0] -= b.n[0];
  836. return a;
  837. }
  838. WC_MISC_STATIC WC_INLINE void w64Zero(w64wrapper *a)
  839. {
  840. a->n[0] = a->n[1] = 0;
  841. }
  842. WC_MISC_STATIC WC_INLINE byte w64GT(w64wrapper a, w64wrapper b)
  843. {
  844. if (a.n[0] > b.n[0])
  845. return 1;
  846. if (a.n[0] == b.n[0])
  847. return a.n[1] > b.n[1];
  848. return 0;
  849. }
  850. WC_MISC_STATIC WC_INLINE byte w64GTE(w64wrapper a, w64wrapper b)
  851. {
  852. if (a.n[0] > b.n[0])
  853. return 1;
  854. if (a.n[0] == b.n[0])
  855. return a.n[1] >= b.n[1];
  856. return 0;
  857. }
  858. WC_MISC_STATIC WC_INLINE byte w64IsZero(w64wrapper a)
  859. {
  860. return a.n[0] == 0 && a.n[1] == 0;
  861. }
  862. WC_MISC_STATIC WC_INLINE void c64toa(const w64wrapper *a, byte *out)
  863. {
  864. #ifdef BIG_ENDIAN_ORDER
  865. word32 *_out = (word32*)(out);
  866. _out[0] = a->n[0];
  867. _out[1] = a->n[1];
  868. #else
  869. c32toa(a->n[0], out);
  870. c32toa(a->n[1], out + 4);
  871. #endif /* BIG_ENDIAN_ORDER */
  872. }
  873. WC_MISC_STATIC WC_INLINE void ato64(const byte *in, w64wrapper *w64)
  874. {
  875. #ifdef BIG_ENDIAN_ORDER
  876. const word32 *_in = (const word32*)(in);
  877. w64->n[0] = *_in;
  878. w64->n[1] = *(_in + 1);
  879. #else
  880. ato32(in, &w64->n[0]);
  881. ato32(in + 4, &w64->n[1]);
  882. #endif /* BIG_ENDIAN_ORDER */
  883. }
  884. WC_MISC_STATIC WC_INLINE w64wrapper w64From32(word32 hi, word32 lo)
  885. {
  886. w64wrapper w64;
  887. w64.n[0] = hi;
  888. w64.n[1] = lo;
  889. return w64;
  890. }
  891. WC_MISC_STATIC WC_INLINE byte w64LT(w64wrapper a, w64wrapper b)
  892. {
  893. if (a.n[0] < b.n[0])
  894. return 1;
  895. if (a.n[0] == b.n[0])
  896. return a.n[1] < b.n[1];
  897. return 0;
  898. }
  899. WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftRight(w64wrapper a, int shift)
  900. {
  901. if (shift < 32) {
  902. a.n[1] = (a.n[1] >> shift) | (a.n[0] << (32 - shift));
  903. a.n[0] >>= shift;
  904. }
  905. else {
  906. a.n[1] = a.n[0] >> (shift - 32);
  907. a.n[0] = 0;
  908. }
  909. return a;
  910. }
  911. WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftLeft(w64wrapper a, int shift)
  912. {
  913. if (shift < 32) {
  914. a.n[0] = (a.n[0] << shift) | (a.n[1] >> (32 - shift));
  915. a.n[1] <<= shift;
  916. }
  917. else {
  918. a.n[0] = a.n[1] << (shift - 32);
  919. a.n[1] = 0;
  920. }
  921. return a;
  922. }
  923. WC_MISC_STATIC WC_INLINE w64wrapper w64Mul(word32 a, word32 b)
  924. {
  925. w64wrapper ret;
  926. word16 ltlA, ltlB, ltlC, ltlD;
  927. word32 bigA, bigB, bigC, bigD;
  928. ltlA = a & 0xFFFF;
  929. ltlB = (a >> 16) & 0xFFFF;
  930. ltlC = b & 0xFFFF;
  931. ltlD = (b >> 16) & 0xFFFF;
  932. bigA = (word32)ltlA * (word32)ltlC;
  933. bigC = (word32)ltlB * (word32)ltlC;
  934. bigD = (word32)ltlA * (word32)ltlD;
  935. bigB = (word32)ltlB * (word32)ltlD;
  936. ret = w64From32(0, bigB);
  937. ret = w64ShiftLeft(ret, 16);
  938. ret = w64Add32(ret, bigD, NULL);
  939. ret = w64Add32(ret, bigC, NULL);
  940. ret = w64ShiftLeft(ret, 16);
  941. return w64Add32(ret, bigA, NULL);
  942. }
  943. #endif /* WORD64_AVAILABLE && !WOLFSSL_W64_WRAPPER_TEST */
  944. #endif /* WOLFSSL_W64_WRAPPER */
  945. #if defined(HAVE_SESSION_TICKET) || !defined(NO_CERTS) || \
  946. !defined(NO_SESSION_CACHE)
  947. /* Make a word from the front of random hash */
  948. WC_MISC_STATIC WC_INLINE word32 MakeWordFromHash(const byte* hashID)
  949. {
  950. return ((word32)hashID[0] << 24) | ((word32)hashID[1] << 16) |
  951. ((word32)hashID[2] << 8) | (word32)hashID[3];
  952. }
  953. #endif /* HAVE_SESSION_TICKET || !NO_CERTS || !NO_SESSION_CACHE */
  954. #if !defined(WOLFCRYPT_ONLY) && !defined(NO_HASH_WRAPPER) && \
  955. (!defined(NO_SESSION_CACHE) || defined(HAVE_SESSION_TICKET))
  956. #include <wolfssl/wolfcrypt/hash.h>
  957. /* some session IDs aren't random after all, let's make them random */
  958. WC_MISC_STATIC WC_INLINE word32 HashObject(const byte* o, word32 len,
  959. int* error)
  960. {
  961. byte digest[WC_MAX_DIGEST_SIZE];
  962. #ifndef NO_MD5
  963. *error = wc_Md5Hash(o, len, digest);
  964. #elif !defined(NO_SHA)
  965. *error = wc_ShaHash(o, len, digest);
  966. #elif !defined(NO_SHA256)
  967. *error = wc_Sha256Hash(o, len, digest);
  968. #else
  969. #error "We need a digest to hash the session IDs"
  970. #endif
  971. return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
  972. }
  973. #endif /* WOLFCRYPT_ONLY && !NO_HASH_WRAPPER &&
  974. * (!NO_SESSION_CACHE || HAVE_SESSION_TICKET) */
  975. WC_MISC_STATIC WC_INLINE char* CopyString(const char* src, int srcLen,
  976. void* heap, int type) {
  977. char* dst = NULL;
  978. if (src == NULL)
  979. return NULL;
  980. if (srcLen <= 0)
  981. srcLen = (int)XSTRLEN(src);
  982. dst = (char*)XMALLOC((size_t)srcLen + 1, heap, type);
  983. if (dst != NULL) {
  984. XMEMCPY(dst, src, (size_t)srcLen);
  985. dst[srcLen] = '\0';
  986. }
  987. return dst;
  988. }
  989. #endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */
  990. #endif /* WOLF_CRYPT_MISC_C */