pwdbased.c 21 KB

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