private void HKDFTest(int Size, byte[] Salt, byte[] Key, byte[] Info, byte[] Output) { byte[] outBytes = new byte[Size]; using (HKDF gen = new HKDF(new SHA256())) { gen.Initialize(Salt, Key, Info); gen.Generate(outBytes, 0, Size); } if (Evaluate.AreEqual(outBytes, Output) == false) { throw new Exception("HKDF: Values are not equal! Expected: " + HexConverter.ToString(Output) + " Received: " + HexConverter.ToString(outBytes)); } using (HKDF gen = new HKDF(new HMAC(new SHA256()))) { gen.Initialize(Salt, Key, Info); gen.Generate(outBytes, 0, Size); } if (Evaluate.AreEqual(outBytes, Output) == false) { throw new Exception("HKDF: Values are not equal! Expected: " + HexConverter.ToString(Output) + " Received: " + HexConverter.ToString(outBytes)); } }
private uint[] SecureExpand(byte[] Key) { // expanded key size int keySize = 4 * (m_rndCount + 1); // hkdf return array int keyBytes = keySize * 4; byte[] rawKey = new byte[keyBytes]; HKDF gen = new HKDF(m_kdfExtractor); // change 1.2: use extract only on an oversized key if (Key.Length > m_kdfExtractor.BlockSize) { // seperate salt and key m_kdfKeySize = m_kdfExtractor.BlockSize; byte[] kdfKey = new byte[m_kdfKeySize]; Buffer.BlockCopy(Key, 0, kdfKey, 0, m_kdfKeySize); int saltSize = Key.Length - m_kdfKeySize; byte[] kdfSalt = new byte[saltSize]; Buffer.BlockCopy(Key, m_kdfKeySize, kdfSalt, 0, saltSize); // info can be null gen.Initialize(kdfKey, kdfSalt, m_kdfInfo); } else { if (m_kdfInfo.Length != 0) { gen.Info = m_kdfInfo; } gen.Initialize(Key); } gen.Generate(rawKey); gen.Dispose(); // initialize working key uint[] expKey = new uint[keySize]; // copy bytes to working key Buffer.BlockCopy(rawKey, 0, expKey, 0, keyBytes); return(expKey); }
private Int32[] ExpandKey(byte[] Key) { // expanded key size int keySize = 4 * (_dfnRounds + 1); // hkdf return array int keyBytes = keySize * 4; byte[] rawKey = new byte[keyBytes]; int saltSize = Key.Length - _ikmSize; // salt must be divisible of hash blocksize if (saltSize % _keyEngine.BlockSize != 0) { saltSize = saltSize - saltSize % _keyEngine.BlockSize; } // hkdf input byte[] hkdfKey = new byte[_ikmSize]; byte[] hkdfSalt = new byte[saltSize]; // copy hkdf key and salt from user key Buffer.BlockCopy(Key, 0, hkdfKey, 0, _ikmSize); Buffer.BlockCopy(Key, _ikmSize, hkdfSalt, 0, saltSize); // HKDF generator expands array using an SHA512 HMAC using (HKDF gen = new HKDF(_keyEngine, false)) { gen.Initialize(hkdfSalt, hkdfKey, _hkdfInfo); gen.Generate(rawKey); } // initialize working key Int32[] wK = new Int32[keySize]; // copy bytes to working key Buffer.BlockCopy(rawKey, 0, wK, 0, keyBytes); return(wK); }
private Int32[] ExpandKey(byte[] Key) { Int32 Y0, Y1, Y2, Y3; int k64Cnt = 4; int keyCtr = 0; int keySize = _dfnRounds * 2 + 8; int kbtSize = keySize * 4; byte[] rawKey = new byte[kbtSize]; byte[] sbKey = new byte[16]; Int32[] eKm = new Int32[k64Cnt]; Int32[] oKm = new Int32[k64Cnt]; Int32[] wK = new Int32[keySize]; int saltSize = Key.Length - _ikmSize; // salt must be divisible of hash blocksize if (saltSize % _keyEngine.BlockSize != 0) { saltSize = saltSize - saltSize % _keyEngine.BlockSize; } // hkdf input byte[] hkdfKey = new byte[_ikmSize]; byte[] hkdfSalt = new byte[saltSize]; // copy hkdf key and salt from user key Buffer.BlockCopy(Key, 0, hkdfKey, 0, _ikmSize); Buffer.BlockCopy(Key, _ikmSize, hkdfSalt, 0, saltSize); // HKDF generator expands array using an SHA512 HMAC using (HKDF gen = new HKDF(_keyEngine, false)) { gen.Initialize(hkdfSalt, hkdfKey, _hkdfInfo); gen.Generate(rawKey); } // copy bytes to working key Buffer.BlockCopy(rawKey, 0, wK, 0, kbtSize); for (int i = 0; i < k64Cnt; i++) { // round key material eKm[i] = BytesToInt32(rawKey, keyCtr); keyCtr += 4; oKm[i] = BytesToInt32(rawKey, keyCtr); keyCtr += 4; // sbox key material Int32ToBytes(MDSEncode(eKm[i], oKm[i]), sbKey, ((4 * k64Cnt) - 4) - (i * 4)); } keyCtr = 0; while (keyCtr < KEY_BITS) { Y0 = Y1 = Y2 = Y3 = keyCtr; Y0 = (byte)Q1[Y0] ^ sbKey[12]; Y1 = (byte)Q0[Y1] ^ sbKey[13]; Y2 = (byte)Q0[Y2] ^ sbKey[14]; Y3 = (byte)Q1[Y3] ^ sbKey[15]; Y0 = (byte)Q1[Y0] ^ sbKey[8]; Y1 = (byte)Q1[Y1] ^ sbKey[9]; Y2 = (byte)Q0[Y2] ^ sbKey[10]; Y3 = (byte)Q0[Y3] ^ sbKey[11]; // sbox members as MDS matrix multiplies _sprBox[keyCtr * 2] = MDS0[(byte)Q0[(byte)Q0[Y0] ^ sbKey[4]] ^ sbKey[0]]; _sprBox[keyCtr * 2 + 1] = MDS1[(byte)Q0[Q1[Y1] ^ sbKey[5]] ^ sbKey[1]]; _sprBox[(keyCtr * 2) + 0x200] = MDS2[(byte)Q1[(byte)Q0[Y2] ^ sbKey[6]] ^ sbKey[2]]; _sprBox[keyCtr++ *2 + 0x201] = MDS3[(byte)Q1[(byte)Q1[Y3] ^ sbKey[7]] ^ sbKey[3]]; } return(wK); }