private void ComputeAuthenticationTag(ReadOnlySpan <byte> key, ReadOnlySpan <byte> iv, ReadOnlySpan <byte> associatedData, ReadOnlySpan <byte> ciphertext, Span <byte> authenticationTag, out int authenticationTagBytesWritten) { byte[]? arrayToReturnToPool = null; try { int macLength = associatedData.Length + iv.Length + ciphertext.Length + sizeof(long); Span <byte> macBytes = macLength <= Constants.MaxStackallocBytes ? stackalloc byte[macLength] : (arrayToReturnToPool = ArrayPool <byte> .Shared.Rent(macLength)).AsSpan(0, macLength); associatedData.CopyTo(macBytes); var bytes = macBytes.Slice(associatedData.Length); iv.CopyTo(bytes); bytes = bytes.Slice(iv.Length); ciphertext.CopyTo(bytes); bytes = bytes.Slice(ciphertext.Length); BinaryPrimitives.WriteInt64BigEndian(bytes, associatedData.Length << 3); Sha2 hashAlgorithm = _encryptionAlgorithm.SignatureAlgorithm.Sha; Span <byte> hmacKey = stackalloc byte[hashAlgorithm.BlockSize * 2]; Hmac hmac = new Hmac(hashAlgorithm, key, hmacKey); hmac.ComputeHash(macBytes, authenticationTag); authenticationTagBytesWritten = authenticationTag.Length >> 1; } finally { if (arrayToReturnToPool != null) { ArrayPool <byte> .Shared.Return(arrayToReturnToPool); } } }
private bool VerifyAuthenticationTag(ReadOnlySpan <byte> key, ReadOnlySpan <byte> iv, ReadOnlySpan <byte> associatedData, ReadOnlySpan <byte> ciphertext, ReadOnlySpan <byte> authenticationTag) { byte[]? byteArrayToReturnToPool = null; int macLength = associatedData.Length + iv.Length + ciphertext.Length + sizeof(long); Span <byte> macBytes = macLength <= Constants.MaxStackallocBytes ? stackalloc byte[macLength] : (byteArrayToReturnToPool = ArrayPool <byte> .Shared.Rent(macLength)).AsSpan(0, macLength); try { associatedData.CopyTo(macBytes); var bytes = macBytes.Slice(associatedData.Length); iv.CopyTo(bytes); bytes = bytes.Slice(iv.Length); ciphertext.CopyTo(bytes); bytes = bytes.Slice(ciphertext.Length); BinaryPrimitives.WriteInt64BigEndian(bytes, associatedData.Length << 3); Sha2 hashAlgorithm = _encryptionAlgorithm.SignatureAlgorithm.Sha; Span <byte> hmacKey = stackalloc byte[hashAlgorithm.BlockSize * 2]; Hmac hmac = new Hmac(hashAlgorithm, key, hmacKey); Span <byte> hash = stackalloc byte[authenticationTag.Length * 2]; hmac.ComputeHash(macBytes, hash); CryptographicOperations.ZeroMemory(hmacKey); return(CryptographicOperations.FixedTimeEquals(authenticationTag, hash.Slice(0, authenticationTag.Length))); } finally { if (byteArrayToReturnToPool != null) { ArrayPool <byte> .Shared.Return(byteArrayToReturnToPool); } } }
public static void DeriveKey(byte[] password, ReadOnlySpan <byte> salt, Sha2 prf, uint iterationCount, Span <byte> destination) { Debug.Assert(password != null); Debug.Assert(salt != null); Debug.Assert(destination.Length > 0); int numBytesWritten = 0; int numBytesRemaining = destination.Length; Span <byte> saltWithBlockIndex = stackalloc byte[checked (salt.Length + sizeof(uint))]; salt.CopyTo(saltWithBlockIndex); Span <byte> hmacKey = stackalloc byte[prf.BlockSize * 2]; var hashAlgorithm = new Hmac(prf, password, hmacKey); int wSize = prf.GetWorkingSetSize(int.MaxValue); int blockSize = hashAlgorithm.BlockSize; byte[]? arrayToReturn = null; try { Span <byte> W = wSize > Constants.MaxStackallocBytes ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(wSize)) : stackalloc byte[wSize]; Span <byte> currentBlock = stackalloc byte[hashAlgorithm.HashSize]; Span <byte> iterationBlock = stackalloc byte[hashAlgorithm.HashSize]; Span <byte> blockIndexDestination = saltWithBlockIndex.Slice(saltWithBlockIndex.Length - sizeof(uint)); for (uint blockIndex = 1; numBytesRemaining > 0; blockIndex++) { BinaryPrimitives.WriteUInt32BigEndian(blockIndexDestination, blockIndex); hashAlgorithm.ComputeHash(saltWithBlockIndex, currentBlock, W); // U_1 currentBlock.CopyTo(iterationBlock); for (int iter = 1; iter < iterationCount; iter++) { hashAlgorithm.ComputeHash(currentBlock, currentBlock, W); Xor(src: currentBlock, dest: iterationBlock); } int numBytesToCopy = Math.Min(numBytesRemaining, iterationBlock.Length); iterationBlock.Slice(0, numBytesToCopy).CopyTo(destination.Slice(numBytesWritten)); numBytesWritten += numBytesToCopy; numBytesRemaining -= numBytesToCopy; } } finally { if (arrayToReturn != null) { ArrayPool <byte> .Shared.Return(arrayToReturn); } } }
public EcdsaSignatureVerifier(ECJwk key, SignatureAlgorithm algorithm) : base(algorithm) { Debug.Assert(key != null); Debug.Assert(key.KeySizeInBits == algorithm.RequiredKeySizeInBits); _sha = algorithm.Sha; _hashSize = key.Crv.HashSize; _base64HashSize = Base64Url.GetArraySizeRequiredToEncode(_hashSize); _ecdsaPool = new ObjectPool <ECDsa>(new ECDsaObjectPoolPolicy(key, algorithm)); }
internal Pbes2KeyUnwrapper(PasswordBasedJwk key, EncryptionAlgorithm encryptionAlgorithm, KeyManagementAlgorithm algorithm) : base(encryptionAlgorithm, algorithm) { Debug.Assert(key.SupportKeyManagement(algorithm)); Debug.Assert(algorithm.Category == AlgorithmCategory.Pbkdf2); Debug.Assert(algorithm.WrappedAlgorithm != null); Debug.Assert(algorithm.HashAlgorithm != null); _algorithm = algorithm.Name; _keySizeInBytes = algorithm.WrappedAlgorithm.RequiredKeySizeInBits >> 3; _algorithmNameLength = _algorithm.EncodedUtf8Bytes.Length; _hashAlgorithm = algorithm.HashAlgorithm; _keyManagementAlgorithm = algorithm.WrappedAlgorithm; _password = key.ToArray(); }
/// <summary> /// Initializes a new instance of the <see cref="HmacSha2"/> class. /// </summary> /// <param name="sha2"></param> /// <param name="key"></param> public HmacSha2(Sha2 sha2, ReadOnlySpan <byte> key) { Debug.Assert(sha2 != null); Sha2 = sha2; int blockSize = sha2.BlockSize; _keys = ArrayPool <byte> .Shared.Rent(blockSize * 2); _innerPadKey = new ReadOnlyMemory <byte>(_keys, 0, blockSize); _outerPadKey = new ReadOnlyMemory <byte>(_keys, blockSize, blockSize); if (key.Length > blockSize) { Span <byte> keyPrime = stackalloc byte[sha2.HashSize]; Sha2.ComputeHash(key, default, keyPrime, default);
public Pbes2KeyWrapper(PasswordBasedJwk key, EncryptionAlgorithm encryptionAlgorithm, KeyManagementAlgorithm algorithm, uint iterationCount, uint saltSizeInBytes, ISaltGenerator saltGenerator) : base(encryptionAlgorithm, algorithm) { Debug.Assert(key.SupportKeyManagement(algorithm)); Debug.Assert(algorithm.Category == AlgorithmCategory.Pbkdf2); Debug.Assert(algorithm.WrappedAlgorithm != null); Debug.Assert(algorithm.HashAlgorithm != null); _algorithm = algorithm.Name; _keySizeInBytes = algorithm.WrappedAlgorithm.RequiredKeySizeInBits >> 3; _algorithmNameLength = _algorithm.EncodedUtf8Bytes.Length; _hashAlgorithm = algorithm.HashAlgorithm; _keyManagementAlgorithm = algorithm.WrappedAlgorithm; _password = key.ToArray(); _iterationCount = iterationCount; _saltSizeInBytes = (int)saltSizeInBytes; _saltGenerator = saltGenerator; }
/// <summary>Initializes a new instance of the <see cref="HmacSha2"/> class.</summary> public Hmac(Sha2 sha2, ReadOnlySpan<byte> key, Span<byte> hmacKey) { Debug.Assert(sha2 != null); Debug.Assert(hmacKey.Length >= sha2.BlockSize * 2); Sha2 = sha2; _keys = hmacKey; int blockSize = sha2.BlockSize; if (key.Length > blockSize) { Span<byte> keyPrime = stackalloc byte[Sha2.BlockSizeStackallocThreshold * 2].Slice(0, blockSize); HmacHelper.InitializeIOKeys(keyPrime, _keys, blockSize); keyPrime.Clear(); } else { HmacHelper.InitializeIOKeys(key, _keys, blockSize); } }
public RsaSignatureVerifier(RsaJwk key, SignatureAlgorithm algorithm) : base(algorithm) { Debug.Assert(key != null); Debug.Assert(key.SupportSignature(algorithm)); if (key.KeySizeInBits < 1024) { ThrowHelper.ThrowArgumentOutOfRangeException_SigningKeyTooSmall(key, 1024); } _hashAlgorithm = algorithm.HashAlgorithm; _sha = algorithm.Sha; _signaturePadding = RsaHelper.GetPadding(algorithm); _hashSizeInBytes = key.KeySizeInBits >> 3; _base64HashSizeInBytes = Base64Url.GetArraySizeRequiredToEncode(_hashSizeInBytes); _rsaPool = new ObjectPool <RSA>(new RsaObjectPoolPolicy(key.ExportParameters())); }
public static void ComputeHash(this Sha2 sha2, ReadOnlySpan <byte> source, Span <byte> destination) { sha2.ComputeHash(source, default, destination, default);