public static Decrypt ( byte masterKey, ArraySegment |
||
masterKey | byte | |
ciphertext | ArraySegment |
|
salt | ArraySegment |
|
counter | uint | |
return | byte[] |
}// Decrypt() public static byte[] Decrypt(byte[] masterKey, ArraySegment<byte> ciphertext, ArraySegment<byte>? salt = null, uint counter = 1) { int cipherLength = ciphertext.Count - CONTEXT_BUFFER_LENGTH - MAC_LENGTH; if (cipherLength < 0) return null; var bufferSegment = default(ArraySegment<byte>?); EtM_CTR.Decrypt(masterKey, ciphertext, ref bufferSegment, salt, counter); return (bufferSegment != null) ? bufferSegment.GetValueOrDefault().Array : null; }// Decrypt()
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { int partialBlockSize = inputCount % EtM_Transform_Constants.OUTPUT_BLOCK_SIZE; int fullBlockSize = inputCount - partialBlockSize; if (partialBlockSize != 0) throw new Exception("inputCount must be a multiple of output block size (" + EtM_Transform_Constants.OUTPUT_BLOCK_SIZE.ToString() + ")."); int i = 0, j = 0; if (fullBlockSize > 0) { var authenticateOnly = this.IsAuthenticateOnly; for (; i < fullBlockSize; i += EtM_Transform_Constants.OUTPUT_BLOCK_SIZE, j += EtM_Transform_Constants.INPUT_BLOCK_SIZE) { var outputSegment = new ArraySegment<byte>?(new ArraySegment<byte>(outputBuffer, outputOffset + j, EtM_Transform_Constants.INPUT_BLOCK_SIZE)); var cipherText = new ArraySegment<byte>(inputBuffer, inputOffset + i, EtM_Transform_Constants.OUTPUT_BLOCK_SIZE); if (authenticateOnly) { if (!EtM_CTR.Authenticate( masterKey: this.key, ciphertext: cipherText, salt: this.salt, counter: this.currentChunkNumber)) outputSegment = null; } else { EtM_CTR.Decrypt( masterKey: this.key, ciphertext: cipherText, outputSegment: ref outputSegment, salt: this.salt, counter: this.currentChunkNumber); } if (outputSegment == null) { this.key = null; throw new CryptographicException("Decryption failed for block " + this.currentChunkNumber.ToString() + "."); } if (this.currentChunkNumber == EtM_Transform_Constants.INITIAL_CHUNK_NUMBER) { EtM_EncryptTransform.PrependSaltWith1stBlockContext(ref this.salt, inputBuffer, inputOffset); } checked { ++this.currentChunkNumber; } } } return j; }// TransformBlock()
}// TransformBlock() public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { if (this.key == null) return null; // key would be null if this instance has already been disposed, or previously-called TransformBlock() failed if (inputCount >= EtM_Transform_Constants.OUTPUT_BLOCK_SIZE) throw new Exception("Final output block size must be smaller than " + EtM_Transform_Constants.OUTPUT_BLOCK_SIZE.ToString() + "."); if (inputCount < EtM_Transform_Constants.ETM_CTR_OVERHEAD) throw new Exception("Final output block size must must be at least " + EtM_Transform_Constants.ETM_CTR_OVERHEAD.ToString() + "."); byte[] outputBuffer = null; var cipherText = new ArraySegment<byte>(inputBuffer, inputOffset, inputCount); if (this.IsAuthenticateOnly) { if (EtM_CTR.Authenticate( masterKey: this.key, ciphertext: cipherText, salt: this.salt, counter: this.currentChunkNumber)) outputBuffer = Array.Empty<byte>(); } else { outputBuffer = EtM_CTR.Decrypt( masterKey: this.key, ciphertext: cipherText, salt: this.salt, counter: this.currentChunkNumber); } this.Dispose(); if (outputBuffer == null) throw new CryptographicException("Decryption failed for block " + this.currentChunkNumber.ToString() + "."); this.IsComplete = true; return outputBuffer; }// TransformFinalBlock()
public static byte[] Decrypt(byte[] masterKey, ArraySegment<byte> ciphertext, ArraySegment<byte>? salt = null) { return EtM_CTR.Decrypt(masterKey, ciphertext, salt); }