/** * Perform the central password hashing step in the bcrypt scheme * * @param password the password to hash * @param salt the binary salt to hash with the password * @param log_rounds the binary logarithm of the number of rounds of hashing to apply * @return an array containing the binary hashed password */ private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) { int rounds, i, j; int cdata[] = (int[]) bf_crypt_ciphertext.clone(); int clen = cdata.length; byte ret[]; if (log_rounds < 4 || log_rounds > 31) throw new IllegalArgumentException("Bad number of rounds"); rounds = 1 << log_rounds; if (salt.length != BCRYPT_SALT_LEN) throw new IllegalArgumentException("Bad salt length"); init_key(); ekskey(salt, password); for (i = 0; i < rounds; i++) { key(password); key(salt); } for (i = 0; i < 64; i++) { for (j = 0; j < (clen >> 1); j++) encipher(cdata, j << 1); } ret = new byte[clen * 4]; for (i = 0, j = 0; i < clen; i++) { ret[j++] = (byte) ((cdata[i] >> 24) & 0xff); ret[j++] = (byte) ((cdata[i] >> 16) & 0xff); ret[j++] = (byte) ((cdata[i] >> 8) & 0xff); ret[j++] = (byte) (cdata[i] & 0xff); } return ret; }
/** * Key the Blowfish cipher * * @param key an array containing the key */ private void key(byte key[]) { int i; int koffp[] = {0}; int lr[] = {0, 0}; int plen = P.length, slen = S.length; for (i = 0; i < plen; i++) P[i] = P[i] ^ streamtoword(key, koffp); for (i = 0; i < plen; i += 2) { encipher(lr, 0); P[i] = lr[0]; P[i + 1] = lr[1]; } for (i = 0; i < slen; i += 2) { encipher(lr, 0); S[i] = lr[0]; S[i + 1] = lr[1]; } }