public static IDStorage decryptKeyStoreStorage(byte[] c_baKey, byte[] c_baIV, string c_sBase64JsonStorage) { const int MacBitSize = 128; byte [] baPayload = new byte[0]; var decryptCipher = new GcmBlockCipher(new AesFastEngine()); var parameters = new AeadParameters(new KeyParameter(c_baKey), MacBitSize, c_baIV, baPayload); decryptCipher.Init (false, parameters); byte[] baEncryptedStorage = Convert.FromBase64String (c_sBase64JsonStorage); var decryptedText = new byte[decryptCipher.GetOutputSize(baEncryptedStorage.Length)]; try { var len = decryptCipher.ProcessBytes(baEncryptedStorage, 0, baEncryptedStorage.Length, decryptedText, 0); decryptCipher.DoFinal(decryptedText, len); } catch (InvalidCipherTextException) { //Return null if it doesn't authenticate return null; } string sJsonStorage = Encoding.GetEncoding (1252).GetString (decryptedText); IDStorage _KeyStoreStorage = JsonConvert.DeserializeObject <IDStorage> (sJsonStorage); return _KeyStoreStorage; }
public JObject Encrypt(string key, JObject blob, string adata) { var result = new JObject(); var random = new SecureRandom(); var iv = new byte[32]; var salt = new byte[8]; random.NextBytes(salt); random.NextBytes(iv); try { byte[] plainBytes = Encoding.UTF8.GetBytes(blob.ToString()); byte[] adataBytes = Encoding.UTF8.GetBytes(adata); byte[] nonce = ComputeNonce(iv, plainBytes); KeyParameter keyParam = CreateKey(key, salt, _iter, _ks); var ccm = new AeadParameters(keyParam, MacSize(_ts), nonce, adataBytes); var aes = new CcmBlockCipher(new AesFastEngine()); aes.Init(true, ccm); var enc = new byte[aes.GetOutputSize(plainBytes.Length)]; int res = aes.ProcessBytes(plainBytes, 0, plainBytes.Length, enc, 0); aes.DoFinal(enc, res); result.Add("ct", Base64.ToBase64String(enc)); result.Add("iv", Base64.ToBase64String(iv)); result.Add("salt", Base64.ToBase64String(salt)); result.Add("adata", EncodeAdata(adata)); result.Add("mode", Mode); result.Add("ks", _ks); result.Add("iter", _iter); result.Add("ts", _ts); return result; } catch (Exception e) { throw new ApplicationException("Json encryption failed.", e); } }
/// <summary> /// Simple Encryption And Authentication (AES-GCM) of a UTF8 string. /// </summary> /// <param name="secretMessage">The secret message.</param> /// <param name="key">The key.</param> /// <param name="nonSecretPayload">Optional non-secret payload.</param> /// <returns>Encrypted Message</returns> /// <remarks> /// Adds overhead of (Optional-Payload + BlockSize(16) + Message + HMac-Tag(16)) * 1.33 Base64 /// </remarks> public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null) { //User Error Checks if (key == null || key.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key"); if (secretMessage == null || secretMessage.Length == 0) throw new ArgumentException("Secret Message Required!", "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 cipher = new GcmBlockCipher(new AesFastEngine()); var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload); cipher.Init(true, parameters); //Generate Cipher Text With Auth Tag var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)]; var len = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0); cipher.DoFinal(cipherText, len); //Assemble Message using (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(); } }
private GcmBlockCipher initCipher( IGcmMultiplier m, bool forEncryption, AeadParameters parameters) { GcmBlockCipher c = new GcmBlockCipher(new AesFastEngine(), m); c.Init(forEncryption, parameters); return c; }
private void runTestCase( string[] testVector, int macLength) { int pos = 0; string testName = testVector[pos++]; byte[] K = Hex.Decode(testVector[pos++]); byte[] P = Hex.Decode(testVector[pos++]); byte[] A = Hex.Decode(testVector[pos++]); byte[] IV = Hex.Decode(testVector[pos++]); byte[] C = Hex.Decode(testVector[pos++]); // For short MAC, take leading bytes byte[] t = Hex.Decode(testVector[pos++]); byte[] T = new byte[macLength]; Array.Copy(t, T, T.Length); AeadParameters parameters = new AeadParameters(new KeyParameter(K), T.Length * 8, IV, A); // Default multiplier runTestCase(null, null, parameters, testName, P, C, T); runTestCase(new BasicGcmMultiplier(), new BasicGcmMultiplier(), parameters, testName, P, C, T); runTestCase(new Tables8kGcmMultiplier(), new Tables8kGcmMultiplier(), parameters, testName, P, C, T); runTestCase(new Tables64kGcmMultiplier(), new Tables64kGcmMultiplier(), parameters, testName, P, C, T); }
private void checkVectors( int count, string additionalDataType, byte[] k, int macSize, byte[] n, byte[] a, byte[] sa, byte[] p, byte[] t, byte[] c) { EaxBlockCipher encEax = new EaxBlockCipher(new AesFastEngine()); EaxBlockCipher decEax = new EaxBlockCipher(new AesFastEngine()); AeadParameters parameters = new AeadParameters(new KeyParameter(k), macSize, n, a); encEax.Init(true, parameters); decEax.Init(false, parameters); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); // key reuse test parameters = new AeadParameters(null, macSize, n, a); encEax.Init(true, parameters); decEax.Init(false, parameters); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c); }
/// <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 + nonce_explicit_length]; Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length); /* * RFC 5288/6655 The nonce_explicit MAY be the 64-bit sequence number. * * (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[nonce_explicit_length + ciphertextLength]; Array.Copy(nonce, encryptImplicitNonce.Length, output, 0, nonce_explicit_length); int outputPos = nonce_explicit_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; }
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"); } }
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"); } }
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 IAeadBlockCipher InitOcbCipher(bool forEncryption, AeadParameters parameters) { IAeadBlockCipher c = CreateOcbCipher(); c.Init(forEncryption, parameters); return c; }
private void RunTestCase(string testName, string[] testVector, int macLengthBits, byte[] K) { int pos = 0; byte[] N = Hex.Decode(testVector[pos++]); byte[] A = Hex.Decode(testVector[pos++]); byte[] P = Hex.Decode(testVector[pos++]); byte[] C = Hex.Decode(testVector[pos++]); int macLengthBytes = macLengthBits / 8; // TODO Variations processing AAD and cipher bytes incrementally KeyParameter keyParameter = new KeyParameter(K); AeadParameters aeadParameters = new AeadParameters(keyParameter, macLengthBits, N, A); IAeadBlockCipher encCipher = InitOcbCipher(true, aeadParameters); IAeadBlockCipher decCipher = InitOcbCipher(false, aeadParameters); CheckTestCase(encCipher, decCipher, testName, macLengthBytes, P, C); CheckTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C); // TODO Key reuse }
private void RunTestCase( IGcmMultiplier encM, IGcmMultiplier decM, string testName, byte[] K, byte[] IV, byte[] A, byte[] SA, byte[] P, byte[] C, byte[] T) { AeadParameters parameters = new AeadParameters(new KeyParameter(K), T.Length * 8, IV, A); GcmBlockCipher encCipher = InitCipher(encM, true, parameters); GcmBlockCipher decCipher = InitCipher(decM, false, parameters); CheckTestCase(encCipher, decCipher, testName, SA, P, C, T); CheckTestCase(encCipher, decCipher, testName + " (reused)", SA, P, C, T); // Key reuse AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters); encCipher.Init(true, keyReuseParams); decCipher.Init(false, keyReuseParams); CheckTestCase(encCipher, decCipher, testName + " (key reuse)", SA, P, C, T); }
public static string encryptIdStorage(byte[] c_baKey, byte[] c_baIV, IDStorage c_KeyStoreStorage) { const int MacBitSize = 128; byte [] baPayload = new byte[0]; var encryptCipher = new GcmBlockCipher(new AesFastEngine()); var parameters = new AeadParameters(new KeyParameter(c_baKey), MacBitSize, c_baIV, baPayload); encryptCipher.Init (true, parameters); string sJsonStorage = JsonConvert.SerializeObject (c_KeyStoreStorage);//ConvertToJSON and byte[] baJsonStorage = Encoding.GetEncoding(1252).GetBytes(sJsonStorage);// get Bytes from ASCII-String var cipherText = new byte[encryptCipher.GetOutputSize(baJsonStorage.Length)]; var len = encryptCipher.ProcessBytes(baJsonStorage, 0, baJsonStorage.Length, cipherText, 0); encryptCipher.DoFinal(cipherText, len); string sCipherString = Convert.ToBase64String (cipherText); return sCipherString; }
/// <summary> /// Simple Decryption & Authentication (AES-GCM) of a UTF8 Message /// </summary> /// <param name="encryptedMessage">The encrypted message.</param> /// <param name="key">The key.</param> /// <param name="nonSecretPayloadLength">Length of the optional non-secret payload.</param> /// <returns>Decrypted Message</returns> public static byte[] SimpleDecrypt(byte[] encryptedMessage, byte[] key, int nonSecretPayloadLength = 0) { //User Error Checks if (key == null || key.Length != KeyBitSize / 8) throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key"); if (encryptedMessage == null || encryptedMessage.Length == 0) throw new ArgumentException("Encrypted Message Required!", "encryptedMessage"); using (var cipherStream = new MemoryStream(encryptedMessage)) using (var cipherReader = new BinaryReader(cipherStream)) { //Grab Payload var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength); //Grab Nonce var nonce = cipherReader.ReadBytes(NonceBitSize / 8); var cipher = new GcmBlockCipher(new AesFastEngine()); var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload); cipher.Init(false, parameters); //Decrypt Cipher Text var cipherText = cipherReader.ReadBytes(encryptedMessage.Length - nonSecretPayloadLength - nonce.Length); var plainText = new byte[cipher.GetOutputSize(cipherText.Length)]; try { var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0); cipher.DoFinal(plainText, len); } catch (InvalidCipherTextException) { //Return null if it doesn't authenticate return null; } return plainText; } }
/// <exception cref="IOException"></exception> public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) { 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); 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; }
/// <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 + nonce_explicit_length]; Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length); Array.Copy(ciphertext, offset, nonce, decryptImplicitNonce.Length, nonce_explicit_length); int ciphertextOffset = offset + nonce_explicit_length; int ciphertextLength = len - nonce_explicit_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[] 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; }
public JObject Decrypt(string key, JObject json) { try { byte[] iv = Base64.Decode(json.GetValue("iv").ToString()); byte[] cipherText = Base64.Decode(json.GetValue("ct").ToString()); byte[] adataBytes = DecodeAdataBytes(json.GetValue("adata").ToString()); byte[] nonce = ComputeNonce(iv, cipherText); if (json.GetValue("mode").ToString() != "ccm") { throw new ApplicationException("Can only decrypt ccm mode encrypted data."); } KeyParameter keyParam = CreateKey( key, Base64.Decode(json.GetValue("salt").ToString()), json.GetValue("iter").ToObject<int>(), json.GetValue("ks").ToObject<int>()); var ccm = new AeadParameters( keyParam, MacSize(json.GetValue("ts").ToObject<int>()), nonce, adataBytes); var aes = new CcmBlockCipher(new AesFastEngine()); aes.Init(false, ccm); var plainBytes = new byte[aes.GetOutputSize(cipherText.Length)]; int res = aes.ProcessBytes( cipherText, 0, cipherText.Length, plainBytes, 0); aes.DoFinal(plainBytes, res); var text = Encoding.UTF8.GetString(plainBytes); return JObject.Parse(text); } catch (InvalidCipherTextException) { throw; } catch (Exception e) { throw new ApplicationException("Json decryption failed.", e); } }
protected override int Decrypt (DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output) { var implicitNonce = IsClient ? ServerWriteIV : ClientWriteIV; var writeKey = IsClient ? ServerWriteKey : ClientWriteKey; #if DEBUG_FULL if (Cipher.EnableDebugging) { DebugHelper.WriteLine ("FIXED IV", implicitNonce); DebugHelper.WriteLine ("WRITE KEY", writeKey); DebugHelper.WriteLine ("SEQUENCE: {0}", ReadSequenceNumber); } #endif var length = input.Size - ExplicitNonceSize; var aad = new TlsBuffer (13); aad.Write (ReadSequenceNumber); aad.Write ((byte)contentType); aad.Write ((short)Protocol); aad.Write ((short)(length - MacSize)); #if DEBUG_FULL if (Cipher.EnableDebugging) DebugHelper.WriteFull ("TAG", aad); #endif var gcm = new GcmBlockCipher (new AesEngine ()); var key = new KeyParameter (writeKey.Buffer); var nonce = d.CreateBuffer (ImplicitNonceSize + ExplicitNonceSize); Buffer.BlockCopy (implicitNonce.Buffer, 0, nonce.Buffer, 0, ImplicitNonceSize); Buffer.BlockCopy (input.Buffer, input.Offset, nonce.Buffer, ImplicitNonceSize, ExplicitNonceSize); #if DEBUG_FULL if (Cipher.EnableDebugging) DebugHelper.WriteLine ("NONCE", nonce); #endif var parameters = new AeadParameters (key, 128, nonce.Buffer, aad.Buffer); gcm.Init (false, parameters); int ret; try { ret = gcm.ProcessBytes (input.Buffer, input.Offset + ExplicitNonceSize, length, output.Buffer, output.Offset); ret += gcm.DoFinal (output.Buffer, output.Offset + ret); } catch (CryptoException ex) { throw new TlsException (AlertDescription.BadRecordMAC, ex.Message); } return ret; }
private void checkVectors( int count, byte[] k, int macSize, byte[] n, byte[] a, byte[] p, byte[] t, byte[] c) { EaxBlockCipher encEax = new EaxBlockCipher(new AesFastEngine()); EaxBlockCipher decEax = new EaxBlockCipher(new AesFastEngine()); AeadParameters parameters = new AeadParameters(new KeyParameter(k), macSize, n, a); encEax.Init(true, parameters); decEax.Init(false, parameters); runCheckVectors(count, encEax, decEax, p, t, c); runCheckVectors(count, encEax, decEax, p, t, c); }
public byte[] Decrypt(byte[] cipherBytes, int AddtnlAuthDataLength) { if (cipherBytes == null) return null; using (var cipherStream = new MemoryStream(cipherBytes)) { using (var cipherReader = new BinaryReader(cipherStream)) { //Read Additional Authenticated Data (AddtnlAuthData) var AddtnlAuthData = cipherReader.ReadBytes(AddtnlAuthDataLength); byte[] clearBytes = null; try { // Read out IV var IV = cipherReader.ReadBytes(IVBitSize / 8); // Format AEAD parameters var parameters = new AeadParameters(keyParameter, TagBitSize, IV, AddtnlAuthData); keyParameter = null; cipher.Init(false, parameters); // Read in cipher text, create output buffer var encryptedBytes = cipherReader.ReadBytes(cipherBytes.Length - AddtnlAuthDataLength - IV.Length); clearBytes = new byte[cipher.GetOutputSize(encryptedBytes.Length)]; // Decrypt ciphertext while verifying hmac var len = cipher.ProcessBytes(encryptedBytes, 0, encryptedBytes.Length, clearBytes, 0); cipher.DoFinal(clearBytes, len); } catch (Exception ex) { //Logger.Exception(ex); if (ex is ArgumentException || ex is InvalidCipherTextException || ex is OverflowException) { return null; // this is null here } else { throw; } } return clearBytes; } } }
private void randomTest( SecureRandom srng) { int DAT_LEN = srng.Next(1024); byte[] nonce = new byte[NONCE_LEN]; byte[] authen = new byte[AUTHEN_LEN]; byte[] datIn = new byte[DAT_LEN]; byte[] key = new byte[16]; srng.NextBytes(nonce); srng.NextBytes(authen); srng.NextBytes(datIn); srng.NextBytes(key); AesFastEngine engine = new AesFastEngine(); KeyParameter sessKey = new KeyParameter(key); EaxBlockCipher eaxCipher = new EaxBlockCipher(engine); AeadParameters parameters = new AeadParameters(sessKey, MAC_LEN * 8, nonce, authen); eaxCipher.Init(true, parameters); byte[] intrDat = new byte[eaxCipher.GetOutputSize(datIn.Length)]; int outOff = eaxCipher.ProcessBytes(datIn, 0, DAT_LEN, intrDat, 0); outOff += eaxCipher.DoFinal(intrDat, outOff); eaxCipher.Init(false, parameters); byte[] datOut = new byte[eaxCipher.GetOutputSize(outOff)]; int resultLen = eaxCipher.ProcessBytes(intrDat, 0, outOff, datOut, 0); eaxCipher.DoFinal(datOut, resultLen); if (!AreEqual(datIn, datOut)) { Fail("EAX roundtrip failed to match"); } }
// encrypted = LSByte [AddtnlAuthData || IV || cipherOnly || hmac ] MSByte public byte[] Encrypt(byte[] plainBytes, byte[] AddtnlAuthData) { if (plainBytes == null) return null; // Additional Authenticated (but NOT encrypted) Data AddtnlAuthData = AddtnlAuthData ?? new byte[] { }; // IV prep if (this.IV == null) { this.IV = new byte[IVBitSize / 8]; Random.NextBytes(this.IV); } byte[] cipherBytes; try { var parameters = new AeadParameters(keyParameter, TagBitSize, IV, AddtnlAuthData); keyParameter = null; cipher.Init(true, parameters); //Generate Cipher Text With Auth Tag cipherBytes = new byte[cipher.GetOutputSize(plainBytes.Length)]; var len = cipher.ProcessBytes(plainBytes, 0, plainBytes.Length, cipherBytes, 0); cipher.DoFinal(cipherBytes, len); } catch (Exception ex) { //Logger.Exception(ex); if (ex is ArgumentException || ex is InvalidCipherTextException || ex is OverflowException) { return null; // this is null here } else { throw; } } //Assemble Message using (var combinedStream = new MemoryStream()) { using (var binaryWriter = new BinaryWriter(combinedStream)) { //Prepend Authenticated Payload binaryWriter.Write(AddtnlAuthData); //Prepend Nonce binaryWriter.Write(IV); //Write Cipher Text binaryWriter.Write(cipherBytes); } return combinedStream.ToArray(); } }
private void runTestCase( IGcmMultiplier encM, IGcmMultiplier decM, AeadParameters parameters, string testName, byte[] P, byte[] C, byte[] T) { GcmBlockCipher encCipher = initCipher(encM, true, parameters); GcmBlockCipher decCipher = initCipher(decM, false, parameters); checkTestCase(encCipher, decCipher, testName, P, C, T); checkTestCase(encCipher, decCipher, testName + " (reused)", P, C, T); }
internal static AeadParameters ReuseKey(AeadParameters p) { return new AeadParameters(null, p.MacSize, p.GetNonce(), p.GetAssociatedText()); }
private void randomTest( SecureRandom srng, IGcmMultiplier m) { int kLength = 16 + 8 * srng.Next(3); byte[] K = new byte[kLength]; srng.NextBytes(K); int pLength = srng.Next(1024); byte[] P = new byte[pLength]; srng.NextBytes(P); int aLength = srng.Next(1024); byte[] A = new byte[aLength]; srng.NextBytes(A); int ivLength = 1 + srng.Next(1024); byte[] IV = new byte[ivLength]; srng.NextBytes(IV); GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine(), m); AeadParameters parameters = new AeadParameters(new KeyParameter(K), 16 * 8, IV, A); cipher.Init(true, parameters); byte[] C = new byte[cipher.GetOutputSize(P.Length)]; int len = cipher.ProcessBytes(P, 0, P.Length, C, 0); len += cipher.DoFinal(C, len); if (C.Length != len) { // Console.WriteLine("" + 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)]; len = cipher.ProcessBytes(C, 0, C.Length, decP, 0); 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"); } }
private OcbBlockCipher InitCipher(bool forEncryption, AeadParameters parameters) { OcbBlockCipher c = new OcbBlockCipher(new AesFastEngine(), new AesFastEngine()); c.Init(forEncryption, parameters); return c; }