Пример #1
0
        /// <remarks>
        /// Expand the key and set state variables
        /// </remarks>
        private UInt32[] ExpandKey(byte[] Key, bool Encryption)
        {
            // block and key in 32 bit words
            _wrdBlocks = _blockSize / 4;

            // expanded key size
            int keySize = _wrdBlocks * (_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
            UInt32[] wK = new UInt32[keySize];
            // copy bytes to working key
            Buffer.BlockCopy(rawKey, 0, wK, 0, keyBytes);

            // inverse cipher
            if (!Encryption)
            {
                // reverse key
                for (int i = 0, k = keySize - _wrdBlocks; i < k; i += _wrdBlocks, k -= _wrdBlocks)
                {
                    for (int j = 0; j < _wrdBlocks; j++)
                    {
                        UInt32 temp = wK[i + j];
                        wK[i + j] = wK[k + j];
                        wK[k + j] = temp;
                    }
                }
                // sbox inversion
                for (int i = _wrdBlocks; i < keySize - _wrdBlocks; i++)
                {
                    wK[i] = IT0[SBox[(wK[i] >> 24)]] ^
                        IT1[SBox[(byte)(wK[i] >> 16)]] ^
                        IT2[SBox[(byte)(wK[i] >> 8)]] ^
                        IT3[SBox[(byte)wK[i]]];
                }
            }

            return wK;
        }
Пример #2
0
        private Int32[] ExpandKey(byte[] Key)
        {
            Int32 Y0, Y1, Y2, Y3;
            int k64Cnt = 8;
            int keyCtr = 0;
            int keySize = _dfnRounds * 2 + 8;
            int kbtSize = keySize * 4;
            byte[] rawKey = new byte[kbtSize];
            byte[] sbKey = new byte[32];
            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;

            // create keyed sbox
            while (keyCtr < KEY_BITS)
            {
                Y0 = Y1 = Y2 = Y3 = keyCtr;

                Y0 = (byte)Q1[Y0] ^ sbKey[28];
                Y1 = (byte)Q0[Y1] ^ sbKey[29];
                Y2 = (byte)Q0[Y2] ^ sbKey[30];
                Y3 = (byte)Q1[Y3] ^ sbKey[31];

                Y0 = (byte)Q1[Y0] ^ sbKey[24];
                Y1 = (byte)Q1[Y1] ^ sbKey[25];
                Y2 = (byte)Q0[Y2] ^ sbKey[26];
                Y3 = (byte)Q0[Y3] ^ sbKey[27];

                Y0 = (byte)Q0[Y0] ^ sbKey[20];
                Y1 = (byte)Q1[Y1] ^ sbKey[21];
                Y2 = (byte)Q1[Y2] ^ sbKey[22];
                Y3 = (byte)Q0[Y3] ^ sbKey[23];

                Y0 = (byte)Q0[Y0] ^ sbKey[16];
                Y1 = (byte)Q0[Y1] ^ sbKey[17];
                Y2 = (byte)Q1[Y2] ^ sbKey[18];
                Y3 = (byte)Q1[Y3] ^ sbKey[19];

                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;
        }
Пример #3
0
        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;
        }
Пример #4
0
        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 (Compare.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 SHA256HMAC()))
            {
                gen.Initialize(Salt, Key, Info);
                gen.Generate(outBytes, 0, Size);
            }

            if (Compare.AreEqual(outBytes, Output) == false)
                throw new Exception("HKDF: Values are not equal! Expected: " + HexConverter.ToString(Output) + " Received: " + HexConverter.ToString(outBytes));
        }