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
74 changes: 37 additions & 37 deletions src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ public bool TryExportPkcs8PrivateKey(Span<byte> destination, out int bytesWritte
3 + // Version Integer
2 + // AlgorithmIdentifier Sequence
3 + // AlgorithmIdentifier OID value, undervalued to be safe
2 + // Secret key Octet String prefix, undervalued to be safe
2 + // Private key Octet String prefix, undervalued to be safe
Algorithm.PrivateSeedSizeInBytes;

if (destination.Length < minimumPossiblePkcs8MLDsaKey)
Expand Down Expand Up @@ -1206,45 +1206,45 @@ public void ExportMLDsaPublicKey(Span<byte> destination)
}

/// <summary>
/// Exports the current key in the FIPS 204 secret key format.
/// Exports the current key in the FIPS 204 private key format.
/// </summary>
/// <returns>
/// The FIPS 204 secret key.
/// The FIPS 204 private key.
/// </returns>
/// <exception cref="CryptographicException">
/// <para>The current instance cannot export a secret key.</para>
/// <para>The current instance cannot export a private key.</para>
/// <para>-or-</para>
/// <para>An error occurred while exporting the key.</para>
/// </exception>
/// <exception cref="ObjectDisposedException">The object has already been disposed.</exception>
public byte[] ExportMLDsaSecretKey()
public byte[] ExportMLDsaPrivateKey()
{
ThrowIfDisposed();

byte[] destination = new byte[Algorithm.SecretKeySizeInBytes];
ExportMLDsaSecretKeyCore(destination);
byte[] destination = new byte[Algorithm.PrivateKeySizeInBytes];
ExportMLDsaPrivateKeyCore(destination);
return destination;
}

/// <summary>
/// Exports the current key in the FIPS 204 secret key format.
/// Exports the current key in the FIPS 204 private key format.
/// </summary>
/// <param name="destination">
/// The buffer to receive the secret key. Its length must be exactly
/// <see cref="MLDsaAlgorithm.SecretKeySizeInBytes"/>.
/// The buffer to receive the private key. Its length must be exactly
/// <see cref="MLDsaAlgorithm.PrivateKeySizeInBytes"/>.
/// </param>
/// <exception cref="ArgumentException">
/// <paramref name="destination"/> is the incorrect length to receive the secret key.
/// <paramref name="destination"/> is the incorrect length to receive the private key.
/// </exception>
/// <exception cref="CryptographicException">
/// An error occurred while exporting the key.
/// </exception>
public void ExportMLDsaSecretKey(Span<byte> destination)
public void ExportMLDsaPrivateKey(Span<byte> destination)
{
Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.SecretKeySizeInBytes);
Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.PrivateKeySizeInBytes);
ThrowIfDisposed();

ExportMLDsaSecretKeyCore(destination);
ExportMLDsaPrivateKeyCore(destination);
}

/// <summary>
Expand Down Expand Up @@ -1820,13 +1820,13 @@ public static MLDsa ImportMLDsaPublicKey(MLDsaAlgorithm algorithm, byte[] source
}

/// <summary>
/// Imports an ML-DSA private key in the FIPS 204 secret key format.
/// Imports an ML-DSA private key in the FIPS 204 private key format.
/// </summary>
/// <param name="algorithm">
/// The specific ML-DSA algorithm for this key.
/// </param>
/// <param name="source">
/// The bytes of a FIPS 204 secret key.
/// The bytes of a FIPS 204 private key.
/// </param>
/// <returns>
/// The imported key.
Expand All @@ -1844,29 +1844,29 @@ public static MLDsa ImportMLDsaPublicKey(MLDsaAlgorithm algorithm, byte[] source
/// An error occurred while importing the key.
/// </para>
/// </exception>
public static MLDsa ImportMLDsaSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source)
public static MLDsa ImportMLDsaPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source)
{
ArgumentNullException.ThrowIfNull(algorithm);

if (source.Length != algorithm.SecretKeySizeInBytes)
if (source.Length != algorithm.PrivateKeySizeInBytes)
{
throw new ArgumentException(SR.Cryptography_KeyWrongSizeForAlgorithm, nameof(source));
throw new ArgumentException(SR.Argument_PrivateKeyWrongSizeForAlgorithm, nameof(source));
}

ThrowIfNotSupported();
return MLDsaImplementation.ImportSecretKey(algorithm, source);
return MLDsaImplementation.ImportPrivateKey(algorithm, source);
}

/// <inheritdoc cref="ImportMLDsaSecretKey(MLDsaAlgorithm, ReadOnlySpan{byte})" />
/// <inheritdoc cref="ImportMLDsaPrivateKey(MLDsaAlgorithm, ReadOnlySpan{byte})" />
/// <exception cref="ArgumentNullException">
/// <paramref name="algorithm"/> or <paramref name="source" /> is <see langword="null" />.
/// </exception>
public static MLDsa ImportMLDsaSecretKey(MLDsaAlgorithm algorithm, byte[] source)
public static MLDsa ImportMLDsaPrivateKey(MLDsaAlgorithm algorithm, byte[] source)
{
ArgumentNullException.ThrowIfNull(algorithm);
ArgumentNullException.ThrowIfNull(source);

return ImportMLDsaSecretKey(algorithm, new ReadOnlySpan<byte>(source));
return ImportMLDsaPrivateKey(algorithm, new ReadOnlySpan<byte>(source));
}

/// <summary>
Expand Down Expand Up @@ -2022,12 +2022,12 @@ protected virtual void Dispose(bool disposing)
protected abstract void ExportMLDsaPublicKeyCore(Span<byte> destination);

/// <summary>
/// When overridden in a derived class, exports the FIPS 204 secret key to the specified buffer.
/// When overridden in a derived class, exports the FIPS 204 private key to the specified buffer.
/// </summary>
/// <param name="destination">
/// The buffer to receive the secret key.
/// The buffer to receive the private key.
/// </param>
protected abstract void ExportMLDsaSecretKeyCore(Span<byte> destination);
protected abstract void ExportMLDsaPrivateKeyCore(Span<byte> destination);

/// <summary>
/// When overridden in a derived class, exports the private seed to the specified buffer.
Expand Down Expand Up @@ -2133,10 +2133,10 @@ private AsnWriter ExportEncryptedPkcs8PrivateKeyCore(ReadOnlySpan<char> password

private TResult ExportPkcs8PrivateKeyCallback<TResult>(ExportPkcs8PrivateKeyFunc<TResult> func)
{
// A PKCS#8 ML-DSA secret key has an ASN.1 overhead of 28 bytes, assuming no attributes.
// A PKCS#8 ML-DSA private key has an ASN.1 overhead of 28 bytes, assuming no attributes.
// Make it an even 32 and that should give a good starting point for a buffer size.
// The secret key is always larger than the seed so this buffer size can accommodate both.
int size = Algorithm.SecretKeySizeInBytes + 32;
// The private key is always larger than the seed so this buffer size can accommodate both.
int size = Algorithm.PrivateKeySizeInBytes + 32;
// The buffer is only being passed out as a span, so the derived type can't meaningfully
// hold on to it without being malicious.
byte[] buffer = CryptoPool.Rent(size);
Expand Down Expand Up @@ -2185,30 +2185,30 @@ private static void MLDsaKeyReader(
}
else if (dsaKey.ExpandedKey is ReadOnlyMemory<byte> expandedKey)
{
if (expandedKey.Length != algorithm.SecretKeySizeInBytes)
if (expandedKey.Length != algorithm.PrivateKeySizeInBytes)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

dsa = MLDsaImplementation.ImportSecretKey(algorithm, expandedKey.Span);
dsa = MLDsaImplementation.ImportPrivateKey(algorithm, expandedKey.Span);
}
else if (dsaKey.Both is MLDsaPrivateKeyBothAsn both)
{
int secretKeySize = algorithm.SecretKeySizeInBytes;
int privateKeySize = algorithm.PrivateKeySizeInBytes;

if (both.Seed.Length != algorithm.PrivateSeedSizeInBytes ||
both.ExpandedKey.Length != secretKeySize)
both.ExpandedKey.Length != privateKeySize)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

MLDsa key = MLDsaImplementation.ImportMLDsaPrivateSeed(algorithm, both.Seed.Span);
byte[] rent = CryptoPool.Rent(secretKeySize);
Span<byte> buffer = rent.AsSpan(0, secretKeySize);
byte[] rent = CryptoPool.Rent(privateKeySize);
Span<byte> buffer = rent.AsSpan(0, privateKeySize);

try
{
key.ExportMLDsaSecretKey(buffer);
key.ExportMLDsaPrivateKey(buffer);

if (CryptographicOperations.FixedTimeEquals(buffer, both.ExpandedKey.Span))
{
Expand All @@ -2226,7 +2226,7 @@ private static void MLDsaKeyReader(
}
finally
{
CryptoPool.Return(rent, secretKeySize);
CryptoPool.Return(rent, privateKeySize);
}
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ public sealed class MLDsaAlgorithm : IEquatable<MLDsaAlgorithm>
public string Name { get; }

/// <summary>
/// Gets the size, in bytes, of the ML-DSA secret key for the current ML-DSA algorithm.
/// Gets the size, in bytes, of the ML-DSA private key for the current ML-DSA algorithm.
/// </summary>
/// <value>
/// The size, in bytes, of the ML-DSA secret key for the current ML-DSA algorithm.
/// The size, in bytes, of the ML-DSA private key for the current ML-DSA algorithm.
/// </value>
public int SecretKeySizeInBytes { get; }
public int PrivateKeySizeInBytes { get; }

/// <summary>
/// Gets the size, in bytes, of the ML-DSA private seed for the current ML-DSA algorithm.
Expand Down Expand Up @@ -66,14 +66,14 @@ public sealed class MLDsaAlgorithm : IEquatable<MLDsaAlgorithm>

private MLDsaAlgorithm(
string name,
int secretKeySizeInBytes,
int privateKeySizeInBytes,
int publicKeySizeInBytes,
int signatureSizeInBytes,
int lambdaCollisionStrength,
string oid)
{
Name = name;
SecretKeySizeInBytes = secretKeySizeInBytes;
PrivateKeySizeInBytes = privateKeySizeInBytes;
PublicKeySizeInBytes = publicKeySizeInBytes;
SignatureSizeInBytes = signatureSizeInBytes;
LambdaCollisionStrength = lambdaCollisionStrength;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ protected override void ExportMLDsaPrivateSeedCore(Span<byte> destination)
}

/// <inheritdoc/>
protected override void ExportMLDsaSecretKeyCore(Span<byte> destination)
protected override void ExportMLDsaPrivateKeyCore(Span<byte> destination)
{
bool encryptedOnlyExport = CngPkcs8.AllowsOnlyEncryptedExport(_key);

Expand All @@ -161,16 +161,16 @@ protected override void ExportMLDsaSecretKeyCore(Span<byte> destination)

if (expandedKey is ReadOnlyMemory<byte> expandedKeyValue)
{
if (expandedKeyValue.Length != algorithm.SecretKeySizeInBytes)
if (expandedKeyValue.Length != algorithm.PrivateKeySizeInBytes)
{
throw new CryptographicException(SR.Argument_SecretKeyWrongSizeForAlgorithm);
throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm);
}

expandedKeyValue.Span.CopyTo(destination);
return;
}

// If PKCS#8 only has seed, then we can calculate the secret key
// If PKCS#8 only has seed, then we can calculate the private key
ReadOnlyMemory<byte>? seed = mldsaPrivateKeyAsn.Seed;

if (seed is ReadOnlyMemory<byte> seedValue)
Expand All @@ -182,7 +182,7 @@ protected override void ExportMLDsaSecretKeyCore(Span<byte> destination)

using (MLDsa cloned = MLDsaImplementation.ImportSeed(algorithm, seedValue.Span))
{
cloned.ExportMLDsaSecretKey(destination);
cloned.ExportMLDsaPrivateKey(destination);
return;
}
}
Expand All @@ -194,7 +194,7 @@ protected override void ExportMLDsaSecretKeyCore(Span<byte> destination)
}
else
{
ExportKey(CngKeyBlobFormat.PQDsaPrivateBlob, Algorithm.SecretKeySizeInBytes, destination);
ExportKey(CngKeyBlobFormat.PQDsaPrivateBlob, Algorithm.PrivateKeySizeInBytes, destination);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ internal CngKey CreateEphemeralCng()
{
string bcryptBlobType =
_hasSeed ? Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_SEED_BLOB :
_hasSecretKey ? Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_BLOB :
_hasPrivateKey ? Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_BLOB :
Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PUBLIC_BLOB;

CngKeyBlobFormat cngBlobFormat =
_hasSecretKey ? CngKeyBlobFormat.PQDsaPrivateBlob :
_hasPrivateKey ? CngKeyBlobFormat.PQDsaPrivateBlob :
_hasSeed ? CngKeyBlobFormat.PQDsaPrivateSeedBlob :
CngKeyBlobFormat.PQDsaPublicBlob;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected override bool VerifyMuCore(ReadOnlySpan<byte> mu, ReadOnlySpan<byte> s
protected override void ExportMLDsaPublicKeyCore(Span<byte> destination) =>
throw new PlatformNotSupportedException();

protected override void ExportMLDsaSecretKeyCore(Span<byte> destination) =>
protected override void ExportMLDsaPrivateKeyCore(Span<byte> destination) =>
throw new PlatformNotSupportedException();

protected override void ExportMLDsaPrivateSeedCore(Span<byte> destination) =>
Expand All @@ -55,7 +55,7 @@ internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algor
internal static partial MLDsaImplementation ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source) =>
throw new PlatformNotSupportedException();

internal static partial MLDsaImplementation ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source) =>
internal static partial MLDsaImplementation ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source) =>
throw new PlatformNotSupportedException();

internal static partial MLDsaImplementation ImportSeed(MLDsaAlgorithm algorithm, ReadOnlySpan<byte> source) =>
Expand Down
Loading
Loading