Пример #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);
            }
        }
Пример #2
0
    public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
    {
        byte[] array = new byte[encryptImplicitNonce.Length + nonce_explicit_length];
        Array.Copy(encryptImplicitNonce, 0, array, 0, encryptImplicitNonce.Length);
        TlsUtilities.WriteUint64(seqNo, array, encryptImplicitNonce.Length);
        int outputSize = encryptCipher.GetOutputSize(len);

        byte[] array2 = new byte[nonce_explicit_length + outputSize];
        Array.Copy(array, encryptImplicitNonce.Length, array2, 0, nonce_explicit_length);
        int num = nonce_explicit_length;

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

        try
        {
            encryptCipher.Init(forEncryption: true, parameters);
            num += encryptCipher.ProcessBytes(plaintext, offset, len, array2, num);
            num += encryptCipher.DoFinal(array2, num);
        }
        catch (Exception alertCause)
        {
            throw new TlsFatalAlert(80, alertCause);
        }
        if (num != array2.Length)
        {
            throw new TlsFatalAlert(80);
        }
        return(array2);
    }
Пример #3
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));
        }
Пример #4
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);
        }
Пример #5
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());
            }
        }
Пример #6
0
        /// <summary>
        /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
        /// </summary>
        /// <param name="buffer">An array of bytes. This method copies <paramref name="count"/> bytes from <paramref name="buffer"/> to the current stream.</param>
        /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin copying bytes to the current stream.</param>
        /// <param name="count">The number of bytes to be written to the current stream.</param>
        /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length. </exception>
        /// <exception cref="T:System.ArgumentNullException">
        ///     <paramref name="buffer"/> is null. </exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        ///     <paramref name="offset"/> or <paramref name="count"/> is negative. </exception>
        /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
        /// <exception cref="T:System.NotSupportedException">The stream does not support writing. </exception>
        /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (!_init)
            {
                if (_encrypt)
                {
                    _output.Write(_nonce, 0, _nonce.Length);
                }
                else
                {
                    Array.Copy(buffer, 0, _nonce, 0, _nonce.Length);

                    offset = offset + _nonce.Length;
                    count  = count - _nonce.Length;
                }
                _initFunc(_nonce, _cipher, _header, _encrypt);
                _init = true;
            }

            var outBuffer = new byte[_cipher.GetUpdateOutputSize(count)];
            var outLen    = _cipher.ProcessBytes(buffer, offset, count, outBuffer, 0);

            _output.Write(outBuffer, 0, outLen);
            Secure.Clear(outBuffer);
            _outLen += outLen;
            _inLen  += count;
        }
Пример #7
0
    public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
    {
        if (GetPlaintextLimit(len) < 0)
        {
            throw new TlsFatalAlert(50);
        }
        byte[] array = new byte[decryptImplicitNonce.Length + nonce_explicit_length];
        Array.Copy(decryptImplicitNonce, 0, array, 0, decryptImplicitNonce.Length);
        Array.Copy(ciphertext, offset, array, decryptImplicitNonce.Length, nonce_explicit_length);
        int inOff      = offset + nonce_explicit_length;
        int len2       = len - nonce_explicit_length;
        int outputSize = decryptCipher.GetOutputSize(len2);

        byte[] array2 = new byte[outputSize];
        int    num    = 0;

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

        try
        {
            decryptCipher.Init(forEncryption: false, parameters);
            num += decryptCipher.ProcessBytes(ciphertext, inOff, len2, array2, num);
            num += decryptCipher.DoFinal(array2, num);
        }
        catch (Exception alertCause)
        {
            throw new TlsFatalAlert(20, alertCause);
        }
        if (num != array2.Length)
        {
            throw new TlsFatalAlert(80);
        }
        return(array2);
    }
        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());
        }
        /// <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));
        }
Пример #10
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);
        }
Пример #11
0
 /**
  * process an array of bytes, producing output if necessary.
  *
  * @param in the input byte array.
  * @param inOff the offset at which the input data starts.
  * @param len the number of bytes to be copied out of the input array.
  * @param out the space for any output that might be produced.
  * @param outOff the offset from which the output will be copied.
  * @return the number of output bytes copied to out.
  * @exception DataLengthException if there isn't enough space in out.
  * @exception InvalidOperationException if the cipher isn't initialised.
  */
 public override int ProcessBytes(
     byte[]  input,
     int inOff,
     int length,
     byte[]  output,
     int outOff)
 {
     return(cipher.ProcessBytes(input, inOff, length, output, outOff));
 }
Пример #12
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);
        }
Пример #13
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);
        }
Пример #14
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);
        }
Пример #15
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);
                }
            }
        }
Пример #16
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);
        }
Пример #17
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());
            }
        }
Пример #18
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);
        }
Пример #20
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);
                }
            }
        }
Пример #21
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;
        }
Пример #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");
            }
        }