Example #1
0
        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);
                }
            }
        }
Example #2
0
        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);
                }
            }
        }
Example #3
0
        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();
        }
Example #6
0
        /// <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);
Example #7
0
        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;
        }
Example #8
0
        /// <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);
            }
        }
Example #9
0
        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()));
        }
Example #10
0
 public static void ComputeHash(this Sha2 sha2, ReadOnlySpan <byte> source, Span <byte> destination)
 {
     sha2.ComputeHash(source, default, destination, default);