Ejemplo n.º 1
0
        private void ivParamTest(
            int count,
            IAeadBlockCipher eax,
            byte[]                          k,
            byte[]                          n)
        {
            byte[] p = Encoding.ASCII.GetBytes("hello world!!");

            eax.Init(true, new ParametersWithIV(new KeyParameter(k), n));

            byte[] enc = new byte[p.Length + 8];

            int len = eax.ProcessBytes(p, 0, p.Length, enc, 0);

            len += eax.DoFinal(enc, len);

            eax.Init(false, new ParametersWithIV(new KeyParameter(k), n));

            byte[] tmp = new byte[enc.Length];

            len = eax.ProcessBytes(enc, 0, enc.Length, tmp, 0);

            len += eax.DoFinal(tmp, len);

            byte[] dec = new byte[len];

            Array.Copy(tmp, 0, dec, 0, len);

            if (!AreEqual(p, dec))
            {
                Fail("decrypted stream fails to match in test " + count);
            }
        }
Ejemplo n.º 2
0
        private int UpdateCiphers(IAeadBlockCipher c1, IAeadBlockCipher c2, byte[] S, int i,
                                  bool includeAAD, bool includePlaintext)
        {
            int inputLen  = includePlaintext ? i : 0;
            int outputLen = c2.GetOutputSize(inputLen);

            byte[] output = new byte[outputLen];

            int len = 0;

            if (includeAAD)
            {
                c2.ProcessAadBytes(S, 0, i);
            }

            if (includePlaintext)
            {
                len += c2.ProcessBytes(S, 0, i, output, len);
            }

            len += c2.DoFinal(output, len);

            c1.ProcessAadBytes(output, 0, len);

            return(len);
        }
Ejemplo n.º 3
0
        public override byte[] Encrypt(byte[] input, CryptoKey key)
        {
            byte[]           nonce            = GenerateNonce();
            IAeadBlockCipher cipher           = GetNewAeadBlockCipherInstance();
            AeadParameters   cipherParameters = GetParameters(key, nonce);

            try
            {
                cipher.Init(true, cipherParameters);
                int    outputLen = cipher.GetOutputSize(input.Length);
                byte[] output    = new byte[outputLen + nonce.Length];
                int    position  = cipher.ProcessBytes(input, 0, input.Length, output, 0);

                try
                {
                    cipher.DoFinal(output, position);
                }
                catch (Exception e)
                {
                    throw new AppEncryptionException("unexpected error during encrypt cipher finalization", e);
                }

                AppendNonce(output, nonce);
                return(output);
            }
            finally
            {
                ManagedBufferUtils.WipeByteArray(cipherParameters.Key.GetKey());
            }
        }
Ejemplo n.º 4
0
        private void DoTestExceptions()
        {
            IAeadBlockCipher ocb = CreateOcbCipher();

            try
            {
                ocb = new OcbBlockCipher(new DesEngine(), new DesEngine());
                Fail("incorrect block size not picked up");
            }
            catch (ArgumentException)
            {
                // expected
            }

            try
            {
                ocb.Init(false, new KeyParameter(new byte[16]));
                Fail("illegal argument not picked up");
            }
            catch (ArgumentException)
            {
                // expected
            }

            // TODO
            //AEADTestUtil.testReset(this, createOCBCipher(), createOCBCipher(), new AEADParameters(new KeyParameter(new byte[16]), 128, new byte[15]));
            //AEADTestUtil.testTampering(this, ocb, new AEADParameters(new KeyParameter(new byte[16]), 128, new byte[15]));
        }
Ejemplo n.º 5
0
        private void RunTestCase(string testName, string[] testVector, int macLengthBits, byte[] K)
        {
            int pos = 0;

            byte[] N = Hex.Decode(testVector[pos++]);
            byte[] A = Hex.Decode(testVector[pos++]);
            byte[] P = Hex.Decode(testVector[pos++]);
            byte[] C = Hex.Decode(testVector[pos++]);

            int macLengthBytes = macLengthBits / 8;

            KeyParameter   keyParameter = new KeyParameter(K);
            AeadParameters parameters   = new AeadParameters(keyParameter, macLengthBits, N, A);

            IAeadBlockCipher encCipher = InitOcbCipher(true, parameters);
            IAeadBlockCipher decCipher = InitOcbCipher(false, parameters);

            CheckTestCase(encCipher, decCipher, testName, macLengthBytes, P, C);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C);

            // Key reuse
            AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters);

            encCipher.Init(true, keyReuseParams);
            decCipher.Init(false, keyReuseParams);
            CheckTestCase(encCipher, decCipher, testName + " (key reuse)", macLengthBytes, P, C);
        }
Ejemplo n.º 6
0
            private IAeadCipherBuilder <AuthenticationParametersWithIV> DoCreateAeadCipherBuilder(bool forEncryption, AuthenticationParametersWithIV parameters)
            {
                IAeadBlockCipher cipher = ProviderUtils.CreateAeadCipher("FipsAES", parameters.Algorithm.Mode, parameters, forEncryption, aesEngineProvider);

                cipher.Init(forEncryption, new AeadParameters(null, parameters.MacSizeInBits, parameters.GetIV()));
                return(new AeadCipherBuilderImpl <AuthenticationParametersWithIV>(forEncryption, parameters, cipher));
            }
Ejemplo n.º 7
0
 internal AeadCipherBuilderImpl(bool forEncryption, TParams parameters, IAeadBlockCipher cipher)
 {
     this.isApprovedModeOnly = CryptoServicesRegistrar.IsInApprovedOnlyMode();
     this.forEncryption      = forEncryption;
     this.parameters         = parameters;
     this.cipher             = cipher;
 }
        /// <summary>
        /// Buils an AEADBlockCipher engine
        /// </summary>
        /// <param name="blockCipher">BlockCipher engine</param>
        /// <param name="mode">SymmetricBlockModes enum, symmetric block mode name</param>
        /// <returns>AEADBlockCipher loaded with a given BlockCipher</returns>
        private IAeadBlockCipher getAEADCipherMode(IBlockCipher blockCipher, SymmetricBlockMode mode)
        {
            IAeadBlockCipher bc = null;

            switch (mode)
            {
            case SymmetricBlockMode.AEAD_CCM:
                bc = new CcmBlockCipher(blockCipher);
                break;

            case SymmetricBlockMode.AEAD_EAX:
                bc = new EaxBlockCipher(blockCipher);
                break;

            case SymmetricBlockMode.AEAD_GCM:
                bc = new GcmBlockCipher(blockCipher);
                break;

            case SymmetricBlockMode.AEAD_KCCM:
                bc = new KCcmBlockCipher(blockCipher);
                break;

            default:
                this.error.setError("SB017", "AEADCipher " + mode + " not recognised.");
                break;
            }
            return(bc);
        }
Ejemplo n.º 9
0
 internal AeadCipherImpl(int macSize, IAeadBlockCipher cipher, Stream source)
 {
     this.macSize   = macSize;
     this.cipher    = cipher;
     this.source    = source;
     this.aadStream = new AADBucket(cipher);
 }
Ejemplo n.º 10
0
        private IAeadBlockCipher InitOcbCipher(bool forEncryption, AeadParameters parameters)
        {
            IAeadBlockCipher c = CreateOcbCipher();

            c.Init(forEncryption, parameters);
            return(c);
        }
		public BufferedAeadBlockCipher(
			IAeadBlockCipher cipher)
		{
			if (cipher == null)
				throw new ArgumentNullException("cipher");

			this.cipher = cipher;
		}
 public BufferedAeadBlockCipher(IAeadBlockCipher cipher)
 {
     if (cipher == null)
     {
         throw new ArgumentNullException("cipher");
     }
     this.cipher = cipher;
 }
        /// <summary>
        /// Decrypts the given encrypted text with an AEAD encryption algorithm
        /// </summary>
        /// <param name="symmetricBlockAlgorithm">string SymmetricBlockAlgorithm enum, symmetric block algorithm name</param>
        /// <param name="symmetricBlockMode">string SymmetricBlockModes enum, symmetric block mode name</param>
        /// <param name="key">string Hexa key for the algorithm excecution</param>
        /// <param name="macSize">int macSize in bits for MAC length for AEAD Encryption algorithm</param>
        /// <param name="nonce">string Hexa nonce for MAC length for AEAD Encryption algorithm</param>
        /// <param name="encryptedInput">string Base64 text to decrypt</param>
        /// <returns></returns>
        public string DoAEADDecrypt(string symmetricBlockAlgorithm, string symmetricBlockMode,
                                    string key, int macSize, string nonce, string encryptedInput)
        {
            this.error.cleanError();
            SymmetricBlockAlgorithm algorithm = SymmetricBlockAlgorithmUtils.getSymmetricBlockAlgorithm(symmetricBlockAlgorithm, this.error);
            SymmetricBlockMode      mode      = SymmetricBlockModeUtils.getSymmetricBlockMode(symmetricBlockMode, this.error);

            if (this.error.existsError())
            {
                return("");
            }

            IBlockCipher     engine = getCipherEngine(algorithm);
            IAeadBlockCipher bbc    = getAEADCipherMode(engine, mode);

            if (this.error.existsError() && !(string.Compare(this.error.Code, "SB016", true) == 0))
            {
                return("");
            }
            byte[] nonceBytes = SecurityUtils.GetHexa(nonce, "SB025", this.error);
            byte[] keyBytes   = SecurityUtils.GetHexa(key, "SB025", this.error);
            if (this.HasError())
            {
                return("");
            }
            KeyParameter keyParam = new KeyParameter(keyBytes);

            AeadParameters AEADparams = new AeadParameters(keyParam, macSize, nonceBytes);

            try
            {
                bbc.Init(false, AEADparams);
            }catch (Exception e)
            {
                this.error.setError("SB030", e.Message);
                return("");
            }
            byte[] out2            = Base64.Decode(encryptedInput);
            byte[] comparisonBytes = new byte[bbc.GetOutputSize(out2.Length)];
            int    length          = bbc.ProcessBytes(out2, 0, out2.Length, comparisonBytes, 0);

            try
            {
                bbc.DoFinal(comparisonBytes, length);
            }
            catch (Exception)
            {
                this.error.setError("SB012", "AEAD decryption exception");
                return("");
            }
            this.error.cleanError();
            // return System.Text.Encoding.UTF8.GetString(comparisonBytes).Trim();
            EncodingUtil eu = new EncodingUtil();

            this.error = eu.GetError();

            return(eu.getString(comparisonBytes));
        }
Ejemplo n.º 14
0
        /// <exception cref="IOException"></exception>
        public TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher,
            int cipherKeySize, int macSize)
        {
            if (!TlsUtilities.IsTlsV12(context))
                throw new TlsFatalAlert(AlertDescription.internal_error);

            this.context = context;
            this.macSize = macSize;

            // NOTE: Valid for RFC 5288/6655 ciphers but may need review for other AEAD ciphers
            this.nonce_explicit_length = 8;

            // TODO SecurityParameters.fixed_iv_length
            int fixed_iv_length = 4;

            int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length);

            byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size);

            int offset = 0;

            KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;
            byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;

            if (offset != key_block_size)
                throw new TlsFatalAlert(AlertDescription.internal_error);

            KeyParameter encryptKey, decryptKey;
            if (context.IsServer)
            {
                this.encryptCipher = serverWriteCipher;
                this.decryptCipher = clientWriteCipher;
                this.encryptImplicitNonce = server_write_IV;
                this.decryptImplicitNonce = client_write_IV;
                encryptKey = server_write_key;
                decryptKey = client_write_key;
            }
            else
            {
                this.encryptCipher = clientWriteCipher;
                this.decryptCipher = serverWriteCipher;
                this.encryptImplicitNonce = client_write_IV;
                this.decryptImplicitNonce = server_write_IV;
                encryptKey = client_write_key;
                decryptKey = server_write_key;
            }

            byte[] dummyNonce = new byte[fixed_iv_length + nonce_explicit_length];

            this.encryptCipher.Init(true, new AeadParameters(encryptKey, 8 * macSize, dummyNonce));
            this.decryptCipher.Init(false, new AeadParameters(decryptKey, 8 * macSize, dummyNonce));
        }
Ejemplo n.º 15
0
        /// <exception cref="IOException"></exception>
        public TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher,
            int cipherKeySize, int macSize)
        {
            if (!TlsUtilities.IsTlsV12(context))
                throw new TlsFatalAlert(AlertDescription.internal_error);

            this.context = context;
            this.macSize = macSize;

            // NOTE: Valid for RFC 5288/6655 ciphers but may need review for other AEAD ciphers
            this.nonce_explicit_length = 8;

            // TODO SecurityParameters.fixed_iv_length
            int fixed_iv_length = 4;

            int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length);

            byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size);

            int offset = 0;

            KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;
            byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;

            if (offset != key_block_size)
                throw new TlsFatalAlert(AlertDescription.internal_error);

            KeyParameter encryptKey, decryptKey;
            if (context.IsServer)
            {
                this.encryptCipher = serverWriteCipher;
                this.decryptCipher = clientWriteCipher;
                this.encryptImplicitNonce = server_write_IV;
                this.decryptImplicitNonce = client_write_IV;
                encryptKey = server_write_key;
                decryptKey = client_write_key;
            }
            else
            {
                this.encryptCipher = clientWriteCipher;
                this.decryptCipher = serverWriteCipher;
                this.encryptImplicitNonce = client_write_IV;
                this.decryptImplicitNonce = server_write_IV;
                encryptKey = client_write_key;
                decryptKey = server_write_key;
            }

            byte[] dummyNonce = new byte[fixed_iv_length + nonce_explicit_length];

            this.encryptCipher.Init(true, new AeadParameters(encryptKey, 8 * macSize, dummyNonce));
            this.decryptCipher.Init(false, new AeadParameters(decryptKey, 8 * macSize, dummyNonce));
        }
Ejemplo n.º 16
0
 public BufferedAeadBlockCipher(IAeadBlockCipher cipher)
 {
     //IL_000e: Unknown result type (might be due to invalid IL or missing references)
     if (cipher == null)
     {
         throw new ArgumentNullException("cipher");
     }
     this.cipher = cipher;
 }
Ejemplo n.º 17
0
    public TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher, int cipherKeySize, int macSize)
    {
        if (!TlsUtilities.IsTlsV12(context))
        {
            throw new TlsFatalAlert(80);
        }
        this.context          = context;
        this.macSize          = macSize;
        nonce_explicit_length = 8;
        int num  = 4;
        int num2 = 2 * cipherKeySize + 2 * num;

        byte[]       array        = TlsUtilities.CalculateKeyBlock(context, num2);
        int          num3         = 0;
        KeyParameter keyParameter = new KeyParameter(array, num3, cipherKeySize);

        num3 += cipherKeySize;
        KeyParameter keyParameter2 = new KeyParameter(array, num3, cipherKeySize);

        num3 += cipherKeySize;
        byte[] array2 = Arrays.CopyOfRange(array, num3, num3 + num);
        num3 += num;
        byte[] array3 = Arrays.CopyOfRange(array, num3, num3 + num);
        num3 += num;
        if (num3 != num2)
        {
            throw new TlsFatalAlert(80);
        }
        KeyParameter key;
        KeyParameter key2;

        if (context.IsServer)
        {
            encryptCipher        = serverWriteCipher;
            decryptCipher        = clientWriteCipher;
            encryptImplicitNonce = array3;
            decryptImplicitNonce = array2;
            key  = keyParameter2;
            key2 = keyParameter;
        }
        else
        {
            encryptCipher        = clientWriteCipher;
            decryptCipher        = serverWriteCipher;
            encryptImplicitNonce = array2;
            decryptImplicitNonce = array3;
            key  = keyParameter;
            key2 = keyParameter2;
        }
        byte[] nonce = new byte[num + nonce_explicit_length];
        encryptCipher.Init(forEncryption: true, new AeadParameters(key, 8 * macSize, nonce));
        decryptCipher.Init(forEncryption: false, new AeadParameters(key2, 8 * macSize, nonce));
    }
        private IAeadCipherBuilder <TAuthParamWithIV> DoCreateAeadCipherBuilder(bool forEncryption, TAuthParamWithIV parameters)
        {
            if (CryptoServicesRegistrar.IsInApprovedOnlyMode())
            {
                throw new CryptoUnapprovedOperationError("attempt to create unapproved AEAD cipher builder in approved only mode");
            }

            IAeadBlockCipher cipher = ProviderUtils.CreateAeadCipher(name, parameters.Algorithm.Mode, parameters, false, engineProvider);

            cipher.Init(forEncryption, new AeadParameters(null, parameters.MacSizeInBits, parameters.GetIV()));

            return(new AeadCipherBuilderImpl <TAuthParamWithIV>(forEncryption, parameters, cipher));
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Decodes the AES-GCM encrypted data according to RFC5288 and RFC5264.
        /// (https://tools.ietf.org/html/rfc5288, https://tools.ietf.org/html/rfc5246#page-24).
        /// </summary>
        public static byte[] DecryptAead(IAeadBlockCipher gcm, Span <byte> writeKeyBytes, Span <byte> nonceBytes, Span <byte> encryptedBytes, Span <byte> additionalData)
        {
            var writeKey = new KeyParameter(writeKeyBytes.ToArray());

            gcm.Init(false, new AeadParameters(writeKey, 128, nonceBytes.ToArray(), additionalData.ToArray()));

            var outsize    = gcm.GetOutputSize(encryptedBytes.Length);
            var plainBytes = new byte[outsize];
            var outBytes   = gcm.ProcessBytes(encryptedBytes.ToArray(), 0, encryptedBytes.Length, plainBytes, 0);

            // finally check MAC:
            outBytes += gcm.DoFinal(plainBytes, outBytes);
            return(plainBytes);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SymmetricAeadStream"/> class.
        /// </summary>
        /// <param name="makeCipher">The make cipher.</param>
        /// <param name="outStream">The out stream.</param>
        /// <param name="nonce">The nonce.</param>
        /// <param name="tagLength">Length of the tag.</param>
        /// <param name="initFunc">The init func.</param>
        /// <param name="encrypt">if set to <c>true</c> [encrypt].</param>
        public SymmetricAeadStream(Func<IAeadBlockCipher> makeCipher,
                                   Stream outStream,
                                   byte[] nonce,
                                   int tagLength,
                                   Action<byte[], IAeadBlockCipher, byte[], bool> initFunc,
                                   bool encrypt)
        {
            _output = outStream;
            _nonce = nonce;

            _tagLength = tagLength;
            _initFunc = initFunc;
            _encrypt = encrypt;
            _cipher = makeCipher();
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SymmetricAeadStream"/> class.
        /// </summary>
        /// <param name="makeCipher">The make cipher.</param>
        /// <param name="outStream">The out stream.</param>
        /// <param name="nonce">The nonce.</param>
        /// <param name="tagLength">Length of the tag.</param>
        /// <param name="initFunc">The init func.</param>
        /// <param name="encrypt">if set to <c>true</c> [encrypt].</param>
        public SymmetricAeadStream(Func <IAeadBlockCipher> makeCipher,
                                   Stream outStream,
                                   byte[] nonce,
                                   int tagLength,
                                   Action <byte[], IAeadBlockCipher, byte[], bool> initFunc,
                                   bool encrypt)
        {
            _output = outStream;
            _nonce  = nonce;

            _tagLength = tagLength;
            _initFunc  = initFunc;
            _encrypt   = encrypt;
            _cipher    = makeCipher();
        }
Ejemplo n.º 22
0
        private Byte[] Decrypt(IAeadBlockCipher cipher, Byte[] data)
        {
            var size      = cipher.GetOutputSize(data.Length);
            var outBuffer = new Byte[size];
            var off1      = cipher.ProcessBytes(data, 0, data.Length, outBuffer, 0);
            //cipher.DoFinal(data, 0, data.Length, outBuffer, 0);
            var off2   = cipher.DoFinal(outBuffer, off1);
            var result = new Byte[off2];

            Array.Copy(outBuffer, 0, result, 0, result.Length);

            //String asString = Encoding.ASCII.GetString(result);
            //Console.WriteLine(asString);

            return(result);
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
 /// </summary>
 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
 protected override void Dispose(bool disposing)
 {
     Flush();
     Secure.Clear(_nonce);
     _nonce = null;
     Secure.Clear(_header);
     _header = null;
     //_cipher.Reset();
     _cipher   = null;
     _initFunc = null;
     _output   = null;
     _outLen   = 0;
     _init     = false;
     _inLen    = 0;
     base.Dispose(disposing);
 }
Ejemplo n.º 24
0
        private void CheckTestCase(IAeadBlockCipher encCipher, IAeadBlockCipher decCipher, string testName,
                                   int macLengthBytes, byte[] P, byte[] C)
        {
            byte[] tag = Arrays.CopyOfRange(C, C.Length - macLengthBytes, C.Length);

            {
                byte[] enc = new byte[encCipher.GetOutputSize(P.Length)];
                int    len = encCipher.ProcessBytes(P, 0, P.Length, enc, 0);
                len += encCipher.DoFinal(enc, len);

                if (enc.Length != len)
                {
                    Fail("encryption reported incorrect length: " + testName);
                }

                if (!AreEqual(C, enc))
                {
                    Fail("incorrect encrypt in: " + testName);
                }

                if (!AreEqual(tag, encCipher.GetMac()))
                {
                    Fail("getMac() not the same as the appended tag: " + testName);
                }
            }

            {
                byte[] dec = new byte[decCipher.GetOutputSize(C.Length)];
                int    len = decCipher.ProcessBytes(C, 0, C.Length, dec, 0);
                len += decCipher.DoFinal(dec, len);

                if (dec.Length != len)
                {
                    Fail("decryption reported incorrect length: " + testName);
                }

                if (!AreEqual(P, dec))
                {
                    Fail("incorrect decrypt in: " + testName);
                }

                if (!AreEqual(tag, decCipher.GetMac()))
                {
                    Fail("getMac() not the same as the appended tag: " + testName);
                }
            }
        }
Ejemplo n.º 25
0
        public override byte[] Decrypt(byte[] input, CryptoKey key)
        {
            byte[]           nonce            = GetAppendedNonce(input);
            IAeadBlockCipher cipher           = GetNewAeadBlockCipherInstance();
            AeadParameters   cipherParameters = GetParameters(key, nonce);

            try
            {
                cipher.Init(false, cipherParameters);
                int    cipherTextLength = input.Length - nonce.Length;
                int    outputLen        = cipher.GetOutputSize(cipherTextLength);
                byte[] output           = new byte[outputLen];
                int    position         = cipher.ProcessBytes(input, 0, cipherTextLength, output, 0);

                try
                {
                    position += cipher.DoFinal(output, position);
                }
                catch (Exception e)
                {
                    throw new AppEncryptionException("unexpected error during decrypt cipher finalization", e);
                }

                if (position != outputLen)
                {
                    if (Debug.On)
#pragma warning disable 162
                    {
                        Logger.LogError("position {position} not equal to outputLength {outputLen}", position, outputLen);
                    }
#pragma warning restore 162

                    throw new AppEncryptionException("unexpected error during decrypt cipher finalization");
                }

                return(output);
            }
            finally
            {
                ManagedBufferUtils.WipeByteArray(cipherParameters.Key.GetKey());
            }
        }
Ejemplo n.º 26
0
        private void RunLongerTestCase(int keyLen, int tagLen, string expectedOutputHex)
        {
            byte[] expectedOutput = Hex.Decode(expectedOutputHex);
            byte[] keyBytes       = new byte[keyLen / 8];
            keyBytes[keyBytes.Length - 1] = (byte)tagLen;
            KeyParameter key = new KeyParameter(keyBytes);

            IAeadBlockCipher c1 = InitOcbCipher(true, new AeadParameters(key, tagLen, CreateNonce(385)));
            IAeadBlockCipher c2 = CreateOcbCipher();

            long total = 0;

            byte[] S = new byte[128];

            uint n = 0;

            for (int i = 0; i < 128; ++i)
            {
                c2.Init(true, new AeadParameters(key, tagLen, CreateNonce(++n)));
                total += UpdateCiphers(c1, c2, S, i, true, true);
                c2.Init(true, new AeadParameters(key, tagLen, CreateNonce(++n)));
                total += UpdateCiphers(c1, c2, S, i, false, true);
                c2.Init(true, new AeadParameters(key, tagLen, CreateNonce(++n)));
                total += UpdateCiphers(c1, c2, S, i, true, false);
            }

            long expectedTotal = 16256 + (48 * tagLen);

            if (total != expectedTotal)
            {
                Fail("test generated the wrong amount of input: " + total);
            }

            byte[] output = new byte[c1.GetOutputSize(0)];
            c1.DoFinal(output, 0);

            if (!AreEqual(expectedOutput, output))
            {
                Fail("incorrect encrypt in long-form test");
            }
        }
Ejemplo n.º 27
0
        private void OutputSizeTests()
        {
            byte[] K  = new byte[16];
            byte[] A  = null;
            byte[] IV = new byte[15];

            AeadParameters   parameters = new AeadParameters(new KeyParameter(K), 16 * 8, IV, A);
            IAeadBlockCipher cipher     = InitOcbCipher(true, parameters);

            if (cipher.GetUpdateOutputSize(0) != 0)
            {
                Fail("incorrect getUpdateOutputSize for initial 0 bytes encryption");
            }

            if (cipher.GetOutputSize(0) != 16)
            {
                Fail("incorrect getOutputSize for initial 0 bytes encryption");
            }

            cipher.Init(false, parameters);

            if (cipher.GetUpdateOutputSize(0) != 0)
            {
                Fail("incorrect getUpdateOutputSize for initial 0 bytes decryption");
            }

            // NOTE: 0 bytes would be truncated data, but we want it to fail in the doFinal, not here
            if (cipher.GetOutputSize(0) != 0)
            {
                Fail("fragile getOutputSize for initial 0 bytes decryption");
            }

            if (cipher.GetOutputSize(16) != 0)
            {
                Fail("incorrect getOutputSize for initial MAC-size bytes decryption");
            }
        }
Ejemplo n.º 28
0
        private void RunTestCase(string testName, string[] testVector, int macLengthBits, byte[] K)
        {
            int pos = 0;

            byte[] N = Hex.Decode(testVector[pos++]);
            byte[] A = Hex.Decode(testVector[pos++]);
            byte[] P = Hex.Decode(testVector[pos++]);
            byte[] C = Hex.Decode(testVector[pos++]);

            int macLengthBytes = macLengthBits / 8;

            // TODO Variations processing AAD and cipher bytes incrementally

            KeyParameter   keyParameter   = new KeyParameter(K);
            AeadParameters aeadParameters = new AeadParameters(keyParameter, macLengthBits, N, A);

            IAeadBlockCipher encCipher = InitOcbCipher(true, aeadParameters);
            IAeadBlockCipher decCipher = InitOcbCipher(false, aeadParameters);

            CheckTestCase(encCipher, decCipher, testName, macLengthBytes, P, C);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C);

            // TODO Key reuse
        }
Ejemplo n.º 29
0
        public static IBufferedCipher GetCipher(
            string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = Platform.ToUpperInvariant(algorithm);

            {
                string aliased = (string)algorithms[algorithm];

                if (aliased != null)
                {
                    algorithm = aliased;
                }
            }

            IBasicAgreement iesAgreement = null;

            if (algorithm == "IES")
            {
                iesAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                iesAgreement = new ECDHBasicAgreement();
            }

            if (iesAgreement != null)
            {
                return(new BufferedIesCipher(
                           new IesEngine(
                               iesAgreement,
                               new Kdf2BytesGenerator(
                                   new Sha1Digest()),
                               new HMac(
                                   new Sha1Digest()))));
            }



            if (Platform.StartsWith(algorithm, "PBE"))
            {
                if (Platform.EndsWith(algorithm, "-CBC"))
                {
                    if (algorithm == "PBEWITHSHA1ANDDES-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEngine())));
                    }
                    else if (algorithm == "PBEWITHSHA1ANDRC2-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                    else if (Strings.IsOneOf(algorithm,
                                             "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEdeEngine())));
                    }
                    else if (Strings.IsOneOf(algorithm,
                                             "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                }
                else if (Platform.EndsWith(algorithm, "-BC") || Platform.EndsWith(algorithm, "-OPENSSL"))
                {
                    if (Strings.IsOneOf(algorithm,
                                        "PBEWITHSHAAND128BITAES-CBC-BC",
                                        "PBEWITHSHAAND192BITAES-CBC-BC",
                                        "PBEWITHSHAAND256BITAES-CBC-BC",
                                        "PBEWITHSHA256AND128BITAES-CBC-BC",
                                        "PBEWITHSHA256AND192BITAES-CBC-BC",
                                        "PBEWITHSHA256AND256BITAES-CBC-BC",
                                        "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
                                        "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
                                        "PBEWITHMD5AND256BITAES-CBC-OPENSSL"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new AesFastEngine())));
                    }
                }
            }



            string[] parts = algorithm.Split('/');

            IBlockCipher           blockCipher     = null;
            IAsymmetricBlockCipher asymBlockCipher = null;
            IStreamCipher          streamCipher    = null;

            string algorithmName = parts[0];

            {
                string aliased = (string)algorithms[algorithmName];

                if (aliased != null)
                {
                    algorithmName = aliased;
                }
            }

            CipherAlgorithm cipherAlgorithm;

            try
            {
                cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), algorithmName);
            }
            catch (ArgumentException)
            {
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            switch (cipherAlgorithm)
            {
            case CipherAlgorithm.AES:
                blockCipher = new AesFastEngine();
                break;

            case CipherAlgorithm.ARC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.BLOWFISH:
                blockCipher = new BlowfishEngine();
                break;

            case CipherAlgorithm.CAMELLIA:
                blockCipher = new CamelliaEngine();
                break;

            case CipherAlgorithm.CAST5:
                blockCipher = new Cast5Engine();
                break;

            case CipherAlgorithm.CAST6:
                blockCipher = new Cast6Engine();
                break;

            case CipherAlgorithm.DES:
                blockCipher = new DesEngine();
                break;

            case CipherAlgorithm.DESEDE:
                blockCipher = new DesEdeEngine();
                break;

            case CipherAlgorithm.ELGAMAL:
                asymBlockCipher = new ElGamalEngine();
                break;

            case CipherAlgorithm.GOST28147:
                blockCipher = new Gost28147Engine();
                break;

            case CipherAlgorithm.HC128:
                streamCipher = new HC128Engine();
                break;

            case CipherAlgorithm.HC256:
                streamCipher = new HC256Engine();
                break;

            case CipherAlgorithm.IDEA:
                blockCipher = new IdeaEngine();
                break;

            case CipherAlgorithm.NOEKEON:
                blockCipher = new NoekeonEngine();
                break;

            case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
            case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.RC2:
                blockCipher = new RC2Engine();
                break;

            case CipherAlgorithm.RC5:
                blockCipher = new RC532Engine();
                break;

            case CipherAlgorithm.RC5_64:
                blockCipher = new RC564Engine();
                break;

            case CipherAlgorithm.RC6:
                blockCipher = new RC6Engine();
                break;

            case CipherAlgorithm.RIJNDAEL:
                blockCipher = new RijndaelEngine();
                break;

            case CipherAlgorithm.RSA:
                asymBlockCipher = new RsaBlindedEngine();
                break;

            case CipherAlgorithm.SALSA20:
                streamCipher = new Salsa20Engine();
                break;

            case CipherAlgorithm.SEED:
                blockCipher = new SeedEngine();
                break;

            case CipherAlgorithm.SERPENT:
                blockCipher = new SerpentEngine();
                break;

            case CipherAlgorithm.SKIPJACK:
                blockCipher = new SkipjackEngine();
                break;

            case CipherAlgorithm.TEA:
                blockCipher = new TeaEngine();
                break;

            case CipherAlgorithm.THREEFISH_256:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
                break;

            case CipherAlgorithm.THREEFISH_512:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
                break;

            case CipherAlgorithm.THREEFISH_1024:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
                break;

            case CipherAlgorithm.TNEPRES:
                blockCipher = new TnepresEngine();
                break;

            case CipherAlgorithm.TWOFISH:
                blockCipher = new TwofishEngine();
                break;

            case CipherAlgorithm.VMPC:
                streamCipher = new VmpcEngine();
                break;

            case CipherAlgorithm.VMPC_KSA3:
                streamCipher = new VmpcKsa3Engine();
                break;

            case CipherAlgorithm.XTEA:
                blockCipher = new XteaEngine();
                break;

            default:
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            if (streamCipher != null)
            {
                if (parts.Length > 1)
                {
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");
                }

                return(new BufferedStreamCipher(streamCipher));
            }


            bool cts    = false;
            bool padded = true;
            IBlockCipherPadding padding         = null;
            IAeadBlockCipher    aeadBlockCipher = null;

            if (parts.Length > 2)
            {
                if (streamCipher != null)
                {
                    throw new ArgumentException("Paddings not used for stream ciphers");
                }

                string paddingName = parts[2];

                CipherPadding cipherPadding;
                if (paddingName == "")
                {
                    cipherPadding = CipherPadding.RAW;
                }
                else if (paddingName == "X9.23PADDING")
                {
                    cipherPadding = CipherPadding.X923PADDING;
                }
                else
                {
                    try
                    {
                        cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), paddingName);
                    }
                    catch (ArgumentException)
                    {
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }

                switch (cipherPadding)
                {
                case CipherPadding.NOPADDING:
                    padded = false;
                    break;

                case CipherPadding.RAW:
                    break;

                case CipherPadding.ISO10126PADDING:
                case CipherPadding.ISO10126D2PADDING:
                case CipherPadding.ISO10126_2PADDING:
                    padding = new ISO10126d2Padding();
                    break;

                case CipherPadding.ISO7816_4PADDING:
                case CipherPadding.ISO9797_1PADDING:
                    padding = new ISO7816d4Padding();
                    break;

                case CipherPadding.ISO9796_1:
                case CipherPadding.ISO9796_1PADDING:
                    asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
                    break;

                case CipherPadding.OAEP:
                case CipherPadding.OAEPPADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher);
                    break;

                case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
                    break;

                case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
                    break;

                case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
                    break;

                case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
                    break;

                case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
                    break;

                case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
                    break;

                case CipherPadding.PKCS1:
                case CipherPadding.PKCS1PADDING:
                    asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
                    break;

                case CipherPadding.PKCS5:
                case CipherPadding.PKCS5PADDING:
                case CipherPadding.PKCS7:
                case CipherPadding.PKCS7PADDING:
                    padding = new Pkcs7Padding();
                    break;

                case CipherPadding.TBCPADDING:
                    padding = new TbcPadding();
                    break;

                case CipherPadding.WITHCTS:
                    cts = true;
                    break;

                case CipherPadding.X923PADDING:
                    padding = new X923Padding();
                    break;

                case CipherPadding.ZEROBYTEPADDING:
                    padding = new ZeroBytePadding();
                    break;

                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            string mode = "";

            if (parts.Length > 1)
            {
                mode = parts[1];

                int    di       = GetDigitIndex(mode);
                string modeName = di >= 0 ? mode.Substring(0, di) : mode;

                try
                {
                    CipherMode cipherMode = modeName == ""
                        ? CipherMode.NONE
                        : (CipherMode)Enums.GetEnumValue(typeof(CipherMode), modeName);

                    switch (cipherMode)
                    {
                    case CipherMode.ECB:
                    case CipherMode.NONE:
                        break;

                    case CipherMode.CBC:
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.CCM:
                        aeadBlockCipher = new CcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.CFB:
                    {
                        int bits = (di < 0)
                                ?       8 * blockCipher.GetBlockSize()
                                :       int.Parse(mode.Substring(di));

                        blockCipher = new CfbBlockCipher(blockCipher, bits);
                        break;
                    }

                    case CipherMode.CTR:
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    case CipherMode.CTS:
                        cts         = true;
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.EAX:
                        aeadBlockCipher = new EaxBlockCipher(blockCipher);
                        break;

                    case CipherMode.GCM:
                        aeadBlockCipher = new GcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.GOFB:
                        blockCipher = new GOfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.OCB:
                        aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
                        break;

                    case CipherMode.OFB:
                    {
                        int bits = (di < 0)
                                ?       8 * blockCipher.GetBlockSize()
                                :       int.Parse(mode.Substring(di));

                        blockCipher = new OfbBlockCipher(blockCipher, bits);
                        break;
                    }

                    case CipherMode.OPENPGPCFB:
                        blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.SIC:
                        if (blockCipher.GetBlockSize() < 16)
                        {
                            throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                        }
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    default:
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }
                catch (ArgumentException)
                {
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            if (aeadBlockCipher != null)
            {
                if (cts)
                {
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                }
                if (padded && parts.Length > 2 && parts[2] != "")
                {
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");
                }

                return(new BufferedAeadBlockCipher(aeadBlockCipher));
            }

            if (blockCipher != null)
            {
                if (cts)
                {
                    return(new CtsBlockCipher(blockCipher));
                }

                if (padding != null)
                {
                    return(new PaddedBufferedBlockCipher(blockCipher, padding));
                }

                if (!padded || blockCipher.IsPartialBlockOkay)
                {
                    return(new BufferedBlockCipher(blockCipher));
                }

                return(new PaddedBufferedBlockCipher(blockCipher));
            }

            if (asymBlockCipher != null)
            {
                return(new BufferedAsymmetricBlockCipher(asymBlockCipher));
            }

            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
 /// </summary>
 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
 protected override void Dispose(bool disposing)
 {
     Flush();
     Secure.Clear(_nonce);
     _nonce = null;
     Secure.Clear(_header);
     _header = null;
     //_cipher.Reset();
     _cipher = null;
     _initFunc = null;
     _output = null;
     _outLen = 0;
     _init = false;
     _inLen = 0;
     base.Dispose(disposing);
 }
Ejemplo n.º 31
0
        private void ivParamTest(
			int					count,
			IAeadBlockCipher	eax,
			byte[]				k,
			byte[]				n)
		{
			byte[] p = Encoding.ASCII.GetBytes("hello world!!");

			eax.Init(true, new ParametersWithIV(new KeyParameter(k), n));

			byte[] enc = new byte[p.Length + 8];

			int len = eax.ProcessBytes(p, 0, p.Length, enc, 0);

			len += eax.DoFinal(enc, len);

			eax.Init(false, new ParametersWithIV(new KeyParameter(k), n));

			byte[] tmp = new byte[enc.Length];

			len = eax.ProcessBytes(enc, 0, enc.Length, tmp, 0);

			len += eax.DoFinal(tmp, len);

			byte[] dec = new byte[len];

			Array.Copy(tmp, 0, dec, 0, len);

			if (!AreEqual(p, dec))
			{
				Fail("decrypted stream fails to match in test " + count);
			}
		}
Ejemplo n.º 32
0
        private void CheckTestCase(IAeadBlockCipher encCipher, IAeadBlockCipher decCipher, string testName,
            int macLengthBytes, byte[] P, byte[] C)
        {
            byte[] tag = Arrays.CopyOfRange(C, C.Length - macLengthBytes, C.Length);

            {
                byte[] enc = new byte[encCipher.GetOutputSize(P.Length)];
                int len = encCipher.ProcessBytes(P, 0, P.Length, enc, 0);
                len += encCipher.DoFinal(enc, len);

                if (enc.Length != len)
                {
                    Fail("encryption reported incorrect length: " + testName);
                }

                if (!AreEqual(C, enc))
                {
                    Fail("incorrect encrypt in: " + testName);
                }

                if (!AreEqual(tag, encCipher.GetMac()))
                {
                    Fail("getMac() not the same as the appended tag: " + testName);
                }
            }

            {
                byte[] dec = new byte[decCipher.GetOutputSize(C.Length)];
                int len = decCipher.ProcessBytes(C, 0, C.Length, dec, 0);
                len += decCipher.DoFinal(dec, len);

                if (dec.Length != len)
                {
                    Fail("decryption reported incorrect length: " + testName);
                }

                if (!AreEqual(P, dec))
                {
                    Fail("incorrect decrypt in: " + testName);
                }

                if (!AreEqual(tag, decCipher.GetMac()))
                {
                    Fail("getMac() not the same as the appended tag: " + testName);
                }
            }
        }
Ejemplo n.º 33
0
        private int UpdateCiphers(IAeadBlockCipher c1, IAeadBlockCipher c2, byte[] S, int i,
            bool includeAAD, bool includePlaintext)
        {
            int inputLen = includePlaintext ? i : 0;
            int outputLen = c2.GetOutputSize(inputLen);

            byte[] output = new byte[outputLen];

            int len = 0;

            if (includeAAD) {
                c2.ProcessAadBytes(S, 0, i);
            }

            if (includePlaintext) {
                len += c2.ProcessBytes(S, 0, i, output, len);
            }

            len += c2.DoFinal(output, len);

            c1.ProcessAadBytes(output, 0, len);

            return len;
        }
Ejemplo n.º 34
0
 public AeadCryptographyProvider(IAeadBlockCipher aeadBlockCipher, Encoding encoding)
 {
     _aeadBlockCipher = aeadBlockCipher;
     _encoding        = encoding;
     SetNonceForCcm();
 }
Ejemplo n.º 35
0
 /// <exception cref="IOException"></exception>
 public TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher,
     int cipherKeySize, int macSize)
     : this(context, clientWriteCipher, serverWriteCipher, cipherKeySize, macSize, NONCE_RFC5288)
 {
 }
Ejemplo n.º 36
0
        /// <exception cref="IOException"></exception>
        internal TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher,
            int cipherKeySize, int macSize, int nonceMode)
        {
            if (!TlsUtilities.IsTlsV12(context))
                throw new TlsFatalAlert(AlertDescription.internal_error);

            this.nonceMode = nonceMode;

            // TODO SecurityParameters.fixed_iv_length
            int fixed_iv_length;

            switch (nonceMode)
            {
                case NONCE_RFC5288:
                    fixed_iv_length = 4;
                    this.record_iv_length = 8;
                    break;
                case NONCE_DRAFT_CHACHA20_POLY1305:
                    fixed_iv_length = 12;
                    this.record_iv_length = 0;
                    break;
                default:
                    throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            this.context = context;
            this.macSize = macSize;

            int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length);

            byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size);

            int offset = 0;

            KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;
            byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length);
            offset += fixed_iv_length;

            if (offset != key_block_size)
                throw new TlsFatalAlert(AlertDescription.internal_error);

            KeyParameter encryptKey, decryptKey;
            if (context.IsServer)
            {
                this.encryptCipher = serverWriteCipher;
                this.decryptCipher = clientWriteCipher;
                this.encryptImplicitNonce = server_write_IV;
                this.decryptImplicitNonce = client_write_IV;
                encryptKey = server_write_key;
                decryptKey = client_write_key;
            }
            else
            {
                this.encryptCipher = clientWriteCipher;
                this.decryptCipher = serverWriteCipher;
                this.encryptImplicitNonce = client_write_IV;
                this.decryptImplicitNonce = server_write_IV;
                encryptKey = client_write_key;
                decryptKey = server_write_key;
            }

            byte[] dummyNonce = new byte[fixed_iv_length + record_iv_length];

            this.encryptCipher.Init(true, new AeadParameters(encryptKey, 8 * macSize, dummyNonce));
            this.decryptCipher.Init(false, new AeadParameters(decryptKey, 8 * macSize, dummyNonce));
        }
Ejemplo n.º 37
0
 internal AeadResult(int macLength, IAeadBlockCipher cipher)
 {
     this.macLength = macLength;
     this.cipher    = cipher;
 }
        public CryptoProviderFactory(BlockCipherEngines engine, BlockCipherModes mode)
        {
            var cipherEngine = ChooseBlockCipherEngine(engine);

            _aeadBlockCipher = ChooseBlockCipherMode(mode, cipherEngine);
        }
Ejemplo n.º 39
0
 public AeadCryptographyProvider(IAeadBlockCipher aeadBlockCipher)
 {
     _aeadBlockCipher = aeadBlockCipher;
     _encoding        = Encoding.UTF8;
     SetNonceForCcm();
 }