private BlockCipherAdapter GetCipher()
        {
            var cipher = _cipherSuitesProvider.ResolveCipherAlgorithm(_cipherSuiteConfig.CipherSuite);

            if (cipher is BlockCipherAdapter adapter)
            {
                return(adapter);
            }

            if (cipher is IBlockCipher blockCipher)
            {
                return(new BlockCipherAdapter(blockCipher));
            }

            throw new InvalidCastException("Cipher isn't a block cipher");
        }
예제 #2
0
        private IAEADBlockCipher GetCipher()
        {
            var cipher = _cipherSuitesProvider.ResolveCipherAlgorithm(_cipherSuiteConfig.CipherSuite);

            if (cipher is AEADCipherAdapter adapter)
            {
                return(adapter.Cipher);
            }

            // ReSharper disable SuspiciousTypeConversion.Global
            if (cipher is IAEADBlockCipher aeadCipher)
            {
                return(aeadCipher);
            }
            // ReSharper enable SuspiciousTypeConversion.Global

            throw new InvalidCastException("Cipher isn't an AEAD cipher");
        }
예제 #3
0
 private ICipher GetCipher()
 {
     return(_cipherSuitesProvider.ResolveCipherAlgorithm(_cipherSuiteConfig.CipherSuite));
 }
예제 #4
0
        public void ComputeKeysAndUpdateConfig(byte[] masterSecret)
        {
            if (_randomConfig.Client is null || _randomConfig.Server is null)
            {
                throw new InvalidOperationException("Random config is not initialized");
            }

            _keyConfig.Master = masterSecret;

            var cipherSuite = _cipherSuiteConfig.CipherSuite;

            var clientRandom = _randomConfig.Client;
            var serverRandom = _randomConfig.Server;

            var cipher = _cipherSuitesProvider.ResolveCipherAlgorithm(cipherSuite);
            var mac    = _cipherSuitesProvider.ResolveHashAlgorithm(cipherSuite);

            var prfDigest = _cipherSuitesProvider.ResolvePRFHash(_cipherSuiteConfig.CipherSuite);
            var prf       = new PRF(prfDigest);

            var random = new byte[serverRandom.Length + clientRandom.Length];

            Array.Copy(serverRandom, 0, random, 0, serverRandom.Length);
            Array.Copy(clientRandom, 0, random, serverRandom.Length, clientRandom.Length);

            var macKeyLength = mac.HashSize / 8;
            var encKeyLength = cipher.KeySize;
            // for AEAD - TODO is it constant?
            var implicitIVLength = 4;

            var keyBlockLength = 2 * macKeyLength + 2 * encKeyLength + 2 * implicitIVLength;

            var keyBlock = prf.Digest(masterSecret, "key expansion", random).Take(keyBlockLength).ToArray();

            var offset = 0;

            // TODO technically AEAD has no mac (i.e. length == 0)
            if (!_cipherSuitesProvider.IsAEADCipher(cipherSuite))
            {
                var clientMACKey = new byte[macKeyLength];
                Array.Copy(keyBlock, offset, clientMACKey, 0, macKeyLength);
                offset += macKeyLength;
                _blockConfig.ClientMACKey = clientMACKey;

                var serverMACKey = new byte[macKeyLength];
                Array.Copy(keyBlock, offset, serverMACKey, 0, macKeyLength);
                offset += macKeyLength;
                _blockConfig.ServerMACKey = serverMACKey;
            }

            var clientKey = new byte[encKeyLength];

            Array.Copy(keyBlock, offset, clientKey, 0, encKeyLength);
            offset           += encKeyLength;
            _keyConfig.Client = clientKey;

            var serverKey = new byte[encKeyLength];

            Array.Copy(keyBlock, offset, serverKey, 0, encKeyLength);
            offset           += encKeyLength;
            _keyConfig.Server = serverKey;

            if (_cipherSuitesProvider.IsAEADCipher(cipherSuite))
            {
                var clientIV = new byte[implicitIVLength];
                Array.Copy(keyBlock, offset, clientIV, 0, implicitIVLength);
                offset += implicitIVLength;
                _aeadConfig.ClientIV = clientIV;

                var serverIV = new byte[implicitIVLength];
                Array.Copy(keyBlock, offset, serverIV, 0, implicitIVLength);
                offset += implicitIVLength;
                _aeadConfig.ServerIV = serverIV;
            }
        }
        public static bool IsAEADCipher(this ICipherSuitesProvider cipherSuiteProvider, CipherSuite cipherSuite)
        {
            var cipherAlgorithm = cipherSuiteProvider.ResolveCipherAlgorithm(cipherSuite);

            return(cipherAlgorithm is AEADCipherAdapter || cipherAlgorithm is IAEADBlockCipher);
        }