CryptX
view release on metacpan or search on metacpan
src/ltc/misc/bcrypt/bcrypt.c view on Meta::CPAN
#ifdef LTC_BCRYPT
#define BCRYPT_WORDS 8
#define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4)
static int s_bcrypt_hash(const unsigned char *pt,
const unsigned char *pass, unsigned long passlen,
const unsigned char *salt, unsigned long saltlen,
unsigned char *out, unsigned long *outlen)
{
symmetric_key key;
int err, n;
ulong32 ct[BCRYPT_WORDS];
if ((err = blowfish_setup_with_data(pass, passlen, salt, saltlen, &key)) != CRYPT_OK) {
return err;
}
for (n = 0; n < 64; ++n) {
if ((err = blowfish_expand(salt, saltlen, NULL, 0, &key)) != CRYPT_OK) {
return err;
}
if ((err = blowfish_expand(pass, passlen, NULL, 0, &key)) != CRYPT_OK) {
return err;
}
}
for (n = 0; n < BCRYPT_WORDS; ++n) {
LOAD32H(ct[n], &pt[n*4]);
}
for (n = 0; n < 64; ++n) {
blowfish_enc(ct, BCRYPT_WORDS/2, &key);
}
for (n = 0; n < BCRYPT_WORDS; ++n) {
STORE32L(ct[n], &out[4 * n]);
}
*outlen = sizeof(ct);
#ifdef LTC_CLEAN_STACK
zeromem(&key, sizeof(key));
zeromem(ct, sizeof(ct));
#endif
return CRYPT_OK;
}
static int s_bcrypt_pbkdf_hash(const unsigned char *pass, unsigned long passlen,
const unsigned char *salt, unsigned long saltlen,
unsigned char *out, unsigned long *outlen)
{
const unsigned char pt[] = "OxychromaticBlowfishSwatDynamite";
return s_bcrypt_hash(pt, pass, passlen, salt, saltlen, out, outlen);
}
/**
Compatible to bcrypt_pbkdf() as provided in OpenBSD
@param password The input password (or key)
@param password_len The length of the password (octets)
@param salt The salt (or nonce)
@param salt_len The length of the salt (octets)
@param rounds # of iterations desired [read specs for more]
@param hash_idx The index of the hash desired
@param out [out] The destination for this algorithm
@param outlen [in/out] The desired size of the algorithm output
@return CRYPT_OK if successful
*/
int bcrypt_pbkdf_openbsd(const void *secret, unsigned long secret_len,
const unsigned char *salt, unsigned long salt_len,
unsigned int rounds, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
int err;
ulong32 blkno;
unsigned long left, itts, x, y, hashed_pass_len, step_size, steps, dest, used_rounds;
unsigned char *buf[3], blkbuf[4];
unsigned char *hashed_pass;
LTC_ARGCHK(secret != NULL);
LTC_ARGCHK(salt != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((secret_len == 0) || (salt_len == 0) || (*outlen == 0)) {
return CRYPT_INVALID_ARG;
}
/* test hash IDX */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* set default value for rounds if not given */
if (rounds == 0) {
used_rounds = LTC_BCRYPT_DEFAULT_ROUNDS;
} else {
used_rounds = rounds;
}
buf[0] = XMALLOC(MAXBLOCKSIZE * 3);
hashed_pass = XMALLOC(MAXBLOCKSIZE);
if (buf[0] == NULL || hashed_pass == NULL) {
if (hashed_pass != NULL) {
XFREE(hashed_pass);
}
if (buf[0] != NULL) {
XFREE(buf[0]);
}
return CRYPT_MEM;
}
/* buf[1] points to the second block of MAXBLOCKSIZE bytes */
buf[1] = buf[0] + MAXBLOCKSIZE;
buf[2] = buf[1] + MAXBLOCKSIZE;
step_size = (*outlen + BCRYPT_HASHSIZE - 1) / BCRYPT_HASHSIZE;
steps = (*outlen + step_size - 1) / step_size;
hashed_pass_len = MAXBLOCKSIZE;
if ((err = hash_memory(hash_idx, (unsigned char*)secret, secret_len, hashed_pass, &hashed_pass_len)) != CRYPT_OK) {
goto LBL_ERR;
}
left = *outlen;
blkno = 0;
( run in 1.283 second using v1.01-cache-2.11-cpan-71847e10f99 )