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)); }
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)); } }
private ReadOnlyMemory <byte> GetOrDeriveKey(KerberosKey kerberosKey, KeyUsage usage) { return(kerberosKey.GetOrDeriveKey( this, $"{usage}|Ke|{KeySize}|{BlockSize}", key => DK(key, usage, KeyDerivationMode.Ke, KeySize, BlockSize) )); }
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) )); }
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)); }
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)); }
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)); }