Example #1
0
        private static void Test4(IBlockCrypto crypto, string hex1, string hex2)
        {
            Assert.AreEqual(@"AES-CBC", crypto.Name);
            Assert.AreEqual(16, crypto.BlockSize);

            Span <byte> h1 = hex1.FromHex();
            Span <byte> h2 = hex2.FromHex();
            Span <byte> o1 = stackalloc byte[64];

            crypto.Encrypt4(h1, o1);
            Assert.IsTrue(o1.SequenceEqual(h2));

            crypto.Reset();

            crypto.Encrypt4(h1, o1);
            Assert.IsTrue(o1.SequenceEqual(h2));

            crypto.Reset();

            crypto.Decrypt(h2, o1);
            crypto.Decrypt(h2.Slice(16), o1.Slice(16));
            crypto.Decrypt(h2.Slice(32), o1.Slice(32));
            crypto.Decrypt(h2.Slice(48), o1.Slice(48));

            Assert.IsTrue(o1.SequenceEqual(h1));

            crypto.Dispose();
        }
Example #2
0
        private static void Test4(IBlockCrypto crypto, string hex1, string hex2)
        {
            Assert.AreEqual(@"AES", crypto.Name);
            Assert.AreEqual(16, crypto.BlockSize);

            Span <byte> h1 = hex1.FromHex();
            Span <byte> h2 = hex2.FromHex();
            Span <byte> o1 = stackalloc byte[crypto.BlockSize * 4];

            crypto.Encrypt4(h1, o1);
            Assert.IsTrue(o1.SequenceEqual(h2));

            crypto.Encrypt4(h1, o1);
            Assert.IsTrue(o1.SequenceEqual(h2));

            crypto.Dispose();
        }
Example #3
0
        private void TestEncrypt4(IBlockCrypto crypto, Span <byte> origin)
        {
            Span <byte> o = stackalloc byte[origin.Length];

            for (var i = 0; i < Max; ++i)
            {
                crypto.Encrypt4(origin, o);
            }

            crypto.Dispose();
        }
Example #4
0
        public unsafe void Encrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source,
                                   Span <byte> destination, Span <byte> tag, ReadOnlySpan <byte> associatedData = default)
        {
            if (nonce.Length != NonceSize)
            {
                throw new ArgumentException(@"Nonce size must be 12 bytes", nameof(nonce));
            }

            if (destination.Length != source.Length)
            {
                throw new ArgumentException(string.Empty, nameof(destination));
            }

            var length = (ulong)source.Length << 3;

            var counterBlock = _counterBlock.AsSpan(0, BlockSize4);
            var counter0     = counterBlock.Slice(12, 4);
            var counter1     = counterBlock.Slice(28, 4);
            var counter2     = counterBlock.Slice(44, 4);
            var counter3     = counterBlock.Slice(60, 4);

            nonce.CopyTo(counterBlock);
            nonce.CopyTo(counterBlock.Slice(16));
            nonce.CopyTo(counterBlock.Slice(32));
            nonce.CopyTo(counterBlock.Slice(48));

            counter0[0] = 0;
            counter0[1] = 0;
            counter0[2] = 0;
            counter0[3] = 1;

            counter1[0] = 0;
            counter1[1] = 0;
            counter1[2] = 0;
            counter1[3] = 3;

            counter2[0] = 0;
            counter2[1] = 0;
            counter2[2] = 0;
            counter2[3] = 4;

            counter3[0] = 0;
            counter3[1] = 0;
            counter3[2] = 0;
            counter3[3] = 5;

            _crypto.Encrypt(counterBlock, tag);
            counter0[3] = 2;

            _gHash.Update(associatedData);

            while (!source.IsEmpty)
            {
                _crypto.Encrypt4(counterBlock, _buffer);
                counter0.IncrementBe4();
                counter1.IncrementBe4();
                counter2.IncrementBe4();
                counter3.IncrementBe4();

                var n = Math.Min(source.Length, BlockSize4);

                fixed(byte *pOut = destination)
                fixed(byte *pSource = source)
                fixed(byte *pBuffer = _buffer)
                {
                    IntrinsicsUtils.Xor(pSource, pBuffer, pOut, n);
                }

                _gHash.Update(destination.Slice(0, n));

                source      = source.Slice(n);
                destination = destination.Slice(n);
            }

            BinaryPrimitives.WriteUInt64BigEndian(_buffer, (ulong)associatedData.Length << 3);
            BinaryPrimitives.WriteUInt64BigEndian(_buffer.AsSpan(8), length);

            _gHash.Update(_buffer.AsSpan(0, TagSize));
            _gHash.GetMac(_buffer);

            fixed(byte *pTag = tag)
            fixed(byte *pBuffer = _buffer)
            {
                IntrinsicsUtils.Xor16(pTag, pBuffer, pTag);
            }
        }