/* lightly modified and aggressively stripped down version of OpenBSD's implementation of BCrypt */ #include #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)); }