void ExpandKey(byte[] key, byte[] salt, EksBlowfishKeyExpansionFlags flags) { uint[] p = P; uint[][] s = S; int i, j, k; uint data, datal, datar; j = 0; for (i = 0; i < p.Length; i++) { data = 0x00000000; for (k = 0; k < 4; k++) { if ((flags & EksBlowfishKeyExpansionFlags.EmulateCryptBlowfishSignExtensionBug) != 0) { data = (data << 8) | (uint)(int)(sbyte)key[j]; } else { data = (data << 8) | key[j]; } j = (j + 1) % key.Length; } p[i] = p[i] ^ data; } uint saltL0 = BitPacking.UInt32FromBEBytes(salt, 0); uint saltR0 = BitPacking.UInt32FromBEBytes(salt, 4); uint saltL1 = BitPacking.UInt32FromBEBytes(salt, 8); uint saltR1 = BitPacking.UInt32FromBEBytes(salt, 12); datal = 0x00000000; datar = 0x00000000; for (i = 0; i < p.Length; i += 4) { datal ^= saltL0; datar ^= saltR0; Encipher(ref datal, ref datar); p[i + 0] = datal; p[i + 1] = datar; if (i + 2 == p.Length) { break; } // 18 here datal ^= saltL1; datar ^= saltR1; Encipher(ref datal, ref datar); p[i + 2] = datal; p[i + 3] = datar; } for (i = 0; i < s.Length; i++) { uint[] sb = s[i]; for (j = 0; j < sb.Length; j += 4) { datal ^= saltL1; datar ^= saltR1; Encipher(ref datal, ref datar); sb[j + 0] = datal; sb[j + 1] = datar; datal ^= saltL0; datar ^= saltR0; Encipher(ref datal, ref datar); sb[j + 2] = datal; sb[j + 3] = datar; } } }
static BlowfishCipher() { byte[] magicBytes = Encoding.ASCII.GetBytes(BCryptMagic); Array.Resize(ref magicBytes, (magicBytes.Length + 7) / 8 * 8); Magic = new uint[(magicBytes.Length + 3) / 4]; for (int i = 0; i < Magic.Length; i++) { Magic[i] = BitPacking.UInt32FromBEBytes(magicBytes, i * 4); } }
/// <summary> /// Reverses the encipherment of eight bytes of data from one buffer and places the result in another buffer. /// </summary> /// <param name="inputBuffer">The buffer to read enciphered data from.</param> /// <param name="inputOffset">The offset of the first enciphered byte.</param> /// <param name="outputBuffer">The buffer to write plaintext data to.</param> /// <param name="outputOffset">The offset at which to place the first plaintext byte.</param> public void Decipher (byte[] inputBuffer, int inputOffset, byte[] outputBuffer, int outputOffset) { CheckCipherBuffers(inputBuffer, inputOffset, outputBuffer, outputOffset); uint xl = BitPacking.UInt32FromBEBytes(inputBuffer, inputOffset + 0); uint xr = BitPacking.UInt32FromBEBytes(inputBuffer, inputOffset + 4); Decipher(ref xl, ref xr); BitPacking.BEBytesFromUInt32(xl, outputBuffer, outputOffset + 0); BitPacking.BEBytesFromUInt32(xr, outputBuffer, outputOffset + 4); }