예제 #1
0
        public override ReadOnlySpan <byte> Decrypt(ReadOnlyMemory <byte> cipher, KerberosKey kerberosKey, KeyUsage usage)
        {
            var cipherLength = cipher.Length - ChecksumSize;

            var Ke = kerberosKey.GetOrDeriveKey(
                this,
                $"{usage}|Ke|{KeySize}|{BlockSize}",
                key => DK(key.Span, usage, KeyDerivationMode.Ke, KeySize, BlockSize).AsMemory()
                );

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

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

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

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

            return(decrypted.Slice(ConfounderSize, cipherLength - ConfounderSize));
        }
예제 #2
0
        public override ReadOnlyMemory <byte> Encrypt(ReadOnlyMemory <byte> data, KerberosKey kerberosKey, KeyUsage usage)
        {
            var Ke = kerberosKey.GetOrDeriveKey(
                this,
                $"{usage}|Ke|{KeySize}|{BlockSize}",
                key => DK(key.Span, usage, KeyDerivationMode.Ke, KeySize, BlockSize)
                );

            var confounder = GenerateRandomBytes(ConfounderSize);

            var concatLength = confounder.Length + data.Length;

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

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

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

                return(Concat(encrypted.Span, checksum.Span));
            }
        }
예제 #3
0
 private ReadOnlyMemory <byte> GetOrDeriveKey(KerberosKey kerberosKey, KeyUsage usage)
 {
     return(kerberosKey.GetOrDeriveKey(
                this,
                $"{usage}|Ke|{KeySize}|{BlockSize}",
                key => DK(key, usage, KeyDerivationMode.Ke, KeySize, BlockSize)
                ));
 }
예제 #4
0
        private ReadOnlyMemory <byte> GetOrDeriveKey(KerberosKey kerberosKey, KeyUsage usage)
        {
            if (kerberosKey == null)
            {
                throw new InvalidOperationException("Key cannot be null");
            }

            return(kerberosKey.GetOrDeriveKey(
                       this,
                       $"{usage}|Ke|{KeySize}|{BlockSize}",
                       key => DK(key, usage, KeyDerivationMode.Ke, KeySize, BlockSize)
                       ));
        }
예제 #5
0
        public override ReadOnlyMemory <byte> MakeChecksum(
            ReadOnlyMemory <byte> data,
            KerberosKey key,
            KeyUsage usage,
            KeyDerivationMode kdf,
            int hashSize
            )
        {
            var ki = key.GetOrDeriveKey(
                this,
                $"{usage}|{kdf}|{KeySize}|{BlockSize}",
                k => DK(k, usage, kdf, KeySize, BlockSize)
                );

            return(Hmac(ki, data).Slice(0, hashSize));
        }
예제 #6
0
        public override ReadOnlyMemory <byte> MakeChecksum(
            ReadOnlyMemory <byte> data,
            KerberosKey key,
            KeyUsage usage,
            KeyDerivationMode kdf,
            int hashSize
            )
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var ki = key.GetOrDeriveKey(
                this,
                $"{usage}|{kdf}|{this.KeySize}|{this.BlockSize}",
                k => DK(k, usage, kdf, this.KeySize, this.BlockSize)
                );

            return(Hmac(ki, data).Slice(0, hashSize));
        }
예제 #7
0
        public override ReadOnlyMemory <byte> Encrypt(ReadOnlyMemory <byte> data, KerberosKey kerberosKey, KeyUsage usage)
        {
            var Ke = kerberosKey.GetOrDeriveKey(
                this,
                $"{usage}|Ke|{KeySize}|{BlockSize}",
                key => DK(key.Span, usage, KeyDerivationMode.Ke, KeySize, BlockSize).AsMemory()
                );

            var confounder = GenerateRandomBytes(ConfounderSize);

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

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

            var checksum = MakeChecksum(cleartext.Span, kerberosKey, usage, KeyDerivationMode.Ki, ChecksumSize);

            return(Concat(encrypted, checksum));
        }