Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/workflow/building/libraries/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ The libraries build contains some native code. This includes shims over libc, op

- Building and updating the binplace (for e.g. the testhost), which is needed when iterating on native components
```bash
dotnet.sh build src/native/libraries/build-native.proj
dotnet.sh build src/native/libs/build-native.proj
```

- The following example shows how you would do an arm cross-compile build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ internal static partial class Interop
{
internal static partial class Crypto
{
/// <summary>
/// Gets the extra handle associated with the EVP_PKEY. Some tests need to access
/// the interop layer and achieve this by adding the relevant classes to the test
/// project as links. However, accesses to internal members like <see cref="SafeEvpPKeyHandle.ExtraHandle"/>
/// in the product project will not work in the test project. In this particular case,
/// the test project does not need the value of the handle, so it can implement this
/// method to return a null pointer.
/// </summary>
/// <param name="handle">
/// The extra handle associated with the EVP_PKEY.</param>
/// <returns>
/// The extra handle associated with the EVP_PKEY.
/// </returns>
private static partial IntPtr GetExtraHandle(SafeEvpPKeyHandle handle);

// Must be kept in sync with PalKemId in native shim.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,42 +64,6 @@ internal static SafeEvpPKeyHandle MLDsaGenerateKey(string algorithmName, ReadOnl
return handle;
}

[LibraryImport(Libraries.CryptoNative, StringMarshalling = StringMarshalling.Utf8)]
private static partial SafeEvpPKeyHandle CryptoNative_MLDsaImportSecretKey(string keyType, ReadOnlySpan<byte> sk, int skLength);

internal static SafeEvpPKeyHandle MLDsaImportSecretKey(string algorithmName, ReadOnlySpan<byte> sk)
{
SafeEvpPKeyHandle? handle = CryptoNative_MLDsaImportSecretKey(algorithmName, sk, sk.Length);
Debug.Assert(handle != null, "handle != null");

if (handle.IsInvalid)
{
Exception ex = Interop.Crypto.CreateOpenSslCryptographicException();
handle.Dispose();
throw ex;
}

return handle;
}

[LibraryImport(Libraries.CryptoNative, StringMarshalling = StringMarshalling.Utf8)]
private static partial SafeEvpPKeyHandle CryptoNative_MLDsaImportPublicKey(string keyType, ReadOnlySpan<byte> pk, int pkLength);

internal static SafeEvpPKeyHandle MLDsaImportPublicKey(string algorithmName, ReadOnlySpan<byte> pk)
{
SafeEvpPKeyHandle handle = CryptoNative_MLDsaImportPublicKey(algorithmName, pk, pk.Length);
Debug.Assert(handle != null, "handle != null");

if (handle.IsInvalid)
{
Exception ex = Interop.Crypto.CreateOpenSslCryptographicException();
handle.Dispose();
throw ex;
}

return handle;
}

[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_MLDsaSignPure(
SafeEvpPKeyHandle pkey, IntPtr extraHandle,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal static partial class Crypto
{
[LibraryImport(Libraries.CryptoNative, StringMarshalling = StringMarshalling.Utf8)]
private static partial SafeEvpPKeyHandle CryptoNative_SlhDsaGenerateKey(string keyType);

internal static SafeEvpPKeyHandle SlhDsaGenerateKey(string algorithmName)
{
SafeEvpPKeyHandle handle = CryptoNative_SlhDsaGenerateKey(algorithmName);
Debug.Assert(handle != null, "handle != null");

if (handle.IsInvalid)
{
Exception ex = Interop.Crypto.CreateOpenSslCryptographicException();
handle.Dispose();
throw ex;
}

return handle;
}

// Must be kept in sync with PalSlhDsaId in native shim.
internal enum PalSlhDsaAlgorithmId
{
Unknown = 0,
SlhDsaSha2_128s = 1,
SlhDsaShake128s = 2,
SlhDsaSha2_128f = 3,
SlhDsaShake128f = 4,
SlhDsaSha2_192s = 5,
SlhDsaShake192s = 6,
SlhDsaSha2_192f = 7,
SlhDsaShake192f = 8,
SlhDsaSha2_256s = 9,
SlhDsaShake256s = 10,
SlhDsaSha2_256f = 11,
SlhDsaShake256f = 12,
}

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SlhDsaGetPalId")]
private static partial int CryptoNative_SlhDsaGetPalId(
SafeEvpPKeyHandle slhDsa,
out PalSlhDsaAlgorithmId slhDsaId);

internal static PalSlhDsaAlgorithmId GetSlhDsaAlgorithmId(SafeEvpPKeyHandle key)
{
const int Success = 1;
const int Fail = 0;
int result = CryptoNative_SlhDsaGetPalId(key, out PalSlhDsaAlgorithmId slhDsaId);

return result switch
{
Success => slhDsaId,
Fail => throw CreateOpenSslCryptographicException(),
int other => throw FailThrow(other),
};

static Exception FailThrow(int result)
{
Debug.Fail($"Unexpected return value {result} from {nameof(CryptoNative_SlhDsaGetPalId)}.");
return new CryptographicException();
}
}

[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_SlhDsaSignPure(
SafeEvpPKeyHandle pkey, IntPtr extraHandle,
ReadOnlySpan<byte> msg, int msgLength,
ReadOnlySpan<byte> context, int contextLength,
Span<byte> destination, int destinationLength);

internal static void SlhDsaSignPure(
SafeEvpPKeyHandle pkey,
ReadOnlySpan<byte> msg,
ReadOnlySpan<byte> context,
Span<byte> destination)
{
int ret = CryptoNative_SlhDsaSignPure(
pkey, GetExtraHandle(pkey),
msg, msg.Length,
context, context.Length,
destination, destination.Length);

if (ret != 1)
{
throw Interop.Crypto.CreateOpenSslCryptographicException();
}
}

[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_SlhDsaVerifyPure(
SafeEvpPKeyHandle pkey, IntPtr extraHandle,
ReadOnlySpan<byte> msg, int msgLength,
ReadOnlySpan<byte> context, int contextLength,
ReadOnlySpan<byte> signature, int signatureLength);

internal static bool SlhDsaVerifyPure(
SafeEvpPKeyHandle pkey,
ReadOnlySpan<byte> msg,
ReadOnlySpan<byte> context,
ReadOnlySpan<byte> signature)
{
int ret = CryptoNative_SlhDsaVerifyPure(
pkey, GetExtraHandle(pkey),
msg, msg.Length,
context, context.Length,
signature, signature.Length);

if (ret == 1)
{
return true;
}
else if (ret == 0)
{
return false;
}
else
{
throw Interop.Crypto.CreateOpenSslCryptographicException();
}
}

[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_SlhDsaExportSecretKey(SafeEvpPKeyHandle pkey, Span<byte> destination, int destinationLength);

[LibraryImport(Libraries.CryptoNative)]
private static partial int CryptoNative_SlhDsaExportPublicKey(SafeEvpPKeyHandle pkey, Span<byte> destination, int destinationLength);

internal static void SlhDsaExportSecretKey(SafeEvpPKeyHandle key, Span<byte> destination) =>
Interop.Crypto.ExportKeyContents(key, destination, CryptoNative_SlhDsaExportSecretKey);

internal static void SlhDsaExportPublicKey(SafeEvpPKeyHandle key, Span<byte> destination) =>
Interop.Crypto.ExportKeyContents(key, destination, CryptoNative_SlhDsaExportPublicKey);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal static partial class Crypto
{
internal static partial class EvpPKeySlhDsaAlgs
{
internal static string? SlhDsaSha2_128s { get; }
internal static string? SlhDsaShake128s { get; }
internal static string? SlhDsaSha2_128f { get; }
internal static string? SlhDsaShake128f { get; }
internal static string? SlhDsaSha2_192s { get; }
internal static string? SlhDsaShake192s { get; }
internal static string? SlhDsaSha2_192f { get; }
internal static string? SlhDsaShake192f { get; }
internal static string? SlhDsaSha2_256s { get; }
internal static string? SlhDsaShake256s { get; }
internal static string? SlhDsaSha2_256f { get; }
internal static string? SlhDsaShake256f { get; }

static EvpPKeySlhDsaAlgs()
{
CryptoInitializer.Initialize();

// Do not use property initializers for these because we need to ensure CryptoInitializer.Initialize
// is called first. Property initializers happen before cctors, so instead set the property after the
// initializer is run.
SlhDsaSha2_128s = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaSha2_128s.Name);
SlhDsaShake128s = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaShake128s.Name);
SlhDsaSha2_128f = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaSha2_128f.Name);
SlhDsaShake128f = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaShake128f.Name);
SlhDsaSha2_192s = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaSha2_192s.Name);
SlhDsaShake192s = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaShake192s.Name);
SlhDsaSha2_192f = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaSha2_192f.Name);
SlhDsaShake192f = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaShake192f.Name);
SlhDsaSha2_256s = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaSha2_256s.Name);
SlhDsaShake256s = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaShake256s.Name);
SlhDsaSha2_256f = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaSha2_256f.Name);
SlhDsaShake256f = IsSignatureAlgorithmAvailable(SlhDsaAlgorithm.SlhDsaShake256f.Name);
}
}
}
}
Loading
Loading