Skip to content
Open
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
39 changes: 20 additions & 19 deletions src/libraries/Common/src/Interop/Windows/BCrypt/Cng.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,26 @@ internal static partial class BCryptNative
/// </summary>
internal static class AlgorithmName
{
public const string DSA = "DSA"; // BCRYPT_DSA_ALGORITHM
public const string ECDH = "ECDH"; // BCRYPT_ECDH_ALGORITHM
public const string ECDHP256 = "ECDH_P256"; // BCRYPT_ECDH_P256_ALGORITHM
public const string ECDHP384 = "ECDH_P384"; // BCRYPT_ECDH_P384_ALGORITHM
public const string ECDHP521 = "ECDH_P521"; // BCRYPT_ECDH_P521_ALGORITHM
public const string ECDsa = "ECDSA"; // BCRYPT_ECDSA_ALGORITHM
public const string ECDsaP256 = "ECDSA_P256"; // BCRYPT_ECDSA_P256_ALGORITHM
public const string ECDsaP384 = "ECDSA_P384"; // BCRYPT_ECDSA_P384_ALGORITHM
public const string ECDsaP521 = "ECDSA_P521"; // BCRYPT_ECDSA_P521_ALGORITHM
public const string HKDF = "HKDF"; // BCRYPT_HKDF_ALGORITHM
public const string MD5 = "MD5"; // BCRYPT_MD5_ALGORITHM
public const string MLDsa = "ML-DSA"; // BCRYPT_MLDSA_ALGORITHM
public const string MLKem = "ML-KEM"; // BCRYPT_MLKEM_ALGORITHM
public const string RSA = "RSA"; // BCRYPT_RSA_ALGORITHM
public const string Sha1 = "SHA1"; // BCRYPT_SHA1_ALGORITHM
public const string Sha256 = "SHA256"; // BCRYPT_SHA256_ALGORITHM
public const string Sha384 = "SHA384"; // BCRYPT_SHA384_ALGORITHM
public const string Sha512 = "SHA512"; // BCRYPT_SHA512_ALGORITHM
public const string Pbkdf2 = "PBKDF2"; // BCRYPT_PBKDF2_ALGORITHM
public const string CompositeMLDsa = "Composite-ML-DSA"; // BCRYPT_COMPOSITE_MLDSA_ALGORITHM
public const string DSA = "DSA"; // BCRYPT_DSA_ALGORITHM
public const string ECDH = "ECDH"; // BCRYPT_ECDH_ALGORITHM
public const string ECDHP256 = "ECDH_P256"; // BCRYPT_ECDH_P256_ALGORITHM
public const string ECDHP384 = "ECDH_P384"; // BCRYPT_ECDH_P384_ALGORITHM
public const string ECDHP521 = "ECDH_P521"; // BCRYPT_ECDH_P521_ALGORITHM
public const string ECDsa = "ECDSA"; // BCRYPT_ECDSA_ALGORITHM
public const string ECDsaP256 = "ECDSA_P256"; // BCRYPT_ECDSA_P256_ALGORITHM
public const string ECDsaP384 = "ECDSA_P384"; // BCRYPT_ECDSA_P384_ALGORITHM
public const string ECDsaP521 = "ECDSA_P521"; // BCRYPT_ECDSA_P521_ALGORITHM
public const string HKDF = "HKDF"; // BCRYPT_HKDF_ALGORITHM
public const string MD5 = "MD5"; // BCRYPT_MD5_ALGORITHM
public const string MLDsa = "ML-DSA"; // BCRYPT_MLDSA_ALGORITHM
public const string MLKem = "ML-KEM"; // BCRYPT_MLKEM_ALGORITHM
public const string RSA = "RSA"; // BCRYPT_RSA_ALGORITHM
public const string Sha1 = "SHA1"; // BCRYPT_SHA1_ALGORITHM
public const string Sha256 = "SHA256"; // BCRYPT_SHA256_ALGORITHM
public const string Sha384 = "SHA384"; // BCRYPT_SHA384_ALGORITHM
public const string Sha512 = "SHA512"; // BCRYPT_SHA512_ALGORITHM
public const string Pbkdf2 = "PBKDF2"; // BCRYPT_PBKDF2_ALGORITHM
}

internal static class KeyDerivationFunction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ internal static unsafe NTSTATUS BCryptSignHashPss(
}
}

internal static unsafe void BCryptSignHashPqcPure(
internal static unsafe int BCryptSignHashPqcPure(
SafeBCryptKeyHandle key,
ReadOnlySpan<byte> data,
ReadOnlySpan<byte> context,
Expand Down Expand Up @@ -104,12 +104,14 @@ internal static unsafe void BCryptSignHashPqcPure(
BCryptSignVerifyFlags.BCRYPT_PAD_PQDSA);
}

Debug.Assert(bytesWritten == destination.Length);

if (status != Interop.BCrypt.NTSTATUS.STATUS_SUCCESS)
{
throw Interop.BCrypt.CreateCryptographicException(status);
}

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

return bytesWritten;
}

internal static unsafe void BCryptSignHashPqcPreHash(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ internal enum KeyBlobMagicNumber : int
BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC = 0x50444345,
BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC = 0x56444345,

BCRYPT_COMPOSITE_MLDSA_PUBLIC_MAGIC = 0x4B504D43,
BCRYPT_COMPOSITE_MLDSA_PRIVATE_MAGIC = 0x4B534D43,

BCRYPT_MLDSA_PUBLIC_MAGIC = 0x4B505344,
BCRYPT_MLDSA_PRIVATE_MAGIC = 0x4B535344,
BCRYPT_MLDSA_PRIVATE_SEED_MAGIC = 0x53535344,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,11 @@ static void SubjectPublicKeyReader(ReadOnlySpan<byte> key, in ValueAlgorithmIden
{
CompositeMLDsaAlgorithm algorithm = GetAlgorithmIdentifier(in identifier);

if (!IsAlgorithmSupported(algorithm))
{
throw new CryptographicException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa)));
}

if (!algorithm.IsValidPublicKeySize(key.Length))
{
throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm);
Expand Down Expand Up @@ -867,6 +872,11 @@ static void PrivateKeyReader(
{
CompositeMLDsaAlgorithm algorithm = GetAlgorithmIdentifier(in algorithmIdentifier);

if (!IsAlgorithmSupported(algorithm))
{
throw new CryptographicException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa)));
}

if (!algorithm.IsValidPrivateKeySize(privateKeyContents.Length))
{
throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm);
Expand Down Expand Up @@ -1795,6 +1805,50 @@ protected virtual void Dispose(bool disposing)
{
}

private protected bool TryExportPkcs8FromExportedPrivateKey(Span<byte> destination, out int bytesWritten)
{
AsnWriter? writer = null;

try
{
using (CryptoPoolLease lease = CryptoPoolLease.Rent(Algorithm.MaxPrivateKeySizeInBytes))
{
int privateKeySize = ExportCompositeMLDsaPrivateKeyCore(lease.Span);

if (!Algorithm.IsValidPrivateKeySize(privateKeySize))
{
bytesWritten = 0;
throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm);
}

// Add some overhead for the ASN.1 structure.
int initialCapacity = 32 + privateKeySize;

writer = new AsnWriter(AsnEncodingRules.DER, initialCapacity);

using (writer.PushSequence())
{
writer.WriteInteger(0); // Version

using (writer.PushSequence())
{
writer.WriteObjectIdentifier(Algorithm.Oid);
}

writer.WriteOctetString(lease.Span.Slice(0, privateKeySize));
}

Debug.Assert(writer.GetEncodedLength() <= initialCapacity);

return writer.TryEncode(destination, out bytesWritten);
}
}
finally
{
writer?.Reset();
}
}

private AsnWriter WriteEncryptedPkcs8PrivateKeyToAsnWriter(ReadOnlySpan<byte> passwordBytes, PbeParameters pbeParameters)
{
AsnWriter? tmp = null;
Expand Down
Loading
Loading