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); }
/// <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 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); }
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); }
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 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)); }
/// <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); }
/// <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); }
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"); } }
/// <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); }
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); }
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); } } }
/// <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 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"); } }
/// <summary> /// Finishes this instance. /// </summary> /// <exception cref="InvalidCryptoDataException"></exception> public override void Finish() { try { if (!_init && _encrypt) { _output.Write(_nonce, 0, _nonce.Length); _initFunc(_nonce, _cipher, _header, _encrypt); _init = true; } var buffLen = _cipher.GetOutputSize(_inLen) - _outLen; var buffer = new byte[buffLen]; var writeLen = _cipher.DoFinal(buffer, 0); _output.Write(buffer, 0, writeLen); Secure.Clear(buffer); } catch (InvalidCipherTextException ex) { throw new InvalidCryptoDataException(ex.Message); } }
/** * return the size of the output buffer required for an update plus a * doFinal with an input of len bytes. * * @param len the length of the input. * @return the space required to accommodate a call to update and doFinal * with len bytes of input. */ public override int GetOutputSize( int length) { return(cipher.GetOutputSize(length)); }
/********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 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; }
public int GetMaxOutputSize(int inputLen) { return(cipher.GetOutputSize(inputLen)); }
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"); } }