Exemple #1
0
        internal LiteHmac(PAL_HashAlgorithm algorithm, ReadOnlySpan <byte> key, bool preinitialize)
        {
            int hashSizeInBytes = 0;

            _ctx = Interop.AppleCrypto.HmacCreate(algorithm, ref hashSizeInBytes);

            if (hashSizeInBytes < 0)
            {
                _ctx.Dispose();
                throw new PlatformNotSupportedException(
                          SR.Format(
                              SR.Cryptography_UnknownHashAlgorithm,
                              Enum.GetName(typeof(Interop.AppleCrypto.PAL_HashAlgorithm), algorithm)));
            }

            if (_ctx.IsInvalid)
            {
                _ctx.Dispose();
                throw new CryptographicException();
            }

            if (preinitialize)
            {
                if (Interop.AppleCrypto.HmacInit(_ctx, key) != Success)
                {
                    _ctx.Dispose();
                    throw new CryptographicException();
                }
            }

            _hashSizeInBytes = hashSizeInBytes;
        }
            public AppleHmacProvider(string hashAlgorithmId, ReadOnlySpan <byte> key)
            {
                PAL_HashAlgorithm algorithm = HashAlgorithmNames.HashAlgorithmToPal(hashAlgorithmId);

                _liteHmac = new LiteHmac(algorithm, key, preinitialize: false);
                _key      = key.ToArray();
            }
            public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                if (hash == null)
                {
                    throw new ArgumentNullException(nameof(hash));
                }
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }

                if (padding == RSASignaturePadding.Pkcs1)
                {
                    SecKeyPair keys = GetKeys();

                    if (keys.PrivateKey == null)
                    {
                        throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                    }

                    int expectedSize;
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out expectedSize);

                    if (hash.Length != expectedSize)
                    {
                        // Windows: NTE_BAD_DATA ("Bad Data.")
                        // OpenSSL: RSA_R_INVALID_MESSAGE_LENGTH ("invalid message length")
                        throw new CryptographicException(
                                  SR.Format(
                                      SR.Cryptography_BadHashSize_ForAlgorithm,
                                      hash.Length,
                                      expectedSize,
                                      hashAlgorithm.Name));
                    }

                    return(Interop.AppleCrypto.GenerateSignature(
                               keys.PrivateKey,
                               hash,
                               palAlgId));
                }

                // A signature will always be the keysize (in ceiling-bytes) in length.
                int outputSize = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);

                byte[] output = new byte[outputSize];

                if (!TrySignHash(hash, output, hashAlgorithm, padding, out int bytesWritten))
                {
                    Debug.Fail("TrySignHash failed with a pre-allocated buffer");
                    throw new CryptographicException();
                }

                Debug.Assert(bytesWritten == outputSize);
                return(output);
            }
            public static unsafe int HashData(string hashAlgorithmId, ReadOnlySpan <byte> source, Span <byte> destination)
            {
                Interop.AppleCrypto.PAL_HashAlgorithm algorithm = HashAlgorithmToPal(hashAlgorithmId);

                fixed(byte *pSource = source)
                fixed(byte *pDestination = destination)
                {
                    int ret = Interop.AppleCrypto.DigestOneShot(
                        algorithm,
                        pSource,
                        source.Length,
                        pDestination,
                        destination.Length,
                        out int digestSize);

                    if (ret != 1)
                    {
                        Debug.Fail($"HashData return value {ret} was not 1");
                        throw new CryptographicException();
                    }

                    Debug.Assert(digestSize <= destination.Length);

                    return(digestSize);
                }
            }
Exemple #5
0
            public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                if (hash == null)
                {
                    throw new ArgumentNullException(nameof(hash));
                }
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }
                if (padding != RSASignaturePadding.Pkcs1)
                {
                    throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
                }

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                int expectedSize;

                Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                    PalAlgorithmFromAlgorithmName(hashAlgorithm, out expectedSize);

                if (hash.Length != expectedSize)
                {
                    // Windows: NTE_BAD_DATA ("Bad Data.")
                    // OpenSSL: RSA_R_INVALID_MESSAGE_LENGTH ("invalid message length")
                    throw new CryptographicException(
                              SR.Format(
                                  SR.Cryptography_BadHashSize_ForAlgorithm,
                                  hash.Length,
                                  expectedSize,
                                  hashAlgorithm.Name));
                }

                return(Interop.AppleCrypto.GenerateSignature(
                           keys.PrivateKey,
                           hash,
                           palAlgId));
            }
Exemple #6
0
            public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }
                if (padding != RSASignaturePadding.Pkcs1)
                {
                    throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
                }

                Interop.AppleCrypto.PAL_HashAlgorithm palAlgId = PalAlgorithmFromAlgorithmName(hashAlgorithm, out int expectedSize);
                return(Interop.AppleCrypto.VerifySignature(GetKeys().PublicKey, hash, signature, palAlgId));
            }
Exemple #7
0
            public override bool VerifyHash(
                byte[] hash,
                byte[] signature,
                HashAlgorithmName hashAlgorithm,
                RSASignaturePadding padding)
            {
                if (padding != RSASignaturePadding.Pkcs1)
                {
                    throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
                }

                int expectedSize;

                Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                    PalAlgorithmFromAlgorithmName(hashAlgorithm, out expectedSize);

                return(Interop.AppleCrypto.VerifySignature(
                           GetKeys().PublicKey,
                           hash,
                           signature,
                           palAlgId));
            }
Exemple #8
0
            internal AppleDigestProvider(Interop.AppleCrypto.PAL_HashAlgorithm algorithm)
            {
                int hashSizeInBytes;

                _ctx = Interop.AppleCrypto.DigestCreate(algorithm, out hashSizeInBytes);

                if (hashSizeInBytes < 0)
                {
                    _ctx.Dispose();
                    throw new PlatformNotSupportedException(
                              SR.Format(
                                  SR.Cryptography_UnknownHashAlgorithm,
                                  Enum.GetName(typeof(Interop.AppleCrypto.PAL_HashAlgorithm), algorithm)));
                }

                if (_ctx.IsInvalid)
                {
                    _ctx.Dispose();
                    throw new CryptographicException();
                }

                HashSizeInBytes = hashSizeInBytes;
            }
Exemple #9
0
            internal AppleHmacProvider(Interop.AppleCrypto.PAL_HashAlgorithm algorithm, byte[] key)
            {
                _key = key.CloneByteArray();
                int hashSizeInBytes = 0;

                _ctx = Interop.AppleCrypto.HmacCreate(algorithm, ref hashSizeInBytes);

                if (hashSizeInBytes < 0)
                {
                    _ctx.Dispose();
                    throw new PlatformNotSupportedException(
                              SR.Format(
                                  SR.Cryptography_UnknownHashAlgorithm,
                                  Enum.GetName(typeof(Interop.AppleCrypto.PAL_HashAlgorithm), algorithm)));
                }

                if (_ctx.IsInvalid)
                {
                    _ctx.Dispose();
                    throw new CryptographicException();
                }

                HashSizeInBytes = hashSizeInBytes;
            }
            public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm));
                ArgumentNullException.ThrowIfNull(padding);

                ThrowIfDisposed();

                if (padding == RSASignaturePadding.Pkcs1)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out _);
                    return(Interop.AppleCrypto.VerifySignature(
                               GetKeys().PublicKey,
                               hash,
                               signature,
                               palAlgId,
                               Interop.AppleCrypto.PAL_SignatureAlgorithm.RsaPkcs1));
                }
                else if (padding.Mode == RSASignaturePaddingMode.Pss)
                {
                    SafeSecKeyRefHandle publicKey = GetKeys().PublicKey;

                    int keySize = KeySize;
                    int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                    if (signature.Length != rsaSize)
                    {
                        return(false);
                    }

                    if (hash.Length != RsaPaddingProcessor.HashLength(hashAlgorithm))
                    {
                        return(false);
                    }

                    byte[]      rented    = CryptoPool.Rent(rsaSize);
                    Span <byte> unwrapped = new Span <byte>(rented, 0, rsaSize);

                    try
                    {
                        if (!Interop.AppleCrypto.TryRsaVerificationPrimitive(
                                publicKey,
                                signature,
                                unwrapped,
                                out int bytesWritten))
                        {
                            Debug.Fail($"TryRsaVerificationPrimitive with a pre-allocated buffer");
                            throw new CryptographicException();
                        }

                        Debug.Assert(bytesWritten == rsaSize);
                        return(RsaPaddingProcessor.VerifyPss(hashAlgorithm, hash, unwrapped, keySize));
                    }
                    finally
                    {
                        CryptographicOperations.ZeroMemory(unwrapped);
                        CryptoPool.Return(rented, clearSize: 0);
                    }
                }

                throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
            }
            public override bool TrySignHash(ReadOnlySpan <byte> hash, Span <byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten)
            {
                ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm));
                ArgumentNullException.ThrowIfNull(padding);

                ThrowIfDisposed();

                bool pssPadding = padding.Mode switch
                {
                    RSASignaturePaddingMode.Pss => true,
                    RSASignaturePaddingMode.Pkcs1 => false,
                    _ => throw new CryptographicException(SR.Cryptography_InvalidPaddingMode)
                };

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                int keySize = KeySize;
                int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                if (!pssPadding)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out int expectedSize);

                    if (hash.Length != expectedSize)
                    {
                        // Windows: NTE_BAD_DATA ("Bad Data.")
                        // OpenSSL: RSA_R_INVALID_MESSAGE_LENGTH ("invalid message length")
                        throw new CryptographicException(
                                  SR.Format(
                                      SR.Cryptography_BadHashSize_ForAlgorithm,
                                      hash.Length,
                                      expectedSize,
                                      hashAlgorithm.Name));
                    }

                    if (destination.Length < rsaSize)
                    {
                        bytesWritten = 0;
                        return(false);
                    }

                    return(Interop.AppleCrypto.TryCreateSignature(
                               keys.PrivateKey,
                               hash,
                               destination,
                               palAlgId,
                               Interop.AppleCrypto.PAL_SignatureAlgorithm.RsaPkcs1,
                               out bytesWritten));
                }

                Debug.Assert(padding.Mode == RSASignaturePaddingMode.Pss);

                if (destination.Length < rsaSize)
                {
                    bytesWritten = 0;
                    return(false);
                }

                byte[]      rented = CryptoPool.Rent(rsaSize);
                Span <byte> buf    = new Span <byte>(rented, 0, rsaSize);

                RsaPaddingProcessor.EncodePss(hashAlgorithm, hash, buf, keySize);

                try
                {
                    return(Interop.AppleCrypto.TryRsaSignaturePrimitive(keys.PrivateKey, buf, destination, out bytesWritten));
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(buf);
                    CryptoPool.Return(rented, clearSize: 0);
                }
            }
 public static HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlySpan <byte> key)
 {
     Interop.AppleCrypto.PAL_HashAlgorithm algorithm = HashAlgorithmToPal(hashAlgorithmId);
     return(new AppleHmacProvider(algorithm, key));
 }
 public static HashProvider CreateHashProvider(string hashAlgorithmId)
 {
     Interop.AppleCrypto.PAL_HashAlgorithm algorithm = HashAlgorithmToPal(hashAlgorithmId);
     return(new AppleDigestProvider(algorithm));
 }
Exemple #14
0
        internal static LiteHmac CreateHmac(string hashAlgorithmId, ReadOnlySpan <byte> key)
        {
            PAL_HashAlgorithm algorithm = HashAlgorithmNames.HashAlgorithmToPal(hashAlgorithmId);

            return(new LiteHmac(algorithm, key, preinitialize: true));
        }
Exemple #15
0
        internal static LiteHash CreateHash(string hashAlgorithmId)
        {
            PAL_HashAlgorithm algorithm = HashAlgorithmNames.HashAlgorithmToPal(hashAlgorithmId);

            return(new LiteHash(algorithm));
        }
Exemple #16
0
            public override bool VerifyHash(ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }

                if (padding == RSASignaturePadding.Pkcs1)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out int expectedSize);
                    return(Interop.AppleCrypto.VerifySignature(GetKeys().PublicKey, hash, signature, palAlgId));
                }
                else if (padding.Mode == RSASignaturePaddingMode.Pss)
                {
                    RsaPaddingProcessor processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
                    SafeSecKeyRefHandle publicKey = GetKeys().PublicKey;

                    int keySize = KeySize;
                    int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                    if (signature.Length != rsaSize)
                    {
                        return(false);
                    }

                    if (hash.Length != processor.HashLength)
                    {
                        return(false);
                    }

                    byte[] rented = ArrayPool <byte> .Shared.Rent(rsaSize);

                    Span <byte> unwrapped = new Span <byte>(rented, 0, rsaSize);

                    try
                    {
                        if (!Interop.AppleCrypto.TryRsaVerificationPrimitive(
                                publicKey,
                                signature,
                                unwrapped,
                                out int bytesWritten))
                        {
                            Debug.Fail($"TryRsaVerificationPrimitive with a pre-allocated buffer");
                            throw new CryptographicException();
                        }

                        Debug.Assert(bytesWritten == rsaSize);
                        return(processor.VerifyPss(hash, unwrapped, keySize));
                    }
                    finally
                    {
                        unwrapped.Clear();
                        ArrayPool <byte> .Shared.Return(rented);
                    }
                }

                throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
            }
Exemple #17
0
            public override bool TrySignHash(ReadOnlySpan <byte> hash, Span <byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten)
            {
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }

                RsaPaddingProcessor processor = null;

                if (padding.Mode == RSASignaturePaddingMode.Pss)
                {
                    processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
                }
                else if (padding != RSASignaturePadding.Pkcs1)
                {
                    throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
                }

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                int keySize = KeySize;
                int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                if (processor == null)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out int expectedSize);

                    if (hash.Length != expectedSize)
                    {
                        // Windows: NTE_BAD_DATA ("Bad Data.")
                        // OpenSSL: RSA_R_INVALID_MESSAGE_LENGTH ("invalid message length")
                        throw new CryptographicException(
                                  SR.Format(
                                      SR.Cryptography_BadHashSize_ForAlgorithm,
                                      hash.Length,
                                      expectedSize,
                                      hashAlgorithm.Name));
                    }

                    if (destination.Length < rsaSize)
                    {
                        bytesWritten = 0;
                        return(false);
                    }

                    return(Interop.AppleCrypto.TryGenerateSignature(
                               keys.PrivateKey,
                               hash,
                               destination,
                               palAlgId,
                               out bytesWritten));
                }

                Debug.Assert(padding.Mode == RSASignaturePaddingMode.Pss);

                if (destination.Length < rsaSize)
                {
                    bytesWritten = 0;
                    return(false);
                }

                byte[] rented = ArrayPool <byte> .Shared.Rent(rsaSize);

                Span <byte> buf = new Span <byte>(rented, 0, rsaSize);

                processor.EncodePss(hash, buf, keySize);

                try
                {
                    return(Interop.AppleCrypto.TryRsaSignaturePrimitive(keys.PrivateKey, buf, destination, out bytesWritten));
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(buf);
                    ArrayPool <byte> .Shared.Return(rented);
                }
            }