Example #1
0
        internal override bool Decrypt(int recordType, int version,
                                       byte[] data, ref int off, ref int len)
        {
            off += 8;
            len -= 24;
            IO.Enc64be(seq, tmp, 0);
            IO.WriteHeader(recordType, version, len, tmp, 8);
            IO.Enc64be(13 << 3, tmp, 13);
            IO.Enc64be((ulong)len << 3, tmp, 21);
            for (int i = 0; i < 16; i++)
            {
                tag[i] = 0;
            }
            GHASH.Run(tag, h, tmp, 0, 13);
            GHASH.Run(tag, h, data, off, len);
            GHASH.Run(tag, h, tmp, 13, 16);
            seq++;

            Array.Copy(data, off - 8, iv, 4, 8);
            bc.CTRRun(iv, 2, data, off, len);
            bc.CTRRun(iv, 1, data, off + len, 16);

            int z = 0;

            for (int i = 0; i < 16; i++)
            {
                z |= tag[i] ^ data[off + len + i];
            }
            return(z == 0);
        }
Example #2
0
        internal override void Encrypt(int recordType, int version,
                                       byte[] data, ref int off, ref int len)
        {
            /*
             * Explicit nonce is the encoded sequence number. We
             * encrypt the data itself; the counter starts at 2
             * (value 1 is for the authentication tag).
             */
            IO.Enc64be(seq, data, off - 8);
            Array.Copy(data, off - 8, iv, 4, 8);
            bc.CTRRun(iv, 2, data, off, len);

            /*
             * For the authentication tag:
             *   header = sequence + 5-byte "plain" header
             *   footer = the two relevant lengths (in bits)
             */
            IO.Enc64be(seq, tmp, 0);
            IO.WriteHeader(recordType, version, len, tmp, 8);
            IO.Enc64be(13 << 3, tmp, 13);
            IO.Enc64be((ulong)len << 3, tmp, 21);

            /*
             * Compute clear authentication tag.
             */
            for (int i = 0; i < 16; i++)
            {
                tag[i] = 0;
            }
            GHASH.Run(tag, h, tmp, 0, 13);
            GHASH.Run(tag, h, data, off, len);
            GHASH.Run(tag, h, tmp, 13, 16);

            /*
             * Copy authentication tag and apply final encryption on it.
             */
            Array.Copy(tag, 0, data, off + len, 16);
            bc.CTRRun(iv, 1, data, off + len, 16);

            /*
             * Each record uses one sequence number.
             */
            seq++;

            /*
             * Write encrypted header and return adjusted offset/length.
             */
            off -= 13;
            len += 24;
            IO.WriteHeader(recordType, version, len, data, off);
            len += 5;
        }