pkcs_5_2.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtomcrypt.org
  10. */
  11. #include <mycrypt.h>
  12. /* PKCS #5, Algorithm #2 */
  13. #ifdef PKCS_5
  14. int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
  15. const unsigned char *salt, unsigned long salt_len,
  16. int iteration_count, int hash_idx,
  17. unsigned char *out, unsigned long *outlen)
  18. {
  19. int err, itts;
  20. unsigned long stored, left, x, y, blkno;
  21. unsigned char *buf[2];
  22. hmac_state *hmac;
  23. _ARGCHK(password != NULL);
  24. _ARGCHK(salt != NULL);
  25. _ARGCHK(out != NULL);
  26. _ARGCHK(outlen != NULL);
  27. /* test hash IDX */
  28. if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
  29. return err;
  30. }
  31. buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
  32. hmac = XMALLOC(sizeof(hmac_state));
  33. if (hmac == NULL || buf[0] == NULL) {
  34. if (hmac != NULL) {
  35. XFREE(hmac);
  36. }
  37. if (buf[0] != NULL) {
  38. XFREE(buf[0]);
  39. }
  40. return CRYPT_MEM;
  41. }
  42. /* buf[1] points to the second block of MAXBLOCKSIZE bytes */
  43. buf[1] = buf[0] + MAXBLOCKSIZE;
  44. left = *outlen;
  45. blkno = 1;
  46. stored = 0;
  47. while (left != 0) {
  48. /* process block number blkno */
  49. zeromem(buf[0], MAXBLOCKSIZE*2);
  50. /* store current block number and increment for next pass */
  51. STORE32H(blkno, buf[1]);
  52. ++blkno;
  53. /* get PRF(P, S||int(blkno)) */
  54. if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) {
  55. goto __ERR;
  56. }
  57. if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
  58. goto __ERR;
  59. }
  60. if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
  61. goto __ERR;
  62. }
  63. x = MAXBLOCKSIZE;
  64. if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
  65. goto __ERR;
  66. }
  67. /* now compute repeated and XOR it in buf[1] */
  68. XMEMCPY(buf[1], buf[0], x);
  69. for (itts = 1; itts < iteration_count; ++itts) {
  70. if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
  71. goto __ERR;
  72. }
  73. for (y = 0; y < x; y++) {
  74. buf[1][y] ^= buf[0][y];
  75. }
  76. }
  77. /* now emit upto x bytes of buf[1] to output */
  78. for (y = 0; y < x && left != 0; ++y) {
  79. out[stored++] = buf[1][y];
  80. --left;
  81. }
  82. }
  83. *outlen = stored;
  84. err = CRYPT_OK;
  85. __ERR:
  86. #ifdef CLEAN_STACK
  87. zeromem(buf[0], MAXBLOCKSIZE*2);
  88. zeromem(hmac, sizeof(hmac_state));
  89. #endif
  90. XFREE(hmac);
  91. XFREE(buf[0]);
  92. return err;
  93. }
  94. #endif