Beispiel #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);
            }
        }
Beispiel #2
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));
    }
Beispiel #3
0
        private IAeadBlockCipher InitOcbCipher(bool forEncryption, AeadParameters parameters)
        {
            IAeadBlockCipher c = CreateOcbCipher();

            c.Init(forEncryption, parameters);
            return(c);
        }
Beispiel #4
0
        /// <exception cref="IOException"></exception>
        public /*virtual */ BufferSegment EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
        {
            // nonce is passed to AeadParameters and used a lot of places
            byte[] nonce = new byte[encryptImplicitNonce.Length + record_iv_length];

            switch (nonceMode)
            {
            case NONCE_RFC5288:
                Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length);
                // RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number.
                TlsUtilities.WriteUint64(seqNo, nonce, encryptImplicitNonce.Length);
                break;

            case NONCE_DRAFT_CHACHA20_POLY1305:
                TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8);
                for (int i = 0; i < encryptImplicitNonce.Length; ++i)
                {
                    nonce[i] ^= encryptImplicitNonce[i];
                }
                break;

            default:
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            int plaintextOffset  = offset;
            int plaintextLength  = len;
            int ciphertextLength = encryptCipher.GetOutputSize(plaintextLength);

            int outputLength = record_iv_length + ciphertextLength;

            byte[] output = BufferPool.Get(outputLength, true);
            if (record_iv_length != 0)
            {
                Array.Copy(nonce, nonce.Length - record_iv_length, output, 0, record_iv_length);
            }
            int outputPos = record_iv_length;

            byte[]         additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters     = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                encryptCipher.Init(true, parameters);
                outputPos += encryptCipher.ProcessBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos);
                outputPos += encryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error, e);
            }

            if (outputPos != outputLength)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return(new BufferSegment(output, 0, outputLength));
        }
Beispiel #5
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));
            }
        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());
            }
        }
Beispiel #7
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);
        }
        private byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null)
        {
            //User Error Checks
            if (key == null || key.Length != KeyBitSize / 8)
            {
                throw new ArgumentException($"Key needs to be {KeyBitSize} bit!", nameof(key));
            }

            if (secretMessage == null || secretMessage.Length == 0)
            {
                throw new ArgumentException(@"Secret Message Required!", nameof(secretMessage));
            }

            //Non-secret Payload Optional
            nonSecretPayload = nonSecretPayload ?? new byte[] { };

            //Using random nonce large enough not to repeat
            var nonce = new byte[NonceBitSize / 8];

            _random.NextBytes(nonce, 0, nonce.Length);

            var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);

            _aeadBlockCipher.Init(true, parameters);

            //Generate Cipher Text With Auth Tag
            var cipherText = new byte[_aeadBlockCipher.GetOutputSize(secretMessage.Length)];
            var len        = _aeadBlockCipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);

            _aeadBlockCipher.DoFinal(cipherText, len);

            //Assemble Message
            var combinedStream = new MemoryStream();

            using (var binaryWriter = new BinaryWriter(combinedStream))
            {
                //Prepend Authenticated Payload
                binaryWriter.Write(nonSecretPayload);
                //Prepend Nonce
                binaryWriter.Write(nonce);
                //Write Cipher Text
                binaryWriter.Write(cipherText);
            }

            return(combinedStream.ToArray());
        }
Beispiel #9
0
 public override void Init(bool forEncryption, ICipherParameters parameters)
 {
     if (parameters is ParametersWithRandom)
     {
         parameters = ((ParametersWithRandom)parameters).Parameters;
     }
     cipher.Init(forEncryption, parameters);
 }
        /// <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));
        }
Beispiel #11
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
        {
            if (GetPlaintextLimit(len) < 0)
            {
                throw new TlsFatalAlert(AlertDescription.decode_error);
            }

            byte[] nonce = new byte[decryptImplicitNonce.Length + record_iv_length];

            switch (nonceMode)
            {
            case NONCE_RFC5288:
                Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length);
                Array.Copy(ciphertext, offset, nonce, nonce.Length - record_iv_length, record_iv_length);
                break;

            case NONCE_DRAFT_CHACHA20_POLY1305:
                TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8);
                for (int i = 0; i < decryptImplicitNonce.Length; ++i)
                {
                    nonce[i] ^= decryptImplicitNonce[i];
                }
                break;

            default:
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            int ciphertextOffset = offset + record_iv_length;
            int ciphertextLength = len - record_iv_length;
            int plaintextLength  = decryptCipher.GetOutputSize(ciphertextLength);

            byte[] output    = new byte[plaintextLength];
            int    outputPos = 0;

            byte[]         additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters     = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                decryptCipher.Init(false, parameters);
                outputPos += decryptCipher.ProcessBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos);
                outputPos += decryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
            }

            if (outputPos != output.Length)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return(output);
        }
Beispiel #12
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");
            }
        }
        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));
        }
Beispiel #14
0
        public void Init(ICipherParameters parameters)
        {
            if (parameters is ParametersWithIV)
            {
                ParametersWithIV p = (ParametersWithIV)parameters;

                aeadCipher.Init(true, new AeadParameters((KeyParameter)p.Parameters, macLenInBits, p.GetIV()));
            }
            else
            {
                throw new ArgumentException("AEAD cipher based MAC needs nonce/IV");
            }
        }
Beispiel #15
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);
        }
Beispiel #16
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
        {
            if (GetPlaintextLimit(len) < 0)
            {
                throw new TlsFatalAlert(AlertDescription.decode_error);
            }

            byte[] nonce = new byte[this.decryptImplicitNonce.Length + 8];
            Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length);
            //Array.Copy(ciphertext, offset, nonce, decryptImplicitNonce.Length, nonce_explicit_length);
            if (record_iv_length == 0)
            {
                TlsUtilities.WriteUint64(seqNo, nonce, decryptImplicitNonce.Length);
            }
            else
            {
                Array.Copy(ciphertext, offset, nonce, nonce.Length - record_iv_length, record_iv_length);
            }

            int ciphertextOffset = offset + record_iv_length;
            int ciphertextLength = len - record_iv_length;
            int plaintextLength  = decryptCipher.GetOutputSize(ciphertextLength);

            byte[] output    = new byte[plaintextLength];
            int    outputPos = 0;

            byte[]         additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters     = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                decryptCipher.Init(false, parameters);
                outputPos += decryptCipher.ProcessBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos);
                outputPos += decryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
            }

            if (outputPos != output.Length)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return(output);
        }
Beispiel #17
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
        {
            byte[] nonce = new byte[this.encryptImplicitNonce.Length + 8];
            Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length);

            /*
             * RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number.
             * draft-zauner-tls-aes-ocb-03: uses the sequence number (not included in message).
             *
             * (May need review for other AEAD ciphers).
             */
            TlsUtilities.WriteUint64(seqNo, nonce, encryptImplicitNonce.Length);

            int plaintextOffset  = offset;
            int plaintextLength  = len;
            int ciphertextLength = encryptCipher.GetOutputSize(plaintextLength);

            byte[] output = new byte[record_iv_length + ciphertextLength];
            if (record_iv_length != 0)
            {
                Array.Copy(nonce, nonce.Length - record_iv_length, output, 0, record_iv_length);
            }
            int outputPos = record_iv_length;

            byte[]         additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters     = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                encryptCipher.Init(true, parameters);
                outputPos += encryptCipher.ProcessBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos);
                outputPos += encryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error, e);
            }

            if (outputPos != output.Length)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return(output);
        }
Beispiel #18
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());
            }
        }
Beispiel #19
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");
            }
        }
Beispiel #20
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);
			}
		}
        /********EXTERNAL OBJECT PUBLIC METHODS  - BEGIN ********/



        /// <summary>
        /// Encrypts the given 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="plainText"> string UTF-8 plain text to encrypt</param>
        /// <returns></returns>
        public string DoAEADEncrypt(string symmetricBlockAlgorithm, string symmetricBlockMode,
                                    string key, int macSize, string nonce, string plainText)
        {
            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, "SB024", this.error);
            byte[] keyBytes   = SecurityUtils.GetHexa(key, "SB024", this.error);
            if (this.HasError())
            {
                return("");
            }

            KeyParameter keyParam = new KeyParameter(keyBytes);

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

            try
            {
                bbc.Init(true, AEADparams);
            }catch (Exception e)
            {
                this.error.setError("SB029", e.Message);
                return("");
            }
            EncodingUtil eu = new EncodingUtil();

            byte[] inputBytes = eu.getBytes(plainText);
            if (eu.GetError().existsError())
            {
                this.error = eu.GetError();
                return("");
            }
            byte[] outputBytes = new byte[bbc.GetOutputSize(inputBytes.Length)];
            int    length      = bbc.ProcessBytes(inputBytes, 0, inputBytes.Length, outputBytes, 0);

            try
            {
                bbc.DoFinal(outputBytes, length);
            }
            catch (Exception)
            {
                this.error.setError("SB010", "AEAD encryption exception");
                return("");
            }
            string result = Base64.ToBase64String(outputBytes);

            if (result == null || result.Length == 0)
            {
                this.error.setError("SB011", "Error encoding base64");
                return("");
            }
            this.error.cleanError();
            return(result);
        }
Beispiel #22
0
        private void RandomTest(SecureRandom srng)
        {
            int kLength = 16 + 8 * (System.Math.Abs(srng.NextInt()) % 3);

            byte[] K = new byte[kLength];
            srng.NextBytes(K);

            int pLength = (int)((uint)srng.NextInt() >> 16);

            byte[] P = new byte[pLength];
            srng.NextBytes(P);

            int aLength = (int)((uint)srng.NextInt() >> 24);

            byte[] A = new byte[aLength];
            srng.NextBytes(A);

            int saLength = (int)((uint)srng.NextInt() >> 24);

            byte[] SA = new byte[saLength];
            srng.NextBytes(SA);

            int ivLength = 1 + NextInt(srng, 15);

            byte[] IV = new byte[ivLength];
            srng.NextBytes(IV);

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

            byte[] C         = new byte[cipher.GetOutputSize(P.Length)];
            int    predicted = cipher.GetUpdateOutputSize(P.Length);

            int split = NextInt(srng, SA.Length + 1);

            cipher.ProcessAadBytes(SA, 0, split);
            int len = cipher.ProcessBytes(P, 0, P.Length, C, 0);

            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            if (predicted != len)
            {
                Fail("encryption reported incorrect update length in randomised test");
            }

            len += cipher.DoFinal(C, len);

            if (C.Length != len)
            {
                Fail("encryption reported incorrect length in randomised test");
            }

            byte[] encT = cipher.GetMac();
            byte[] tail = new byte[C.Length - P.Length];
            Array.Copy(C, P.Length, tail, 0, tail.Length);

            if (!AreEqual(encT, tail))
            {
                Fail("stream contained wrong mac in randomised test");
            }

            cipher.Init(false, parameters);
            byte[] decP = new byte[cipher.GetOutputSize(C.Length)];
            predicted = cipher.GetUpdateOutputSize(C.Length);

            split = NextInt(srng, SA.Length + 1);
            cipher.ProcessAadBytes(SA, 0, split);
            len = cipher.ProcessBytes(C, 0, C.Length, decP, 0);
            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            if (predicted != len)
            {
                Fail("decryption reported incorrect update length in randomised test");
            }

            len += cipher.DoFinal(decP, len);

            if (!AreEqual(P, decP))
            {
                Fail("incorrect decrypt in randomised test");
            }

            byte[] decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }

            //
            // key reuse test
            //
            cipher.Init(false, AeadTestUtilities.ReuseKey(parameters));
            decP = new byte[cipher.GetOutputSize(C.Length)];

            split = NextInt(srng, SA.Length + 1);
            cipher.ProcessAadBytes(SA, 0, split);
            len = cipher.ProcessBytes(C, 0, C.Length, decP, 0);
            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            len += cipher.DoFinal(decP, len);

            if (!AreEqual(P, decP))
            {
                Fail("incorrect decrypt in randomised test");
            }

            decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }
        }