/// <summary> /// Start an encryption session with random key and IV. /// </summary> public virtual CryptoData Decrypt(CryptoData Input, byte[] Data) { StartDecrypt(Input.Key, Input.IV); return Process(Data); }
/// <summary> /// Processes the specified input data. /// </summary> /// <param name="Data">The input to process</param> /// <returns>The result of the cryptographic operation.</returns> public virtual CryptoData Process(CryptoData Data) { return Process(Data.Data); }
/// <summary> /// Processes the specified region of the specified byte array /// </summary> /// <param name="InputBuffer">The input to process</param> /// <param name="InputOffset">The offset into the byte array from which to begin using data.</param> /// <param name="Count">The number of bytes in the array to use as data.</param> /// <returns>The result of the cryptographic operation.</returns> public override CryptoData Process(byte[] InputBuffer, int InputOffset, int Count) { int FullBlocks; int ExtraBytes; int LastOffset = 0; if (Encrypting) { Transform = Provider.CreateEncryptor(); FullBlocks = Count / Transform.InputBlockSize; ExtraBytes = AppendIV ? Transform.InputBlockSize : 0; // calculate extra bytes required for padding if (Provider.Mode == CipherMode.CBC) { ExtraBytes += Transform.OutputBlockSize; } else if (Provider.Mode == CipherMode.CTS) { // Cipher Text Stealling does not require padding unless there is // less than a full block in the input. ExtraBytes += FullBlocks == 0 ? Transform.OutputBlockSize : Count % Transform.InputBlockSize; } } else { Transform = Provider.CreateDecryptor(); FullBlocks = (Count / Transform.InputBlockSize) - 1 - (AppendIV ? 1 : 0); // This will always be more than needed. ExtraBytes = Transform.OutputBlockSize; LastOffset = FullBlocks > 0 ? Transform.OutputBlockSize : 0; } // Here we will need to add code to manage the additional data for the // integrity check value and initialization when available. int TotalBytes = FullBlocks * Transform.OutputBlockSize + ExtraBytes; byte[] OutputBuffer = new byte[TotalBytes]; int OutputOffset = 0; if (AppendIV) { Array.Copy(Provider.IV, OutputBuffer, Provider.IV.Length); OutputOffset += Provider.IV.Length; } if (FullBlocks == 0) { } else if (Transform.CanTransformMultipleBlocks) { // Can we do it the fast way? Transform.TransformBlock(InputBuffer, InputOffset, FullBlocks * Transform.InputBlockSize, OutputBuffer, OutputOffset); InputOffset += FullBlocks * Transform.InputBlockSize; OutputOffset += FullBlocks * Transform.OutputBlockSize; } else { // Do it the lame way for (var i = 0; i < FullBlocks; i++) { Transform.TransformBlock(InputBuffer, InputOffset, Transform.InputBlockSize, OutputBuffer, OutputOffset); InputOffset += Transform.InputBlockSize; OutputOffset += Transform.OutputBlockSize; } } var LastBlock = Transform.TransformFinalBlock(InputBuffer, InputOffset, Count - FullBlocks * Transform.InputBlockSize); Array.Copy(LastBlock, 0, OutputBuffer, OutputOffset - LastOffset, LastBlock.Length); Array.Resize(ref OutputBuffer, TotalBytes - Transform.OutputBlockSize + LastBlock.Length - LastOffset); var CryptoResult = new CryptoData(CryptoAlgorithmID.NULL, null, null, OutputBuffer); CryptoResult.IV = IV; CryptoResult.Key = Key; return CryptoResult; }
/// <summary> /// Create a new encryption context and encrypt the data under the /// generated content key and IV. /// </summary> /// <param name="Data">The data to encrypt</param> /// <param name="Encryptor">The encryption provider to use.</param> public void Encrypt(byte[] Data, CryptoProviderEncryption Encryptor) { //Trace.WriteHex("Encryption Key", Encryptor.Key); CryptoData = Encryptor.Encrypt(Data); var Preheader = new Header(Encryptor); Protected = Preheader.GetBytes(false); // get the data bytes untagged IV = CryptoData.IV; JTag = CryptoData.Integrity; CipherText = CryptoData.Data; }
/// <summary> /// Encrypt the provided cryptoblob /// </summary> public virtual CryptoData Encrypt(CryptoData Input) { StartEncrypt(Input.Key, Input.IV); return Process(Input); }
/// <summary> /// Computes the hash value for the specified region of the specified byte array /// </summary> /// <param name="Buffer">The input to compute the hash code for.</param> /// <param name="offset">The offset into the byte array from which to begin using data.</param> /// <param name="count">The number of bytes in the array to use as data.</param> /// <returns>The computed hash code.</returns> public override CryptoData Process(byte[] Buffer, int offset, int count) { var Data = HashAlgorithm.ComputeHash(Buffer, offset, count); var CryptoDigestValue = new CryptoData(CryptoAlgorithmID, OID, Data); return CryptoDigestValue; }
/// <summary> /// Terminates a part processing session and returns the result. /// </summary> /// <returns>The computed hash code.</returns> public override CryptoData TransformFinal() { if (MemoryStream == null) { MemoryStream = new MemoryStream(); } var Data = HashAlgorithm.ComputeHash(MemoryStream); var CryptoDigestValue = new CryptoData(CryptoAlgorithmID, OID, Data); return CryptoDigestValue; }
/// <summary> /// Encrypt key data. /// </summary> /// <param name="Input">The key data to encrypt.</param> /// <returns>Encrypted data</returns> public CryptoData Encrypt(CryptoData Input) { var Result = Encrypt(Input.Key); return new CryptoData(CryptoAlgorithmID, OID, null, Result, null, null); }
/// <summary> /// Decrypt data. Note that this is only possibly when the corresponding private /// key is available on the local machine. /// </summary> /// <param name="Input">The data to decrypt.</param> /// <returns>Decrypted data.</returns> public CryptoData Decrypt(CryptoData Input) { var Result = Decrypt(Input.Data); return new CryptoData(CryptoAlgorithmID, OID, null, null, Result, null); }
/// <summary> /// Sign a previously computed digest (requires private key). /// </summary> /// <param name="Data">Computed digest</param> /// <returns>Signature</returns> public abstract CryptoData Sign(CryptoData Data);
/// <summary> /// Verify signature. /// </summary> /// <param name="Data">Computed digest</param> /// <param name="Signature">Signature</param> /// <returns>True if signature verification is successful, otherwise false.</returns> public override bool Verify(CryptoData Data, byte [] Signature) { return Provider.VerifyHash(Data.Integrity, Data.OID, Signature); }
/// <summary> /// Sign a previously computed digest (requires private key). /// </summary> /// <param name="Data">Computed digest</param> /// <returns>Signature</returns> public override CryptoData Sign(CryptoData Data) { var Signature = Provider.SignHash(Data.Integrity, Data.OID); var Result = new CryptoData(CryptoAlgorithmID, OID, Signature); return Result; }
/// <summary> /// Verify signature. /// </summary> /// <param name="Data">Computed digest</param> /// <param name="Signature">Signature</param> /// <returns>True if signature verification is successful, otherwise false.</returns> public virtual bool Verify(CryptoData Data, CryptoData Signature) { return Verify(Data, Signature.Integrity); }
/// <summary> /// Verify signature. /// </summary> /// <param name="Data">Computed digest</param> /// <param name="Signature">Signature</param> /// <returns>True if signature verification is successful, otherwise false.</returns> public abstract bool Verify(CryptoData Data, byte[] Signature);