Path: blob/master/libs/tomcrypt/src/misc/pkcs5/pkcs_5_2.c
5972 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910/**11@file pkcs_5_2.c12PKCS #5, Algorithm #2, Tom St Denis13*/14#ifdef LTC_PKCS_51516/**17Execute PKCS #5 v218@param password The input password (or key)19@param password_len The length of the password (octets)20@param salt The salt (or nonce)21@param salt_len The length of the salt (octets)22@param iteration_count # of iterations desired for PKCS #5 v2 [read specs for more]23@param hash_idx The index of the hash desired24@param out [out] The destination for this algorithm25@param outlen [in/out] The max size and resulting size of the algorithm output26@return CRYPT_OK if successful27*/28int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,29const unsigned char *salt, unsigned long salt_len,30int iteration_count, int hash_idx,31unsigned char *out, unsigned long *outlen)32{33int err, itts;34ulong32 blkno;35unsigned long stored, left, x, y;36unsigned char *buf[2];37hmac_state *hmac;3839LTC_ARGCHK(password != NULL);40LTC_ARGCHK(salt != NULL);41LTC_ARGCHK(out != NULL);42LTC_ARGCHK(outlen != NULL);4344/* test hash IDX */45if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {46return err;47}4849buf[0] = XMALLOC(MAXBLOCKSIZE * 2);50hmac = XMALLOC(sizeof(hmac_state));51if (hmac == NULL || buf[0] == NULL) {52if (hmac != NULL) {53XFREE(hmac);54}55if (buf[0] != NULL) {56XFREE(buf[0]);57}58return CRYPT_MEM;59}60/* buf[1] points to the second block of MAXBLOCKSIZE bytes */61buf[1] = buf[0] + MAXBLOCKSIZE;6263left = *outlen;64blkno = 1;65stored = 0;66while (left != 0) {67/* process block number blkno */68zeromem(buf[0], MAXBLOCKSIZE*2);6970/* store current block number and increment for next pass */71STORE32H(blkno, buf[1]);72++blkno;7374/* get PRF(P, S||int(blkno)) */75if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) {76goto LBL_ERR;77}78if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {79goto LBL_ERR;80}81if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {82goto LBL_ERR;83}84x = MAXBLOCKSIZE;85if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {86goto LBL_ERR;87}8889/* now compute repeated and XOR it in buf[1] */90XMEMCPY(buf[1], buf[0], x);91for (itts = 1; itts < iteration_count; ++itts) {92if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {93goto LBL_ERR;94}95for (y = 0; y < x; y++) {96buf[1][y] ^= buf[0][y];97}98}99100/* now emit upto x bytes of buf[1] to output */101for (y = 0; y < x && left != 0; ++y) {102out[stored++] = buf[1][y];103--left;104}105}106*outlen = stored;107108err = CRYPT_OK;109LBL_ERR:110#ifdef LTC_CLEAN_STACK111zeromem(buf[0], MAXBLOCKSIZE*2);112zeromem(hmac, sizeof(hmac_state));113#endif114115XFREE(hmac);116XFREE(buf[0]);117118return err;119}120121#endif122123124