Skip to content

Commit

Permalink
OpenSSL providers support
Browse files Browse the repository at this point in the history
  • Loading branch information
krwq committed Jul 16, 2024
1 parent 25a5085 commit 8134c62
Show file tree
Hide file tree
Showing 36 changed files with 1,442 additions and 813 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,21 @@ internal static partial class Crypto
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPkeyGetEcKey")]
internal static partial SafeEcKeyHandle EvpPkeyGetEcKey(SafeEvpPKeyHandle pkey);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPkeySetEcKey")]
[LibraryImport(Libraries.CryptoNative)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool EvpPkeySetEcKey(SafeEvpPKeyHandle pkey, SafeEcKeyHandle key);
private static partial bool CryptoNative_EvpPkeySetEcKey(SafeEvpPKeyHandle pkey, SafeEcKeyHandle key);

// Calls EVP_PKEY_set1_EC_KEY therefore the key will be duplicated
internal static SafeEvpPKeyHandle CreateEvpPkeyFromEcKey(SafeEcKeyHandle key)
{
SafeEvpPKeyHandle pkey = Interop.Crypto.EvpPkeyCreate();
if (!CryptoNative_EvpPkeySetEcKey(pkey, key))
{
pkey.Dispose();
throw Interop.Crypto.CreateOpenSslCryptographicException();
}

return pkey;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,100 @@ internal static partial class Interop
{
internal static partial class Crypto
{
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPKeyCtxCreateFromPKey")]
private static partial SafeEvpPKeyCtxHandle EvpPKeyCtxCreate(SafeEvpPKeyHandle pkey, IntPtr extraHandle);

internal static SafeEvpPKeyCtxHandle EvpPKeyCtxCreate(SafeEvpPKeyHandle pkey)
=> EvpPKeyCtxCreate(pkey, pkey.ExtraHandle);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPKeyCtxCreate")]
internal static partial SafeEvpPKeyCtxHandle EvpPKeyCtxCreate(SafeEvpPKeyHandle pkey, SafeEvpPKeyHandle peerkey, out uint secretLength);
private static partial SafeEvpPKeyCtxHandle EvpPKeyCtxCreate(SafeEvpPKeyHandle pkey, IntPtr extraHandle, SafeEvpPKeyHandle peerkey, out uint secretLength);

internal static SafeEvpPKeyCtxHandle EvpPKeyCtxCreate(SafeEvpPKeyHandle pkey, SafeEvpPKeyHandle peerkey, out uint secretLength)
=> EvpPKeyCtxCreate(pkey, pkey.ExtraHandle, peerkey, out secretLength);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPKeyCtxConfigureForECDSASign")]
private static partial int EvpPKeyCtxConfigureForECDSASignCore(SafeEvpPKeyCtxHandle ctx);

internal static void EvpPKeyCtxConfigureForECDSASign(SafeEvpPKeyCtxHandle ctx)
{
Debug.Assert(ctx != null);
Debug.Assert(!ctx.IsInvalid);

if (EvpPKeyCtxConfigureForECDSASignCore(ctx) != 1)
{
throw CreateOpenSslCryptographicException();
}
}

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPKeyCtxConfigureForECDSAVerify")]
private static partial int EvpPKeyCtxConfigureForECDSAVerifyCore(SafeEvpPKeyCtxHandle ctx);

internal static void EvpPKeyCtxConfigureForECDSAVerify(SafeEvpPKeyCtxHandle ctx)
{
Debug.Assert(ctx != null);
Debug.Assert(!ctx.IsInvalid);

if (EvpPKeyCtxConfigureForECDSAVerifyCore(ctx) != 1)
{
throw CreateOpenSslCryptographicException();
}
}

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPKeyCtxSignHash")]
private static unsafe partial int EvpPKeyCtxSignHash(SafeEvpPKeyCtxHandle ctx, byte* hash, int hashLen, byte* destination, ref int destinationLen);

internal static unsafe bool TryEvpPKeyCtxSignHash(SafeEvpPKeyCtxHandle ctx, ReadOnlySpan<byte> hash, Span<byte> destination, out int bytesWritten)
{
Debug.Assert(ctx != null);
Debug.Assert(!ctx.IsInvalid);

if (hash.Length == 0 || destination.Length == 0)
{
bytesWritten = 0;
return false;
}

bytesWritten = destination.Length;
ref byte hashRef = ref MemoryMarshal.GetReference(hash);
ref byte destRef = ref MemoryMarshal.GetReference(destination);
fixed (byte* hashPtr = &hashRef)
fixed (byte* destPtr = &destRef)
{
return EvpPKeyCtxSignHash(ctx, hashPtr, hash.Length, destPtr, ref bytesWritten) == 1;
}
}

internal static unsafe bool TryEvpPKeyCtxSignatureSize(SafeEvpPKeyCtxHandle ctx, ReadOnlySpan<byte> hash, out int bytesWritten)
{
Debug.Assert(ctx != null);
Debug.Assert(!ctx.IsInvalid);

bytesWritten = 0;

if (hash.Length == 0)
{
return false;
}

ref byte hashRef = ref MemoryMarshal.GetReference(hash);
fixed (byte* hashPtr = &hashRef)
{
byte* destPtr = null;
return EvpPKeyCtxSignHash(ctx, hashPtr, hash.Length, destPtr, ref bytesWritten) == 1;
}
}

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPKeyCtxVerifyHash")]
private static partial int EvpPKeyCtxVerifyHash(SafeEvpPKeyCtxHandle ctx, ref byte hash, int hashLen, ref byte signature, int signatureLen);

internal static bool EvpPKeyCtxVerifyHash(SafeEvpPKeyCtxHandle ctx, ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature)
{
Debug.Assert(ctx != null);
Debug.Assert(!ctx.IsInvalid);

return EvpPKeyCtxVerifyHash(ctx, ref MemoryMarshal.GetReference(hash), hash.Length, ref MemoryMarshal.GetReference(signature), signature.Length) == 1;
}

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPKeyDeriveSecretAgreement")]
private static partial int EvpPKeyDeriveSecretAgreement(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ internal static SafeEvpPKeyHandle RsaGenerateKey(int keySize)
[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_RsaDecrypt(
SafeEvpPKeyHandle pkey,
IntPtr extraHandle,
ref byte source,
int sourceLength,
RSAEncryptionPaddingMode paddingMode,
Expand All @@ -64,6 +65,7 @@ internal static int RsaDecrypt(
{
int written = CryptoNative_RsaDecrypt(
pkey,
pkey.ExtraHandle,
ref MemoryMarshal.GetReference(source),
source.Length,
paddingMode,
Expand All @@ -83,6 +85,7 @@ ref MemoryMarshal.GetReference(destination),
[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_RsaEncrypt(
SafeEvpPKeyHandle pkey,
IntPtr extraHandle,
ref byte source,
int sourceLength,
RSAEncryptionPaddingMode paddingMode,
Expand All @@ -99,6 +102,7 @@ internal static int RsaEncrypt(
{
int written = CryptoNative_RsaEncrypt(
pkey,
pkey.ExtraHandle,
ref MemoryMarshal.GetReference(source),
source.Length,
paddingMode,
Expand All @@ -116,78 +120,53 @@ ref MemoryMarshal.GetReference(destination),
}

[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_RsaSignHash(
SafeEvpPKeyHandle pkey,
private static partial int CryptoNative_EvpPKeyCtxConfigureForRsaSign(
SafeEvpPKeyCtxHandle ctx,
RSASignaturePaddingMode paddingMode,
IntPtr digestAlgorithm,
ref byte hash,
int hashLength,
ref byte destination,
int destinationLength);
IntPtr digestAlgorithm);

internal static int RsaSignHash(
SafeEvpPKeyHandle pkey,
internal static void CryptoNative_ConfigureForRsaSign(
SafeEvpPKeyCtxHandle ctx,
RSASignaturePaddingMode paddingMode,
IntPtr digestAlgorithm,
ReadOnlySpan<byte> hash,
Span<byte> destination)
HashAlgorithmName digestAlgorithm)
{
int written = CryptoNative_RsaSignHash(
pkey,
paddingMode,
digestAlgorithm,
ref MemoryMarshal.GetReference(hash),
hash.Length,
ref MemoryMarshal.GetReference(destination),
destination.Length);
if (digestAlgorithm.Name == null)
{
throw new ArgumentNullException(nameof(digestAlgorithm));
}

if (written < 0)
IntPtr digestAlgorithmPtr = Interop.Crypto.HashAlgorithmToEvp(digestAlgorithm.Name);
int ret = CryptoNative_EvpPKeyCtxConfigureForRsaSign(ctx, paddingMode, digestAlgorithmPtr);

if (ret != 1)
{
Debug.Assert(written == -1);
throw CreateOpenSslCryptographicException();
}

return written;
}

[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_RsaVerifyHash(
SafeEvpPKeyHandle pkey,
private static partial int CryptoNative_EvpPKeyCtxConfigureForRsaVerify(
SafeEvpPKeyCtxHandle ctx,
RSASignaturePaddingMode paddingMode,
IntPtr digestAlgorithm,
ref byte hash,
int hashLength,
ref byte signature,
int signatureLength);
IntPtr digestAlgorithm);

internal static bool RsaVerifyHash(
SafeEvpPKeyHandle pkey,
internal static void CryptoNative_ConfigureForRsaVerify(
SafeEvpPKeyCtxHandle ctx,
RSASignaturePaddingMode paddingMode,
IntPtr digestAlgorithm,
ReadOnlySpan<byte> hash,
ReadOnlySpan<byte> signature)
HashAlgorithmName digestAlgorithm)
{
int ret = CryptoNative_RsaVerifyHash(
pkey,
paddingMode,
digestAlgorithm,
ref MemoryMarshal.GetReference(hash),
hash.Length,
ref MemoryMarshal.GetReference(signature),
signature.Length);

if (ret == 1)
if (digestAlgorithm.Name == null)
{
return true;
throw new ArgumentNullException(nameof(digestAlgorithm));
}

if (ret == 0)
IntPtr digestAlgorithmPtr = Interop.Crypto.HashAlgorithmToEvp(digestAlgorithm.Name);
int ret = CryptoNative_EvpPKeyCtxConfigureForRsaVerify(ctx, paddingMode, digestAlgorithmPtr);

if (ret != 1)
{
return false;
throw CreateOpenSslCryptographicException();
}

Debug.Assert(ret == -1);
throw CreateOpenSslCryptographicException();
}
}
}
Loading

0 comments on commit 8134c62

Please sign in to comment.