예제 #1
0
        public override ReadOnlyMemory <byte> PseudoRandomFunction(ReadOnlyMemory <byte> key, ReadOnlyMemory <byte> input)
        {
            // aes-ecb(trunc128(sha-1(input)))

            using (var sha1 = CryptoPal.Platform.Sha1())
            {
                var checksum = sha1.ComputeHash(input.Span).Slice(0, AesBlockSize);

                var kp = this.DK(key, PrfConstant, this.KeySize, this.BlockSize);

                return(AESCTS.Encrypt(checksum, kp, AllZerosInitVector));
            }
        }
예제 #2
0
        public override ReadOnlyMemory <byte> Encrypt(ReadOnlyMemory <byte> data, KerberosKey kerberosKey, KeyUsage usage)
        {
            var ke = this.GetOrDeriveKey(kerberosKey, usage, KeyDerivationMode.Ke);

            ReadOnlyMemory <byte> confounder;

            if (this.Confounder.Length > 0)
            {
                confounder = this.Confounder;
            }
            else
            {
                confounder = this.GenerateRandomBytes(this.ConfounderSize);
            }

            var concatLength = confounder.Length + data.Length;

            using (var cleartextPool = CryptoPool.Rent <byte>(concatLength))
            {
                var cleartext = cleartextPool.Memory.Slice(0, concatLength);

                Concat(confounder.Span, data.Span, cleartext);

                var encrypted = AESCTS.Encrypt(
                    cleartext,
                    ke,
                    AllZerosInitVector
                    );

                var checksumDataLength = AllZerosInitVector.Length + encrypted.Length;

                using (var checksumDataRented = CryptoPool.Rent <byte>(checksumDataLength))
                {
                    var checksumData = checksumDataRented.Memory.Slice(0, checksumDataLength);

                    Concat(AllZerosInitVector.Span, encrypted.Span, checksumData);

                    var checksum = this.MakeChecksum(checksumData, kerberosKey, usage, KeyDerivationMode.Ki, this.ChecksumSize);

                    return(Concat(encrypted.Span, checksum.Span));
                }
            }
        }
예제 #3
0
        public override ReadOnlyMemory <byte> Decrypt(ReadOnlyMemory <byte> cipher, KerberosKey kerberosKey, KeyUsage usage)
        {
            var cipherLength = cipher.Length - this.ChecksumSize;

            var ke = this.GetOrDeriveKey(kerberosKey, usage, KeyDerivationMode.Ke);

            var decrypted = AESCTS.Decrypt(
                cipher.Slice(0, cipherLength),
                ke,
                AllZerosInitVector
                );

            var actualChecksum = this.MakeChecksum(decrypted, kerberosKey, usage, KeyDerivationMode.Ki, this.ChecksumSize);

            var expectedChecksum = cipher.Slice(cipherLength, this.ChecksumSize);

            if (!AreEqualSlow(expectedChecksum.Span, actualChecksum.Span))
            {
                throw new SecurityException("Invalid checksum");
            }

            return(decrypted.Slice(this.ConfounderSize, cipherLength - this.ConfounderSize));
        }
예제 #4
0
        public void Encrypt(byte[] key, byte[] iv, byte[] tmpEnc)
        {
            var output = AESCTS.Encrypt(tmpEnc, key, iv);

            Buffer.BlockCopy(output, 0, tmpEnc, 0, output.Length);
        }