Пример #1
0
            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));
            }
Пример #2
0
            public State(long aSize, int blockSize, int tagSize, byte[] j0, IDigest tagHash, CTRBlockCipher ctr, IBlockCipher cipher)
            {
                _aSize = aSize;

                _j0      = j0;
                _tagHash = tagHash;
                _ctr     = ctr;
                _cipher  = cipher;

                _buffer    = new byte[blockSize];
                _blockSize = blockSize;
                _tagSize   = tagSize;
            }
Пример #3
0
            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));
            }
Пример #4
0
        public void Init(ICipherParameters parameters)
        {
            // setup AAD
            var aadParam = parameters as AADParameter;

            SecurityAssert.NotNull(aadParam);

            var a     = aadParam !.AAD;
            var aSize = a.Length * 8;

            // setup IV
            var ivParam = aadParam !.Parameters as IVParameter;

            SecurityAssert.NotNull(ivParam);

            var iv     = ivParam !.IV;
            var ivSize = iv.Length * 8;

            // setup cipher
            _cipher.Init(ivParam !.Parameters);

            // setup H subkey
            var h = new byte[16];

            _cipher.EncryptBlock(new byte[16], 0, h, 0);

            // setup tag hash
            var tagHash = new GHash(h);

            tagHash.Update(a);
            var tagAADPaddingLength = 16 - a.Length % 16;

            tagHash.Update(new byte[tagAADPaddingLength]);

            // setup pre-counter block
            byte[] j0;
            if (iv.Length == 12)
            {
                // IV || 0^31 ||1

                j0 = new byte[16];
                Array.Copy(iv, j0, 12);
                j0[15] = 1;
            }
            else
            {
                // GHASH_H(IV || 0^(s+64) || [len(IV)])

                var j0PaddingLength = 8 + (16 - iv.Length % 16) % 16;

                var j0Hash = new GHash(h);
                j0Hash.Update(iv);
                j0Hash.Update(new byte[j0PaddingLength]);
                j0Hash.Update(EndianBitConverter.Big.GetBytes((long)ivSize));

                j0 = j0Hash.DigestBuffer();
            }

            var ctr = new CTRBlockCipher(_cipher);

            ctr.Init(new IVParameter(j0));
            ctr.Inc();

            _state = new State(aSize, BlockLength, TagLength, j0, tagHash, ctr, _cipher);
        }