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); } }
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 IAeadBlockCipher InitOcbCipher(bool forEncryption, AeadParameters parameters) { IAeadBlockCipher c = CreateOcbCipher(); c.Init(forEncryption, parameters); return(c); }
/// <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)); }
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()); } }
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()); }
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)); }
/// <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); }
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)); }
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"); } }
/// <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); }
/// <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); }
/// <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); }
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()); } }
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"); } }
/********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); }
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"); } }