internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData) { byte[] buffer8; try { byte[] buffer4; EnsureConfig(); if (!fEncrypt && signData) { if ((start != 0) || (length != buf.Length)) { byte[] dst = new byte[length]; Buffer.BlockCopy(buf, start, dst, 0, length); buf = dst; start = 0; } buf = GetUnHashedData(buf); if (buf == null) { throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data")); } length = buf.Length; } if (useLegacyMode) { useLegacyMode = _UsingCustomEncryption; } MemoryStream stream = new MemoryStream(); ICryptoTransform transform = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode); CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write); bool flag = signData || ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1)); if (fEncrypt && flag) { int ivLength = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption; byte[] data = null; switch (ivType) { case IVType.Random: data = new byte[ivLength]; RandomNumberGenerator.GetBytes(data); break; case IVType.Hash: data = GetIVHash(buf, ivLength); break; } stream2.Write(data, 0, data.Length); } stream2.Write(buf, start, length); if (fEncrypt && (modifier != null)) { stream2.Write(modifier, 0, modifier.Length); } stream2.FlushFinalBlock(); byte[] src = stream.ToArray(); stream2.Close(); ReturnCryptoTransform(fEncrypt, transform, useValidationSymAlgo, useLegacyMode); if (!fEncrypt && flag) { int srcOffset = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption; int count = src.Length - srcOffset; if (count < 0) { throw new Exception(); } buffer4 = new byte[count]; Buffer.BlockCopy(src, srcOffset, buffer4, 0, count); } else { buffer4 = src; } if ((!fEncrypt && (modifier != null)) && (modifier.Length > 0)) { bool flag2 = false; for (int i = 0; i < modifier.Length; i++) { if (buffer4[(buffer4.Length - modifier.Length) + i] != modifier[i]) { flag2 = true; } } if (flag2) { throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data")); } byte[] buffer5 = new byte[buffer4.Length - modifier.Length]; Buffer.BlockCopy(buffer4, 0, buffer5, 0, buffer5.Length); buffer4 = buffer5; } if (fEncrypt && signData) { byte[] buffer6 = HashData(buffer4, null, 0, buffer4.Length); byte[] buffer7 = new byte[buffer4.Length + buffer6.Length]; Buffer.BlockCopy(buffer4, 0, buffer7, 0, buffer4.Length); Buffer.BlockCopy(buffer6, 0, buffer7, buffer4.Length, buffer6.Length); buffer4 = buffer7; } buffer8 = buffer4; } catch { throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data")); } return buffer8; }
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData) { /* This algorithm is used to perform encryption or decryption of a buffer, along with optional signing (for encryption) * or signature verification (for decryption). Possible operation modes are: * * ENCRYPT + SIGN DATA (fEncrypt = true, signData = true) * Input: buf represents plaintext to encrypt, modifier represents data to be appended to buf (but isn't part of the plaintext itself) * Output: E(iv + buf + modifier) + HMAC(E(iv + buf + modifier)) * * ONLY ENCRYPT DATA (fEncrypt = true, signData = false) * Input: buf represents plaintext to encrypt, modifier represents data to be appended to buf (but isn't part of the plaintext itself) * Output: E(iv + buf + modifier) * * VERIFY + DECRYPT DATA (fEncrypt = false, signData = true) * Input: buf represents ciphertext to decrypt, modifier represents data to be removed from the end of the plaintext (since it's not really plaintext data) * Input (buf): E(iv + m + modifier) + HMAC(E(iv + m + modifier)) * Output: m * * ONLY DECRYPT DATA (fEncrypt = false, signData = false) * Input: buf represents ciphertext to decrypt, modifier represents data to be removed from the end of the plaintext (since it's not really plaintext data) * Input (buf): E(iv + plaintext + modifier) * Output: m * * The 'iv' in the above descriptions isn't an actual IV. Rather, if ivType = IVType.Random, we'll prepend random bytes ('iv') * to the plaintext before feeding it to the crypto algorithms. Introducing randomness early in the algorithm prevents users * from inspecting two ciphertexts to see if the plaintexts are related. If ivType = IVType.None, then 'iv' is simply * an empty string. If ivType = IVType.Hash, we use a non-keyed hash of the plaintext. * * The 'modifier' in the above descriptions is a piece of metadata that should be encrypted along with the plaintext but * which isn't actually part of the plaintext itself. It can be used for storing things like the user name for whom this * plaintext was generated, the page that generated the plaintext, etc. On decryption, the modifier parameter is compared * against the modifier stored in the crypto stream, and it is stripped from the message before the plaintext is returned. * * In all cases, if something goes wrong (e.g. invalid padding, invalid signature, invalid modifier, etc.), a generic exception is thrown. */ try { EnsureConfig(); if (!fEncrypt && signData) { if (start != 0 || length != buf.Length) { // These transformations assume that we're operating on buf in its entirety and // not on any subset of buf, so we'll just replace buf with the particular subset // we're interested in. byte[] bTemp = new byte[length]; Buffer.BlockCopy(buf, start, bTemp, 0, length); buf = bTemp; start = 0; } // buf actually contains E(iv + m + modifier) + HMAC(E(iv + m + modifier)), so we need to verify and strip off the signature buf = GetUnHashedData(buf); // At this point, buf contains only E(iv + m + modifier) if the signature check succeeded. if (buf == null) { // signature verification failed throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); } // need to fix up again since GetUnhashedData() returned a different array length = buf.Length; } if (useLegacyMode) useLegacyMode = _UsingCustomEncryption; // only use legacy mode for custom algorithms System.IO.MemoryStream ms = new System.IO.MemoryStream(); ICryptoTransform cryptoTransform = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode); CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write); // DevDiv Bugs 137864: Add IV to beginning of data to be encrypted. // IVType.None is used by MembershipProvider which requires compatibility even in SP2 mode (and will set signData = false). // MSRC 10405: If signData is set to true, we must generate an IV. bool createIV = signData || ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1)); if (fEncrypt && createIV) { int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); byte[] iv = null; switch (ivType) { case IVType.Hash: // iv := H(buf) iv = GetIVHash(buf, ivLength); break; case IVType.Random: // iv := [random] iv = new byte[ivLength]; RandomNumberGenerator.GetBytes(iv); break; } Debug.Assert(iv != null, "Invalid value for IVType: " + ivType.ToString("G")); cs.Write(iv, 0, iv.Length); } cs.Write(buf, start, length); if (fEncrypt && modifier != null) { cs.Write(modifier, 0, modifier.Length); } cs.FlushFinalBlock(); byte[] paddedData = ms.ToArray(); // At this point: // If fEncrypt = true (encrypting), paddedData := Enc(iv + buf + modifier) // If fEncrypt = false (decrypting), paddedData := iv + plaintext + modifier byte[] bData; cs.Close(); // In ASP.NET 2.0, we pool ICryptoTransform objects, and this returns that ICryptoTransform // to the pool. In ASP.NET 4.0, this just disposes of the ICryptoTransform object. ReturnCryptoTransform(fEncrypt, cryptoTransform, useValidationSymAlgo, useLegacyMode); // DevDiv Bugs 137864: Strip IV from beginning of unencrypted data if (!fEncrypt && createIV) { // strip off the first bytes that were random bits int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); int bDataLength = paddedData.Length - ivLength; if (bDataLength < 0) { throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); } bData = new byte[bDataLength]; Buffer.BlockCopy(paddedData, ivLength, bData, 0, bDataLength); } else { bData = paddedData; } // At this point: // If fEncrypt = true (encrypting), bData := Enc(iv + buf + modifier) // If fEncrypt = false (decrypting), bData := plaintext + modifier if (!fEncrypt && modifier != null && modifier.Length > 0) { // MSRC 10405: Crypto board suggests blinding where signature failed // to prevent timing attacks. bool modifierCheckFailed = false; for(int iter=0; iter<modifier.Length; iter++) if (bData[bData.Length - modifier.Length + iter] != modifier[iter]) modifierCheckFailed = true; if (modifierCheckFailed) { throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); } byte[] bData2 = new byte[bData.Length - modifier.Length]; Buffer.BlockCopy(bData, 0, bData2, 0, bData2.Length); bData = bData2; } // At this point: // If fEncrypt = true (encrypting), bData := Enc(iv + buf + modifier) // If fEncrypt = false (decrypting), bData := plaintext if (fEncrypt && signData) { byte[] hmac = HashData(bData, null, 0, bData.Length); byte[] bData2 = new byte[bData.Length + hmac.Length]; Buffer.BlockCopy(bData, 0, bData2, 0, bData.Length); Buffer.BlockCopy(hmac, 0, bData2, bData.Length, hmac.Length); bData = bData2; } // At this point: // If fEncrypt = true (encrypting), bData := Enc(iv + buf + modifier) + HMAC(Enc(iv + buf + modifier)) // If fEncrypt = false (decrypting), bData := plaintext // And we're done return bData; } catch { // It's important that we don't propagate the original exception here as we don't want a production // server which has unintentionally left YSODs enabled to leak cryptographic information. throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); } }
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType) { return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, !AppSettings.UseLegacyEncryption); }
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData) { byte[] buffer8; try { byte[] buffer4; EnsureConfig(); if (!fEncrypt && signData) { if ((start != 0) || (length != buf.Length)) { byte[] dst = new byte[length]; Buffer.BlockCopy(buf, start, dst, 0, length); buf = dst; start = 0; } buf = GetUnHashedData(buf); if (buf == null) { throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data")); } length = buf.Length; } if (useLegacyMode) { useLegacyMode = _UsingCustomEncryption; } MemoryStream stream = new MemoryStream(); ICryptoTransform transform = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode); CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write); bool flag = signData || ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1)); if (fEncrypt && flag) { int ivLength = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption; byte[] data = null; switch (ivType) { case IVType.Random: data = new byte[ivLength]; RandomNumberGenerator.GetBytes(data); break; case IVType.Hash: data = GetIVHash(buf, ivLength); break; } stream2.Write(data, 0, data.Length); } stream2.Write(buf, start, length); if (fEncrypt && (modifier != null)) { stream2.Write(modifier, 0, modifier.Length); } stream2.FlushFinalBlock(); byte[] src = stream.ToArray(); stream2.Close(); ReturnCryptoTransform(fEncrypt, transform, useValidationSymAlgo, useLegacyMode); if (!fEncrypt && flag) { int srcOffset = useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption; int count = src.Length - srcOffset; if (count < 0) { throw new Exception(); } buffer4 = new byte[count]; Buffer.BlockCopy(src, srcOffset, buffer4, 0, count); } else { buffer4 = src; } if ((!fEncrypt && (modifier != null)) && (modifier.Length > 0)) { bool flag2 = false; for (int i = 0; i < modifier.Length; i++) { if (buffer4[(buffer4.Length - modifier.Length) + i] != modifier[i]) { flag2 = true; } } if (flag2) { throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data")); } byte[] buffer5 = new byte[buffer4.Length - modifier.Length]; Buffer.BlockCopy(buffer4, 0, buffer5, 0, buffer5.Length); buffer4 = buffer5; } if (fEncrypt && signData) { byte[] buffer6 = HashData(buffer4, null, 0, buffer4.Length); byte[] buffer7 = new byte[buffer4.Length + buffer6.Length]; Buffer.BlockCopy(buffer4, 0, buffer7, 0, buffer4.Length); Buffer.BlockCopy(buffer6, 0, buffer7, buffer4.Length, buffer6.Length); buffer4 = buffer7; } buffer8 = buffer4; } catch { throw new HttpException(System.Web.SR.GetString("Unable_to_validate_data")); } return(buffer8); }
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType) { // MSRC 10405: Encryption is not sufficient to prevent a malicious user from tampering with the data, and the result of decryption can // be used to discover information about the plaintext (such as via a padding or decryption oracle). We must sign anything that we // encrypt to ensure that end users can't abuse our encryption routines. // the new encrypt-then-sign behavior for everything EXCEPT Membership / MachineKey. We need to make it very clear that setting this // to 'false' is a Very Bad Thing(tm). return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, !AppSettings.UseLegacyEncryption); }
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType) { EnsureConfig(); if (useLegacyMode) { useLegacyMode = _UsingCustomEncryption; // only use legacy mode for custom algorithms } System.IO.MemoryStream ms = new System.IO.MemoryStream(); ICryptoTransform oDesEnc = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode); CryptoStream cs = new CryptoStream(ms, oDesEnc, CryptoStreamMode.Write); // DevDiv Bugs 137864: Add Random or Hashed IV to beginning of data to be encrypted. // IVType.None is used by MembershipProvider which requires compatibility even in SP2 mode. bool createIV = ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1)); if (fEncrypt && createIV) { byte[] iv = null; int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); switch (ivType) { case IVType.Hash: iv = GetIVHash(buf, ivLength); break; case IVType.Random: iv = new byte[ivLength]; RandomNumberGenerator.GetBytes(iv); break; } Debug.Assert(iv != null, "Invalid value for IVType: " + ivType.ToString("G")); cs.Write(iv, 0, iv.Length); } cs.Write(buf, start, length); if (fEncrypt && modifier != null) { cs.Write(modifier, 0, modifier.Length); } cs.FlushFinalBlock(); byte[] paddedData = ms.ToArray(); byte[] bData; cs.Close(); ReturnCryptoTransform(fEncrypt, oDesEnc, useValidationSymAlgo, useLegacyMode); // DevDiv Bugs 137864: Strip Random or Hashed IV from beginning of unencrypted data if (!fEncrypt && createIV) { // strip off the first bytes that were either random bits or a hash of the original data // either way it is always equal to the key length int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); int bDataLength = paddedData.Length - ivLength; // valid if the data is long enough to have included the padding if (bDataLength >= 0) { bData = new byte[bDataLength]; // copy from the padded data to non-padded buffer bData. // dont bother with copy if the data is entirely the padding if (bDataLength > 0) { Buffer.BlockCopy(paddedData, ivLength, bData, 0, bDataLength); } } else { // data is not padded because it is not long enough bData = paddedData; } } else { bData = paddedData; } if (!fEncrypt && modifier != null && modifier.Length > 0) { for (int iter = 0; iter < modifier.Length; iter++) { if (bData[bData.Length - modifier.Length + iter] != modifier[iter]) { throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); } } byte[] bData2 = new byte[bData.Length - modifier.Length]; Buffer.BlockCopy(bData, 0, bData2, 0, bData2.Length); bData = bData2; } return(bData); }
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType) { return(EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, !AppSettings.UseLegacyEncryption)); }
public static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType, bool signData) { return EncryptOrDecryptDataFunc(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, signData); }
internal static string EncryptStringWithIV(string s, IVType ivType) { byte[] bytes = Encoding.UTF8.GetBytes(s); return HttpServerUtility.UrlTokenEncode(MachineKeySection.EncryptOrDecryptData(true, bytes, null, 0, bytes.Length, false, false, ivType)); }
internal static string DecryptStringWithIV(string s, IVType ivType) { if (s == null) { return null; } byte[] buf = HttpServerUtility.UrlTokenDecode(s); if (buf != null) { buf = MachineKeySection.EncryptOrDecryptData(false, buf, null, 0, buf.Length, false, false, ivType); } if (buf == null) { throw new HttpException(System.Web.SR.GetString("ViewState_InvalidViewState")); } return Encoding.UTF8.GetString(buf); }
public Variable(IVType value) { _value = value; }