< Summary

Information
Class: Renci.SshNet.Security.Cryptography.Ciphers.TripleDesCipher
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\Cryptography\Ciphers\TripleDesCipher.cs
Line coverage
77%
Covered lines: 55
Uncovered lines: 16
Coverable lines: 71
Total lines: 154
Line coverage: 77.4%
Branch coverage
73%
Covered branches: 22
Total branches: 30
Branch coverage: 73.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
EncryptBlock(...)75%1277.41%
DecryptBlock(...)75%1277.41%
ValidateKey()66.66%666.66%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\Cryptography\Ciphers\TripleDesCipher.cs

#LineLine coverage
 1using System;
 2
 3namespace Renci.SshNet.Security.Cryptography.Ciphers
 4{
 5    /// <summary>
 6    /// Implements 3DES cipher algorithm.
 7    /// </summary>
 8    public sealed class TripleDesCipher : DesCipher
 9    {
 10        private int[] _encryptionKey1;
 11        private int[] _encryptionKey2;
 12        private int[] _encryptionKey3;
 13        private int[] _decryptionKey1;
 14        private int[] _decryptionKey2;
 15        private int[] _decryptionKey3;
 16
 17        /// <summary>
 18        /// Initializes a new instance of the <see cref="TripleDesCipher"/> class.
 19        /// </summary>
 20        /// <param name="key">The key.</param>
 21        /// <param name="mode">The mode.</param>
 22        /// <param name="padding">The padding.</param>
 23        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <see langword="null"/>.</exception>
 24        public TripleDesCipher(byte[] key, CipherMode mode, CipherPadding padding)
 2525            : base(key, mode, padding)
 2526        {
 2527        }
 28
 29        /// <summary>
 30        /// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region 
 31        /// </summary>
 32        /// <param name="inputBuffer">The input data to encrypt.</param>
 33        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
 34        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
 35        /// <param name="outputBuffer">The output to which to write encrypted data.</param>
 36        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
 37        /// <returns>
 38        /// The number of bytes encrypted.
 39        /// </returns>
 40        public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int o
 53941        {
 53942            if ((inputOffset + BlockSize) > inputBuffer.Length)
 043            {
 044                throw new ArgumentException("input buffer too short");
 45            }
 46
 53947            if ((outputOffset + BlockSize) > outputBuffer.Length)
 048            {
 049                throw new ArgumentException("output buffer too short");
 50            }
 51
 53952            if (_encryptionKey1 is null || _encryptionKey2 is null || _encryptionKey3 is null)
 953            {
 954                var part1 = new byte[8];
 955                var part2 = new byte[8];
 56
 957                Buffer.BlockCopy(Key, 0, part1, 0, 8);
 958                Buffer.BlockCopy(Key, 8, part2, 0, 8);
 59
 960                _encryptionKey1 = GenerateWorkingKey(encrypting: true, part1);
 961                _encryptionKey2 = GenerateWorkingKey(encrypting: false, part2);
 62
 963                if (Key.Length == 24)
 964                {
 965                    var part3 = new byte[8];
 966                    Buffer.BlockCopy(Key, 16, part3, 0, 8);
 67
 968                    _encryptionKey3 = GenerateWorkingKey(encrypting: true, part3);
 969                }
 70                else
 071                {
 072                    _encryptionKey3 = _encryptionKey1;
 073                }
 974            }
 75
 53976            var temp = new byte[BlockSize];
 77
 53978            DesFunc(_encryptionKey1, inputBuffer, inputOffset, temp, 0);
 53979            DesFunc(_encryptionKey2, temp, 0, temp, 0);
 53980            DesFunc(_encryptionKey3, temp, 0, outputBuffer, outputOffset);
 81
 53982            return BlockSize;
 53983        }
 84
 85        /// <summary>
 86        /// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region 
 87        /// </summary>
 88        /// <param name="inputBuffer">The input data to decrypt.</param>
 89        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
 90        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
 91        /// <param name="outputBuffer">The output to which to write decrypted data.</param>
 92        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
 93        /// <returns>
 94        /// The number of bytes decrypted.
 95        /// </returns>
 96        public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int o
 161897        {
 161898            if ((inputOffset + BlockSize) > inputBuffer.Length)
 099            {
 0100                throw new ArgumentException("input buffer too short");
 101            }
 102
 1618103            if ((outputOffset + BlockSize) > outputBuffer.Length)
 0104            {
 0105                throw new ArgumentException("output buffer too short");
 106            }
 107
 1618108            if (_decryptionKey1 is null || _decryptionKey2 is null || _decryptionKey3 is null)
 16109            {
 16110                var part1 = new byte[8];
 16111                var part2 = new byte[8];
 112
 16113                Buffer.BlockCopy(Key, 0, part1, 0, 8);
 16114                Buffer.BlockCopy(Key, 8, part2, 0, 8);
 115
 16116                _decryptionKey1 = GenerateWorkingKey(encrypting: false, part1);
 16117                _decryptionKey2 = GenerateWorkingKey(encrypting: true, part2);
 118
 16119                if (Key.Length == 24)
 16120                {
 16121                    var part3 = new byte[8];
 16122                    Buffer.BlockCopy(Key, 16, part3, 0, 8);
 123
 16124                    _decryptionKey3 = GenerateWorkingKey(encrypting: false, part3);
 16125                }
 126                else
 0127                {
 0128                    _decryptionKey3 = _decryptionKey1;
 0129                }
 16130            }
 131
 1618132            var temp = new byte[BlockSize];
 133
 1618134            DesFunc(_decryptionKey3, inputBuffer, inputOffset, temp, 0);
 1618135            DesFunc(_decryptionKey2, temp, 0, temp, 0);
 1618136            DesFunc(_decryptionKey1, temp, 0, outputBuffer, outputOffset);
 137
 1618138            return BlockSize;
 1618139        }
 140
 141        /// <summary>
 142        /// Validates the key.
 143        /// </summary>
 144        protected override void ValidateKey()
 75145        {
 75146            var keySize = Key.Length * 8;
 147
 75148            if (keySize is not (128 or 128 + 64))
 0149            {
 0150                throw new ArgumentException(string.Format("KeySize '{0}' is not valid for this algorithm.", keySize));
 151            }
 75152        }
 153    }
 154}