public AEADResult EncryptFinal(AEADResult previousResult) { var output = previousResult.RemainingOutput; if (_bufferOffset != 0) { output = EncryptBlock(output); } var tagCiphertextPaddingLength = (16 - (int)(_cSize / 8) % 16) % 16; _tagHash.Update(new byte[tagCiphertextPaddingLength]); _tagHash.Update(EndianBitConverter.Big.GetBytes(_aSize)); _tagHash.Update(EndianBitConverter.Big.GetBytes(_cSize)); var ctr = new CTRBlockCipher(_cipher); ctr.Init(new IVParameter(new NullCipherParameter(), _j0)); var blockResult = ctr.EncryptBlock(_tagHash.DigestBuffer(), output); output = blockResult.RemainingOutput; return(new AEADResult(previousResult.RemainingInput, output)); }
public AEADResult DecryptFinal(AEADResult previousResult) { if (_state == null) { throw new InvalidOperationException("GCM is not initialized"); } return(_state.DecryptFinal(previousResult)); }
public AEADResult DecryptFinal(AEADResult previousResult) { // TODO SecurityAssert.AssertBuffer(input, inputOffset, _bufferOffset + TagLength); // TODO SecurityAssert.AssertBuffer(output, outputOffset, _bufferOffset); // Consume everything but the Tag previousResult = Decrypt(previousResult.RemainingInput, previousResult.RemainingOutput); var input = previousResult.RemainingInput; var output = previousResult.RemainingOutput; if (_bufferOffset != 0) { output = DecryptBlock(output); } var tagCiphertextPaddingLength = (16 - (int)(_cSize / 8) % 16) % 16; _tagHash.Update(new byte[tagCiphertextPaddingLength]); _tagHash.Update(EndianBitConverter.Big.GetBytes(_aSize)); _tagHash.Update(EndianBitConverter.Big.GetBytes(_cSize)); var tagCtr = new CTRBlockCipher(_cipher); tagCtr.Init(new IVParameter(new NullCipherParameter(), _j0)); var digest = _tagHash.DigestBuffer(); var calculatedTag = new byte[16]; tagCtr.EncryptBlock(digest, calculatedTag); var tag = input.Slice(0, _tagSize).ToArray(); SecurityAssert.AssertHash(calculatedTag, tag); return(new AEADResult(input.Slice(_tagSize), output)); }