-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Labels
area-System.Securitycryptographic-docs-impactIssues impacting cryptographic docs. Cleared and reused after documentation is updated each release.Issues impacting cryptographic docs. Cleared and reused after documentation is updated each release.
Milestone
Description
As part of the Post-Quantum Cryptography effort, we should add support for Stateless Hash-Based Digital Signature Algorithm (SLH-DSA).
As a signature algorithm, SLH-DSA should be available as a primitive, as well as integrated into:
- X509Certificate2
- SignedXml
- COSE
- TLS (no API required, carried with the certificate)
As the algorithm (family) name is generally written as SLH-DSA, the .NET name is composed of the concatenation of two separate three-letter initialisms, so two capital letters and 4 lowercase: SlhDsa
namespace System.Security.Cryptography
{
[Experimental("SYSLIB5006")]
public abstract class SlhDsa : IDisposable
{
public static bool IsSupported { get; }
protected SlhDsa(SlhDsaAlgorithm algorithm);
public SlhDsaAlgorithm Algorithm { get; }
public int SignatureSizeInBytes { get; }
public void Dispose();
public int SignData(
ReadOnlySpan<byte> data,
Span<byte> destination,
ReadOnlySpan<byte> context = default);
public bool VerifyData(
ReadOnlySpan<byte> data,
ReadOnlySpan<byte> signature,
ReadOnlySpan<byte> context = default);
public int SignPreHash(
ReadOnlySpan<byte> hash,
Span<byte> destination,
HashAlgorithmName preHashAlgorithm,
ReadOnlySpan<byte> context = default);
public bool SignPreHash(
ReadOnlySpan<byte> hash,
ReadOnlySpan<byte> signature,
HashAlgorithmName preHashAlgorithm,
ReadOnlySpan<byte> context = default);
public byte[] ExportSubjectPublicKeyInfo();
public bool TryExportSubjectPublicKeyInfo(Span<byte> destination, out int bytesWritten);
public string ExportSubjectPublicKeyInfoPem();
public byte[] ExportPkcs8PrivateKey();
public bool TryExportPkcs8PrivateKey(Span<byte> destination, out int bytesWritten);
public string ExportPkcs8PrivateKeyPem();
public byte[] ExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<char> password,
PbeParameters pbeParameters);
public byte[] ExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<byte> passwordBytes,
PbeParameters pbeParameters);
public bool TryExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<char> password,
PbeParameters pbeParameters,
Span<byte> destination,
out int bytesWritten);
public bool TryExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<byte> passwordBytes,
PbeParameters pbeParameters,
Span<byte> destination,
out int bytesWritten);
public string ExportEncryptedPkcs8PrivateKeyPem(
ReadOnlySpan<char> password,
PbeParameters pbeParameters);
public string ExportEncryptedPkcs8PrivateKeyPem(
ReadOnlySpan<byte> passwordBytes,
PbeParameters pbeParameters);
public int ExportSlhDsaPublicKey(Span<byte> destination);
public int ExportSlhDsaSecretKey(Span<byte> destination);
public int ExportSlhDsaPrivateSeed(Span<byte> destination);
public static SlhDsa GenerateKey(SlhDsaAlgorithm algorithm);
public static SlhDsa ImportSubjectPublicKeyInfo(ReadOnlySpan<byte> source);
public static SlhDsa ImportPkcs8PrivateKey(ReadOnlySpan<byte> source);
public static SlhDsa ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<byte> passwordBytes, ReadOnlySpan<byte> source);
public static SlhDsa ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<char> password, ReadOnlySpan<byte> source);
public static SlhDsa ImportFromPem(ReadOnlySpan<char> source);
public static SlhDsa ImportFromEncryptedPem(ReadOnlySpan<char> source, ReadOnlySpan<char> password);
public static SlhDsa ImportFromEncryptedPem(ReadOnlySpan<char> source, ReadOnlySpan<byte> passwordBytes);
public static SlhDsa ImportSlhDsaPublicKey(SlhDsaAlgorithm algorithm, ReadOnlySpan<byte> source);
public static SlhDsa ImportSlhDsaSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan<byte> source);
public static SlhDsa ImportSlhDsaPrivateSeed(SlhDsaAlgorithm algorithm, ReadOnlySpan<byte> source);
protected void ThrowIfDisposed();
protected virtual void Dispose(bool disposing);
protected abstract void SignDataCore(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, Span<byte> destination);
protected abstract bool VerifyDataCore(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, ReadOnlySpan<byte> signature);
protected abstract void SignPreHashCore(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> context, HashAlgorithmName preHashAlgorithm, Span<byte> destination);
protected abstract bool VerifyPreHashCore(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> context, HashAlgorithmName preHashAlgorithm, ReadOnlySpan<byte> signature);
protected abstract void ExportSlhDsaPublicKeyCore(Span<byte> destination);
protected abstract void ExportSlhDsaSecretKeyCore(Span<byte> destination);
protected abstract void ExportSlhDsaPrivateSeedCore(Span<byte> destination);
}
[DebuggerDisplay("{Name,nq}")]
[Experimental("SYSLIB5006")]
public sealed class SlhDsaAlgorithm
{
private SlhDsaAlgorithm();
public static SlhDsaAlgorithm SlhDsaSha2_128s { get; }
public static SlhDsaAlgorithm SlhDsaSha2_128f { get; }
public static SlhDsaAlgorithm SlhDsaSha2_192s { get; }
public static SlhDsaAlgorithm SlhDsaSha2_192f { get; }
public static SlhDsaAlgorithm SlhDsaSha2_256s { get; }
public static SlhDsaAlgorithm SlhDsaSha2_256f { get; }
public static SlhDsaAlgorithm SlhDsaShake128s { get; }
public static SlhDsaAlgorithm SlhDsaShake128f { get; }
public static SlhDsaAlgorithm SlhDsaShake192s { get; }
public static SlhDsaAlgorithm SlhDsaShake192f { get; }
public static SlhDsaAlgorithm SlhDsaShake256s { get; }
public static SlhDsaAlgorithm SlhDsaShake256f { get; }
public string Name { get; }
public int PublicKeySizeInBytes { get; }
public int SecretKeySizeInBytes { get; }
public int SignatureSizeInBytes { get; }
}
[Experimental("SYSLIB5006")]
public class SlhDsaCng : SlhDsa
{
public MLDsaCng(CngKey key);
// On ECDsaCng this is an allocating property. Changed to a method here.
public CngKey GetCngKey();
}
[Experimental("SYSLIB5006")]
public class SlhDsaOpenSsl : SlhDsa
{
public SlhDsaOpenSsl(SafeEvpPKeyHandle keyHandle);
public SafeEvpPKeyHandle DuplicateKeyHandle();
}
}
namespace System.Security.Cryptography.X509Certificates
{
// Extension class to enable porting to Microsoft.Bcl.Cryptography
[Experimental("SYSLIB5006")]
public sealed class SlhDsaCertificateExtensions
{
public static SlhDsa GetSlhDsaPublicKey(this X509Certificate2 certificate);
public static SlhDsa GetSlhDsaPrivateKey(this X509Certificate2 certificate);
}
public partial class CertificateRequest
{
[Experimental("SYSLIB5006")]
public CertificateRequest(string subjectName, SlhDsa key);
[Experimental("SYSLIB5006")]
public CertificateRequest(X500DistinguishedName subjectName, SlhDsa key);
}
#if NET10_OR_GREATER
public partial class X509SignatureGenerator
{
[Experimental("SYSLIB5006")]
public static X509SignatureGenerator CreateForSlhDsa(SlhDsa key);
}
#endif
}
#if NET10_OR_GREATER
namespace System.Security.Cryptography.Pkcs
{
public partial class CmsSigner
{
[Experimental("SYSLIB5006")]
public CmsSigner(
X509Certificate2 certificate,
SlhDsa privateKey,
SubjectIdentifierType signerIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier);
}
}
#endif
namespace System.Security.Cryptography.Cose
{
public partial class CoseSigner
{
// As PrivateKey is marked as non-nullable, this will set it to an instance of a non-public type that wraps the key.
[Experimental("SYSLIB5006")]
public CoseSigner(SlhDsa key);
}
}Reactions are currently unavailable
Sub-issues
Metadata
Metadata
Assignees
Labels
area-System.Securitycryptographic-docs-impactIssues impacting cryptographic docs. Cleared and reused after documentation is updated each release.Issues impacting cryptographic docs. Cleared and reused after documentation is updated each release.