pwdbased.c 23 KB

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