packages feed

g3p-hash-1.0.0.0: csrc/bcrypt_raw.c

/* lightly modified and aggressively stripped down version of OpenBSD's implementation of BCrypt */

#include <string.h>
#include "g3p_blf.h"
#include "bcrypt_raw.h"

#define BCRYPT_WORDS 6

void
bcrypt_raw ( const char *key, uint32_t keybytes,
             const char *salt, uint32_t saltbytes,
             char output[BCRYPT_RAW_OUTPUT_LENGTH],
             uint32_t rounds) {
  G3P_blf_ctx state;
  uint8_t ciphertext[BCRYPT_RAW_OUTPUT_LENGTH] = "OrpheanBeholderScryDoubt";
	uint32_t cdata[BCRYPT_WORDS];

	/* Setting up S-Boxes and Subkeys */
	G3P_Blowfish_initstate(&state);
	G3P_Blowfish_expandstate(&state,
	    (const uint8_t *) salt, saltbytes,
	    (const uint8_t *) key, keybytes);

	/* Written so that things work when rounds == UINT32_MAX */
	rounds++;
	do {
		G3P_Blowfish_expand0state(&state, (const uint8_t *) key, keybytes);
		G3P_Blowfish_expand0state(&state, (const uint8_t *) salt, saltbytes);
		rounds--;
	} while (rounds != 0);

	uint16_t j = 0;
	for (uint32_t i = 0; i < BCRYPT_WORDS; i++)
		cdata[i] = G3P_Blowfish_stream2word(ciphertext, 4 * BCRYPT_WORDS, &j);

	/* Now do the encryption */
	for (uint32_t k = 0; k < 64; k++)
		G3P_blf_enc(&state, cdata, BCRYPT_WORDS / 2);

	for (uint32_t i = 0; i < BCRYPT_WORDS; i++) {
		ciphertext[4 * i + 3] = cdata[i] & 0xff;
		cdata[i] = cdata[i] >> 8;
		ciphertext[4 * i + 2] = cdata[i] & 0xff;
		cdata[i] = cdata[i] >> 8;
		ciphertext[4 * i + 1] = cdata[i] & 0xff;
		cdata[i] = cdata[i] >> 8;
		ciphertext[4 * i + 0] = cdata[i] & 0xff;
	}

	memcpy(output, ciphertext, BCRYPT_RAW_OUTPUT_LENGTH);
	explicit_bzero(&state, sizeof(state));
	explicit_bzero(ciphertext, sizeof(ciphertext));
        explicit_bzero(cdata, sizeof(cdata));
}