pwdbased.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. /* pwdbased.c
  2. *
  3. * Copyright (C) 2006-2023 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. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #ifndef NO_PWDBASED
  26. #include <wolfssl/wolfcrypt/pwdbased.h>
  27. #include <wolfssl/wolfcrypt/hmac.h>
  28. #include <wolfssl/wolfcrypt/hash.h>
  29. #include <wolfssl/wolfcrypt/wolfmath.h>
  30. #include <wolfssl/wolfcrypt/error-crypt.h>
  31. #ifdef NO_INLINE
  32. #include <wolfssl/wolfcrypt/misc.h>
  33. #else
  34. #define WOLFSSL_MISC_INCLUDED
  35. #include <wolfcrypt/src/misc.c>
  36. #endif
  37. #ifdef HAVE_PBKDF1
  38. /* PKCS#5 v1.5 with non standard extension to optionally derive the extra data (IV) */
  39. int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
  40. const byte* passwd, int passwdLen, const byte* salt, int saltLen,
  41. int iterations, int hashType, void* heap)
  42. {
  43. int err;
  44. int keyLeft, ivLeft, i;
  45. int store;
  46. int keyOutput = 0;
  47. int digestLen;
  48. byte digest[WC_MAX_DIGEST_SIZE];
  49. #ifdef WOLFSSL_SMALL_STACK
  50. wc_HashAlg* hash = NULL;
  51. #else
  52. wc_HashAlg hash[1];
  53. #endif
  54. enum wc_HashType hashT;
  55. (void)heap;
  56. if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 || ivLen < 0){
  57. return BAD_FUNC_ARG;
  58. }
  59. if (iterations <= 0)
  60. iterations = 1;
  61. hashT = wc_HashTypeConvert(hashType);
  62. err = wc_HashGetDigestSize(hashT);
  63. if (err < 0)
  64. return err;
  65. digestLen = err;
  66. /* initialize hash */
  67. #ifdef WOLFSSL_SMALL_STACK
  68. hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), heap,
  69. DYNAMIC_TYPE_HASHCTX);
  70. if (hash == NULL)
  71. return MEMORY_E;
  72. #endif
  73. err = wc_HashInit_ex(hash, hashT, heap, INVALID_DEVID);
  74. if (err != 0) {
  75. #ifdef WOLFSSL_SMALL_STACK
  76. XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
  77. #endif
  78. return err;
  79. }
  80. keyLeft = keyLen;
  81. ivLeft = ivLen;
  82. while (keyOutput < (keyLen + ivLen)) {
  83. int digestLeft = digestLen;
  84. /* D_(i - 1) */
  85. if (keyOutput) { /* first time D_0 is empty */
  86. err = wc_HashUpdate(hash, hashT, digest, (word32)digestLen);
  87. if (err != 0) break;
  88. }
  89. /* data */
  90. err = wc_HashUpdate(hash, hashT, passwd, (word32)passwdLen);
  91. if (err != 0) break;
  92. /* salt */
  93. if (salt) {
  94. err = wc_HashUpdate(hash, hashT, salt, (word32)saltLen);
  95. if (err != 0) break;
  96. }
  97. err = wc_HashFinal(hash, hashT, digest);
  98. if (err != 0) break;
  99. /* count */
  100. for (i = 1; i < iterations; i++) {
  101. err = wc_HashUpdate(hash, hashT, digest, (word32)digestLen);
  102. if (err != 0) break;
  103. err = wc_HashFinal(hash, hashT, digest);
  104. if (err != 0) break;
  105. }
  106. if (err != 0) break;
  107. if (keyLeft) {
  108. store = (int)min((word32)keyLeft, (word32)digestLen);
  109. XMEMCPY(&key[keyLen - keyLeft], digest, (size_t)store);
  110. keyOutput += store;
  111. keyLeft -= store;
  112. digestLeft -= store;
  113. }
  114. if (ivLeft && digestLeft) {
  115. store = (int)min((word32)ivLeft, (word32)digestLeft);
  116. if (iv != NULL)
  117. XMEMCPY(&iv[ivLen - ivLeft],
  118. &digest[digestLen - digestLeft], (size_t)store);
  119. keyOutput += store;
  120. ivLeft -= store;
  121. }
  122. }
  123. wc_HashFree(hash, hashT);
  124. #ifdef WOLFSSL_SMALL_STACK
  125. XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
  126. #endif
  127. if (err != 0)
  128. return err;
  129. if (keyOutput != (keyLen + ivLen))
  130. return BUFFER_E;
  131. return err;
  132. }
  133. /* PKCS#5 v1.5 */
  134. int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
  135. int sLen, int iterations, int kLen, int hashType)
  136. {
  137. return wc_PBKDF1_ex(output, kLen, NULL, 0,
  138. passwd, pLen, salt, sLen, iterations, hashType, NULL);
  139. }
  140. #endif /* HAVE_PKCS5 */
  141. #if defined(HAVE_PBKDF2) && !defined(NO_HMAC)
  142. int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt,
  143. int sLen, int iterations, int kLen, int hashType, void* heap, int devId)
  144. {
  145. int hLen;
  146. int ret;
  147. #ifdef WOLFSSL_SMALL_STACK
  148. byte* buffer;
  149. Hmac* hmac;
  150. #else
  151. byte buffer[WC_MAX_DIGEST_SIZE];
  152. Hmac hmac[1];
  153. #endif
  154. enum wc_HashType hashT;
  155. if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0) {
  156. return BAD_FUNC_ARG;
  157. }
  158. if (iterations <= 0)
  159. iterations = 1;
  160. hashT = wc_HashTypeConvert(hashType);
  161. hLen = wc_HashGetDigestSize(hashT);
  162. if (hLen < 0)
  163. return BAD_FUNC_ARG;
  164. #ifdef WOLFSSL_SMALL_STACK
  165. buffer = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
  166. if (buffer == NULL)
  167. return MEMORY_E;
  168. hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
  169. if (hmac == NULL) {
  170. XFREE(buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);
  171. return MEMORY_E;
  172. }
  173. #endif
  174. ret = wc_HmacInit(hmac, heap, devId);
  175. if (ret == 0) {
  176. word32 i = 1;
  177. /* use int hashType here, since HMAC FIPS uses the old unique value */
  178. ret = wc_HmacSetKey(hmac, hashType, passwd, (word32)pLen);
  179. while (ret == 0 && kLen) {
  180. int currentLen;
  181. int j;
  182. ret = wc_HmacUpdate(hmac, salt, (word32)sLen);
  183. if (ret != 0)
  184. break;
  185. /* encode i */
  186. for (j = 0; j < 4; j++) {
  187. byte b = (byte)(i >> ((3-j) * 8));
  188. ret = wc_HmacUpdate(hmac, &b, 1);
  189. if (ret != 0)
  190. break;
  191. }
  192. /* check ret from inside for loop */
  193. if (ret != 0)
  194. break;
  195. ret = wc_HmacFinal(hmac, buffer);
  196. if (ret != 0)
  197. break;
  198. currentLen = (int)min((word32)kLen, (word32)hLen);
  199. XMEMCPY(output, buffer, (size_t)currentLen);
  200. for (j = 1; j < iterations; j++) {
  201. ret = wc_HmacUpdate(hmac, buffer, (word32)hLen);
  202. if (ret != 0)
  203. break;
  204. ret = wc_HmacFinal(hmac, buffer);
  205. if (ret != 0)
  206. break;
  207. xorbuf(output, buffer, (word32)currentLen);
  208. }
  209. /* check ret from inside for loop */
  210. if (ret != 0)
  211. break;
  212. output += currentLen;
  213. kLen -= currentLen;
  214. i++;
  215. }
  216. wc_HmacFree(hmac);
  217. }
  218. #ifdef WOLFSSL_SMALL_STACK
  219. XFREE(buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);
  220. XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
  221. #endif
  222. return ret;
  223. }
  224. int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
  225. int sLen, int iterations, int kLen, int hashType)
  226. {
  227. return wc_PBKDF2_ex(output, passwd, pLen, salt, sLen, iterations, kLen,
  228. hashType, NULL, INVALID_DEVID);
  229. }
  230. #endif /* HAVE_PBKDF2 && !NO_HMAC */
  231. #ifdef HAVE_PKCS12
  232. /* helper for PKCS12_PBKDF(), does hash operation */
  233. static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
  234. byte* Ai, word32 u, int iterations)
  235. {
  236. int i;
  237. int ret = 0;
  238. #ifdef WOLFSSL_SMALL_STACK
  239. wc_HashAlg* hash = NULL;
  240. #else
  241. wc_HashAlg hash[1];
  242. #endif
  243. enum wc_HashType hashT;
  244. if (buffer == NULL || Ai == NULL) {
  245. return BAD_FUNC_ARG;
  246. }
  247. hashT = wc_HashTypeConvert(hashType);
  248. /* initialize hash */
  249. #ifdef WOLFSSL_SMALL_STACK
  250. hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
  251. DYNAMIC_TYPE_HASHCTX);
  252. if (hash == NULL)
  253. return MEMORY_E;
  254. #endif
  255. ret = wc_HashInit(hash, hashT);
  256. if (ret != 0) {
  257. #ifdef WOLFSSL_SMALL_STACK
  258. XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
  259. #endif
  260. return ret;
  261. }
  262. ret = wc_HashUpdate(hash, hashT, buffer, totalLen);
  263. if (ret == 0)
  264. ret = wc_HashFinal(hash, hashT, Ai);
  265. for (i = 1; i < iterations; i++) {
  266. if (ret == 0)
  267. ret = wc_HashUpdate(hash, hashT, Ai, u);
  268. if (ret == 0)
  269. ret = wc_HashFinal(hash, hashT, Ai);
  270. }
  271. wc_HashFree(hash, hashT);
  272. #ifdef WOLFSSL_SMALL_STACK
  273. XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
  274. #endif
  275. return ret;
  276. }
  277. int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,
  278. const byte* salt, int saltLen, int iterations, int kLen, int hashType,
  279. int id)
  280. {
  281. return wc_PKCS12_PBKDF_ex(output, passwd, passLen, salt, saltLen,
  282. iterations, kLen, hashType, id, NULL);
  283. }
  284. /* extended API that allows a heap hint to be used */
  285. int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
  286. const byte* salt, int saltLen, int iterations, int kLen,
  287. int hashType, int id, void* heap)
  288. {
  289. /* all in bytes instead of bits */
  290. word32 u, v, dLen, pLen, iLen, sLen, totalLen;
  291. int dynamic = 0;
  292. int ret = 0;
  293. word32 i;
  294. byte *D, *S, *P, *I;
  295. #ifdef WOLFSSL_SMALL_STACK
  296. byte staticBuffer[1]; /* force dynamic usage */
  297. #else
  298. byte staticBuffer[1024];
  299. #endif
  300. byte* buffer = staticBuffer;
  301. #ifdef WOLFSSL_SMALL_STACK
  302. byte* Ai = NULL;
  303. byte* B = NULL;
  304. mp_int *B1 = NULL;
  305. mp_int *i1 = NULL;
  306. mp_int *res = NULL;
  307. #else
  308. byte Ai[WC_MAX_DIGEST_SIZE];
  309. byte B[WC_MAX_BLOCK_SIZE];
  310. mp_int B1[1];
  311. mp_int i1[1];
  312. mp_int res[1];
  313. #endif
  314. enum wc_HashType hashT;
  315. (void)heap;
  316. if (output == NULL || passLen <= 0 || saltLen <= 0 || kLen < 0) {
  317. return BAD_FUNC_ARG;
  318. }
  319. if (iterations <= 0)
  320. iterations = 1;
  321. hashT = wc_HashTypeConvert(hashType);
  322. ret = wc_HashGetDigestSize(hashT);
  323. if (ret < 0)
  324. return ret;
  325. if (ret == 0)
  326. return BAD_STATE_E;
  327. u = (word32)ret;
  328. ret = wc_HashGetBlockSize(hashT);
  329. if (ret < 0)
  330. return ret;
  331. if (ret == 0)
  332. return BAD_STATE_E;
  333. v = (word32)ret;
  334. #ifdef WOLFSSL_SMALL_STACK
  335. Ai = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
  336. if (Ai == NULL)
  337. return MEMORY_E;
  338. B = (byte*)XMALLOC(WC_MAX_BLOCK_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
  339. if (B == NULL) {
  340. XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
  341. return MEMORY_E;
  342. }
  343. #endif
  344. XMEMSET(Ai, 0, WC_MAX_DIGEST_SIZE);
  345. XMEMSET(B, 0, WC_MAX_BLOCK_SIZE);
  346. dLen = v;
  347. sLen = v * (((word32)saltLen + v - 1) / v);
  348. /* with passLen checked at the top of the function for >= 0 then passLen
  349. * must be 1 or greater here and is always 'true' */
  350. pLen = v * (((word32)passLen + v - 1) / v);
  351. iLen = sLen + pLen;
  352. totalLen = dLen + sLen + pLen;
  353. if (totalLen > sizeof(staticBuffer)) {
  354. buffer = (byte*)XMALLOC(totalLen, heap, DYNAMIC_TYPE_KEY);
  355. if (buffer == NULL) {
  356. #ifdef WOLFSSL_SMALL_STACK
  357. XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
  358. XFREE(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
  359. #endif
  360. return MEMORY_E;
  361. }
  362. dynamic = 1;
  363. }
  364. D = buffer;
  365. S = D + dLen;
  366. P = S + sLen;
  367. I = S;
  368. XMEMSET(D, id, dLen);
  369. for (i = 0; i < sLen; i++)
  370. S[i] = salt[i % (word32)saltLen];
  371. for (i = 0; i < pLen; i++)
  372. P[i] = passwd[i % (word32)passLen];
  373. #ifdef WOLFSSL_SMALL_STACK
  374. if (((B1 = (mp_int *)XMALLOC(sizeof(*B1), heap, DYNAMIC_TYPE_TMP_BUFFER))
  375. == NULL) ||
  376. ((i1 = (mp_int *)XMALLOC(sizeof(*i1), heap, DYNAMIC_TYPE_TMP_BUFFER))
  377. == NULL) ||
  378. ((res = (mp_int *)XMALLOC(sizeof(*res), heap, DYNAMIC_TYPE_TMP_BUFFER))
  379. == NULL)) {
  380. ret = MEMORY_E;
  381. goto out;
  382. }
  383. #endif
  384. while (kLen > 0) {
  385. word32 currentLen;
  386. ret = DoPKCS12Hash(hashType, buffer, totalLen, Ai, u, iterations);
  387. if (ret < 0)
  388. break;
  389. for (i = 0; i < v; i++)
  390. B[i] = Ai[(word32)i % u];
  391. if (mp_init(B1) != MP_OKAY)
  392. ret = MP_INIT_E;
  393. else if (mp_read_unsigned_bin(B1, B, v) != MP_OKAY)
  394. ret = MP_READ_E;
  395. else if (mp_add_d(B1, (mp_digit)1, B1) != MP_OKAY)
  396. ret = MP_ADD_E;
  397. if (ret != 0) {
  398. mp_clear(B1);
  399. break;
  400. }
  401. for (i = 0; i < iLen; i += v) {
  402. int outSz;
  403. if (mp_init_multi(i1, res, NULL, NULL, NULL, NULL) != MP_OKAY) {
  404. ret = MP_INIT_E;
  405. break;
  406. }
  407. if (mp_read_unsigned_bin(i1, I + i, v) != MP_OKAY)
  408. ret = MP_READ_E;
  409. else if (mp_add(i1, B1, res) != MP_OKAY)
  410. ret = MP_ADD_E;
  411. else if ( (outSz = mp_unsigned_bin_size(res)) < 0)
  412. ret = MP_TO_E;
  413. else {
  414. if (outSz > (int)v) {
  415. /* take off MSB */
  416. byte tmp[WC_MAX_BLOCK_SIZE + 1];
  417. ret = mp_to_unsigned_bin(res, tmp);
  418. XMEMCPY(I + i, tmp + 1, v);
  419. }
  420. else if (outSz < (int)v) {
  421. XMEMSET(I + i, 0, v - (word32)outSz);
  422. ret = mp_to_unsigned_bin(res, I + i + v - (word32)outSz);
  423. }
  424. else
  425. ret = mp_to_unsigned_bin(res, I + i);
  426. }
  427. mp_clear(i1);
  428. mp_clear(res);
  429. if (ret < 0) break;
  430. }
  431. if (ret < 0) {
  432. mp_clear(B1);
  433. break;
  434. }
  435. currentLen = min((word32)kLen, u);
  436. XMEMCPY(output, Ai, currentLen);
  437. output += currentLen;
  438. kLen -= (int)currentLen;
  439. mp_clear(B1);
  440. }
  441. #ifdef WOLFSSL_SMALL_STACK
  442. out:
  443. if (Ai != NULL)
  444. XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
  445. if (B != NULL)
  446. XFREE(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
  447. if (B1 != NULL)
  448. XFREE(B1, heap, DYNAMIC_TYPE_TMP_BUFFER);
  449. if (i1 != NULL)
  450. XFREE(i1, heap, DYNAMIC_TYPE_TMP_BUFFER);
  451. if (res != NULL)
  452. XFREE(res, heap, DYNAMIC_TYPE_TMP_BUFFER);
  453. #endif
  454. if (dynamic)
  455. XFREE(buffer, heap, DYNAMIC_TYPE_KEY);
  456. return ret;
  457. }
  458. #endif /* HAVE_PKCS12 */
  459. #ifdef HAVE_SCRYPT
  460. #ifdef NO_HMAC
  461. #error scrypt requires HMAC
  462. #endif
  463. /* Rotate the 32-bit value a by b bits to the left.
  464. *
  465. * a 32-bit value.
  466. * b Number of bits to rotate.
  467. * returns rotated value.
  468. */
  469. #define R(a, b) rotlFixed(a, b)
  470. /* (2^32 - 1) */
  471. #define SCRYPT_WORD32_MAX 4294967295U
  472. /* One round of Salsa20/8.
  473. * Code taken from RFC 7914: scrypt PBKDF.
  474. *
  475. * out Output buffer.
  476. * in Input data to hash.
  477. */
  478. static void scryptSalsa(word32* out, word32* in)
  479. {
  480. int i;
  481. word32 x[16];
  482. #ifdef LITTLE_ENDIAN_ORDER
  483. XMEMCPY(x, in, sizeof(x));
  484. #else
  485. for (i = 0; i < 16; i++)
  486. x[i] = ByteReverseWord32(in[i]);
  487. #endif
  488. for (i = 8; i > 0; i -= 2) {
  489. x[ 4] ^= R(x[ 0] + x[12], 7); x[ 8] ^= R(x[ 4] + x[ 0], 9);
  490. x[12] ^= R(x[ 8] + x[ 4], 13); x[ 0] ^= R(x[12] + x[ 8], 18);
  491. x[ 9] ^= R(x[ 5] + x[ 1], 7); x[13] ^= R(x[ 9] + x[ 5], 9);
  492. x[ 1] ^= R(x[13] + x[ 9], 13); x[ 5] ^= R(x[ 1] + x[13], 18);
  493. x[14] ^= R(x[10] + x[ 6], 7); x[ 2] ^= R(x[14] + x[10], 9);
  494. x[ 6] ^= R(x[ 2] + x[14], 13); x[10] ^= R(x[ 6] + x[ 2], 18);
  495. x[ 3] ^= R(x[15] + x[11], 7); x[ 7] ^= R(x[ 3] + x[15], 9);
  496. x[11] ^= R(x[ 7] + x[ 3], 13); x[15] ^= R(x[11] + x[ 7], 18);
  497. x[ 1] ^= R(x[ 0] + x[ 3], 7); x[ 2] ^= R(x[ 1] + x[ 0], 9);
  498. x[ 3] ^= R(x[ 2] + x[ 1], 13); x[ 0] ^= R(x[ 3] + x[ 2], 18);
  499. x[ 6] ^= R(x[ 5] + x[ 4], 7); x[ 7] ^= R(x[ 6] + x[ 5], 9);
  500. x[ 4] ^= R(x[ 7] + x[ 6], 13); x[ 5] ^= R(x[ 4] + x[ 7], 18);
  501. x[11] ^= R(x[10] + x[ 9], 7); x[ 8] ^= R(x[11] + x[10], 9);
  502. x[ 9] ^= R(x[ 8] + x[11], 13); x[10] ^= R(x[ 9] + x[ 8], 18);
  503. x[12] ^= R(x[15] + x[14], 7); x[13] ^= R(x[12] + x[15], 9);
  504. x[14] ^= R(x[13] + x[12], 13); x[15] ^= R(x[14] + x[13], 18);
  505. }
  506. #ifdef LITTLE_ENDIAN_ORDER
  507. for (i = 0; i < 16; ++i)
  508. out[i] = in[i] + x[i];
  509. #else
  510. for (i = 0; i < 16; i++)
  511. out[i] = ByteReverseWord32(ByteReverseWord32(in[i]) + x[i]);
  512. #endif
  513. }
  514. /* Mix a block using Salsa20/8.
  515. * Based on RFC 7914: scrypt PBKDF.
  516. *
  517. * b Blocks to mix.
  518. * y Temporary storage.
  519. * r Size of the block.
  520. */
  521. static void scryptBlockMix(byte* b, byte* y, int r)
  522. {
  523. #ifdef WORD64_AVAILABLE
  524. word64 x[8];
  525. word64* b64 = (word64*)b;
  526. word64* y64 = (word64*)y;
  527. #else
  528. word32 x[16];
  529. word32* b32 = (word32*)b;
  530. word32* y32 = (word32*)y;
  531. #endif
  532. int i;
  533. int j;
  534. /* Step 1. */
  535. XMEMCPY(x, b + (2 * r - 1) * 64, sizeof(x));
  536. /* Step 2. */
  537. for (i = 0; i < 2 * r; i++)
  538. {
  539. #ifdef WORD64_AVAILABLE
  540. for (j = 0; j < 8; j++)
  541. x[j] ^= b64[i * 8 + j];
  542. #else
  543. for (j = 0; j < 16; j++)
  544. x[j] ^= b32[i * 16 + j];
  545. #endif
  546. scryptSalsa((word32*)x, (word32*)x);
  547. XMEMCPY(y + i * 64, x, sizeof(x));
  548. }
  549. /* Step 3. */
  550. for (i = 0; i < r; i++) {
  551. #ifdef WORD64_AVAILABLE
  552. for (j = 0; j < 8; j++) {
  553. b64[i * 8 + j] = y64[2 * i * 8 + j];
  554. b64[(r + i) * 8 + j] = y64[(2 * i + 1) * 8 + j];
  555. }
  556. #else
  557. for (j = 0; j < 16; j++) {
  558. b32[i * 16 + j] = y32[2 * i * 16 + j];
  559. b32[(r + i) * 16 + j] = y32[(2 * i + 1) * 16 + j];
  560. }
  561. #endif
  562. }
  563. }
  564. /* Random oracles mix.
  565. * Based on RFC 7914: scrypt PBKDF.
  566. *
  567. * x Data to mix.
  568. * v Temporary buffer.
  569. * y Temporary buffer for the block mix.
  570. * r Block size parameter.
  571. * n CPU/Memory cost parameter.
  572. */
  573. static void scryptROMix(byte* x, byte* v, byte* y, int r, word32 n)
  574. {
  575. word32 i;
  576. word32 j;
  577. word32 k;
  578. word32 bSz = (word32)(128 * r);
  579. #ifdef WORD64_AVAILABLE
  580. word64* x64 = (word64*)x;
  581. word64* v64 = (word64*)v;
  582. #else
  583. word32* x32 = (word32*)x;
  584. word32* v32 = (word32*)v;
  585. #endif
  586. /* Step 1. X = B (B not needed therefore not implemented) */
  587. /* Step 2. */
  588. for (i = 0; i < n; i++)
  589. {
  590. XMEMCPY(v + i * bSz, x, bSz);
  591. scryptBlockMix(x, y, r);
  592. }
  593. /* Step 3. */
  594. for (i = 0; i < n; i++)
  595. {
  596. #ifdef LITTLE_ENDIAN_ORDER
  597. #ifdef WORD64_AVAILABLE
  598. j = (word32)(*(word64*)(x + (2*r - 1) * 64) & (n-1));
  599. #else
  600. j = *(word32*)(x + (2*r - 1) * 64) & (n-1);
  601. #endif
  602. #else
  603. byte* t = x + (2*r - 1) * 64;
  604. j = (t[0] | (t[1] << 8) | (t[2] << 16) | ((word32)t[3] << 24)) & (n-1);
  605. #endif
  606. #ifdef WORD64_AVAILABLE
  607. for (k = 0; k < bSz / 8; k++)
  608. x64[k] ^= v64[j * bSz / 8 + k];
  609. #else
  610. for (k = 0; k < bSz / 4; k++)
  611. x32[k] ^= v32[j * bSz / 4 + k];
  612. #endif
  613. scryptBlockMix(x, y, r);
  614. }
  615. /* Step 4. B' = X (B = X = B' so not needed, therefore not implemented) */
  616. }
  617. /* Generates an key derived from a password and salt using a memory hard
  618. * algorithm.
  619. * Implements RFC 7914: scrypt PBKDF.
  620. *
  621. * output The derived key.
  622. * passwd The password to derive key from.
  623. * passLen The length of the password.
  624. * salt The key specific data.
  625. * saltLen The length of the salt data.
  626. * cost The CPU/memory cost parameter. Range: 1..(128*r/8-1)
  627. * (Iterations = 2^cost)
  628. * blockSize The number of 128 byte octets in a working block.
  629. * parallel The number of parallel mix operations to perform.
  630. * (Note: this implementation does not use threads.)
  631. * dkLen The length of the derived key in bytes.
  632. * returns BAD_FUNC_ARG when: blockSize is too large for cost.
  633. */
  634. int wc_scrypt(byte* output, const byte* passwd, int passLen,
  635. const byte* salt, int saltLen, int cost, int blockSize,
  636. int parallel, int dkLen)
  637. {
  638. int ret = 0;
  639. int i;
  640. byte* v = NULL;
  641. byte* y = NULL;
  642. byte* blocks = NULL;
  643. word32 blocksSz;
  644. word32 bSz;
  645. if (blockSize > 8)
  646. return BAD_FUNC_ARG;
  647. if (cost < 1 || cost >= 128 * blockSize / 8 || parallel < 1 || dkLen < 1)
  648. return BAD_FUNC_ARG;
  649. /* The following comparison used to be:
  650. * ((word32)parallel > (SCRYPT_MAX / (128 * blockSize)))
  651. * where SCRYPT_MAX is (2^32 - 1) * 32. For some compilers, the RHS of
  652. * the comparison is greater than parallel's type. It wouldn't promote
  653. * both sides to word64. What follows is just arithmetic simplification.
  654. */
  655. if (parallel > (int)((SCRYPT_WORD32_MAX / 4) / (word32)blockSize))
  656. return BAD_FUNC_ARG;
  657. bSz = 128 * (word32)blockSize;
  658. if (parallel > (int)(SCRYPT_WORD32_MAX / bSz))
  659. return BAD_FUNC_ARG;
  660. blocksSz = bSz * (word32)parallel;
  661. blocks = (byte*)XMALLOC((size_t)blocksSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  662. if (blocks == NULL) {
  663. ret = MEMORY_E;
  664. goto end;
  665. }
  666. /* Temporary for scryptROMix. */
  667. v = (byte*)XMALLOC((size_t)((1 << cost) * bSz), NULL,
  668. DYNAMIC_TYPE_TMP_BUFFER);
  669. if (v == NULL) {
  670. ret = MEMORY_E;
  671. goto end;
  672. }
  673. /* Temporary for scryptBlockMix. */
  674. y = (byte*)XMALLOC((size_t)(blockSize * 128), NULL,
  675. DYNAMIC_TYPE_TMP_BUFFER);
  676. if (y == NULL) {
  677. ret = MEMORY_E;
  678. goto end;
  679. }
  680. /* Step 1. */
  681. ret = wc_PBKDF2(blocks, passwd, passLen, salt, saltLen, 1, (int)blocksSz,
  682. WC_SHA256);
  683. if (ret != 0)
  684. goto end;
  685. /* Step 2. */
  686. for (i = 0; i < parallel; i++)
  687. scryptROMix(blocks + i * (int)bSz, v, y, (int)blockSize, 1 << cost);
  688. /* Step 3. */
  689. ret = wc_PBKDF2(output, passwd, passLen, blocks, (int)blocksSz, 1, dkLen,
  690. WC_SHA256);
  691. end:
  692. if (blocks != NULL)
  693. XFREE(blocks, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  694. if (v != NULL)
  695. XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  696. if (y != NULL)
  697. XFREE(y, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  698. return ret;
  699. }
  700. /* Generates an key derived from a password and salt using a memory hard
  701. * algorithm.
  702. * Implements RFC 7914: scrypt PBKDF.
  703. *
  704. * output Derived key.
  705. * passwd Password to derive key from.
  706. * passLen Length of the password.
  707. * salt Key specific data.
  708. * saltLen Length of the salt data.
  709. * iterations Number of iterations to perform. Range: 1 << (1..(128*r/8-1))
  710. * blockSize Number of 128 byte octets in a working block.
  711. * parallel Number of parallel mix operations to perform.
  712. * (Note: this implementation does not use threads.)
  713. * dkLen Length of the derived key in bytes.
  714. * returns BAD_FUNC_ARG when: iterations is not a power of 2 or blockSize is too
  715. * large for iterations.
  716. */
  717. int wc_scrypt_ex(byte* output, const byte* passwd, int passLen,
  718. const byte* salt, int saltLen, word32 iterations,
  719. int blockSize, int parallel, int dkLen)
  720. {
  721. int cost;
  722. /* Iterations must be a power of 2. */
  723. if ((iterations & (iterations - 1)) != 0)
  724. return BAD_FUNC_ARG;
  725. for (cost = -1; iterations != 0; cost++) {
  726. iterations >>= 1;
  727. }
  728. return wc_scrypt(output, passwd, passLen, salt, saltLen, cost, blockSize,
  729. parallel, dkLen);
  730. }
  731. #endif /* HAVE_SCRYPT */
  732. #endif /* NO_PWDBASED */