From 72c57dc1270557fb6d197759ded1f67145bca356 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 10 Apr 2026 12:01:07 -0700 Subject: [PATCH] Improvements to C# PQC --- wrapper/CSharp/user_settings.h | 1 + .../CSharp/wolfCrypt-Test/wolfCrypt-Test.cs | 8 +-- wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs | 72 +++++++++---------- wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs | 2 - 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/wrapper/CSharp/user_settings.h b/wrapper/CSharp/user_settings.h index 13aadf5dc2..1dae86d2e0 100644 --- a/wrapper/CSharp/user_settings.h +++ b/wrapper/CSharp/user_settings.h @@ -91,6 +91,7 @@ #define HAVE_MLKEM #define WOLFSSL_WC_MLKEM #define WOLFSSL_HAVE_MLKEM +/* Required for PQC with DTLS 1.3 (auto-enabled in settings.h, explicit for clarity) */ #define WOLFSSL_DTLS_CH_FRAG #define HAVE_DILITHIUM #define WOLFSSL_WC_DILITHIUM diff --git a/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs b/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs index 5875085193..8364dcc34b 100644 --- a/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs +++ b/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs @@ -871,7 +871,7 @@ public class wolfCrypt_Test_CSharp if (ret == 0) { Console.WriteLine("Testing ML-DSA Key Export..."); - ret = DilithiumExportPrivateKey(key, out privateKey); + ret = wolfcrypt.DilithiumExportPrivateKey(key, out privateKey); if (ret != 0) { Console.Error.WriteLine($"Failed to export private key. Error code: {ret}"); @@ -879,7 +879,7 @@ public class wolfCrypt_Test_CSharp } if (ret == 0) { - ret = DilithiumExportPublicKey(key, out publicKey); + ret = wolfcrypt.DilithiumExportPublicKey(key, out publicKey); if (ret != 0) { Console.Error.WriteLine($"Failed to export public key. Error code: {ret}"); @@ -894,7 +894,7 @@ public class wolfCrypt_Test_CSharp if (ret == 0) { Console.WriteLine("Testing ML-DSA Key Import..."); - ret = DilithiumImportPrivateKey(privateKey, key); + ret = wolfcrypt.DilithiumImportPrivateKey(privateKey, key); if (ret != 0) { Console.Error.WriteLine($"Failed to import private key. Error code: {ret}"); @@ -902,7 +902,7 @@ public class wolfCrypt_Test_CSharp } if (ret == 0) { - ret = DilithiumImportPublicKey(publicKey, key); + ret = wolfcrypt.DilithiumImportPublicKey(publicKey, key); if (ret != 0) { Console.Error.WriteLine($"Failed to import public key. Error code: {ret}"); diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs index b59a96d716..8a28275ebe 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs @@ -540,9 +540,9 @@ namespace wolfSSL.CSharp [DllImport(wolfssl_dll)] private static extern int wc_dilithium_import_public(byte[] input, uint inputLen, IntPtr key); [DllImport(wolfssl_dll)] - private static extern int wc_dilithium_sign_msg(byte[] msg, uint msgLen, byte[] sig, ref uint sigLen, IntPtr key, IntPtr rng); + private static extern int wc_dilithium_sign_ctx_msg(byte[] ctx, byte ctxLen, byte[] msg, uint msgLen, byte[] sig, ref uint sigLen, IntPtr key, IntPtr rng); [DllImport(wolfssl_dll)] - private static extern int wc_dilithium_verify_msg(byte[] sig, uint sigLen, byte[] msg, uint msgLen, ref int res, IntPtr key); + private static extern int wc_dilithium_verify_ctx_msg(byte[] sig, uint sigLen, byte[] ctx, byte ctxLen, byte[] msg, uint msgLen, ref int res, IntPtr key); [DllImport(wolfssl_dll)] private static extern int wc_MlDsaKey_GetPrivLen(IntPtr key, ref int len); [DllImport(wolfssl_dll)] @@ -571,9 +571,9 @@ namespace wolfSSL.CSharp [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private static extern int wc_dilithium_import_public(byte[] input, uint inputLen, IntPtr key); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private static extern int wc_dilithium_sign_msg(byte[] msg, uint msgLen, byte[] sig, ref uint sigLen, IntPtr key, IntPtr rng); + private static extern int wc_dilithium_sign_ctx_msg(byte[] ctx, byte ctxLen, byte[] msg, uint msgLen, byte[] sig, ref uint sigLen, IntPtr key, IntPtr rng); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private static extern int wc_dilithium_verify_msg(byte[] sig, uint sigLen, byte[] msg, uint msgLen, ref int res, IntPtr key); + private static extern int wc_dilithium_verify_ctx_msg(byte[] sig, uint sigLen, byte[] ctx, byte ctxLen, byte[] msg, uint msgLen, ref int res, IntPtr key); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private static extern int wc_MlDsaKey_GetPrivLen(IntPtr key, ref int len); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] @@ -2982,18 +2982,15 @@ namespace wolfSSL.CSharp /// 0 on success, negative value on error. public static int MlKemFreeKey(ref IntPtr key) { - int ret = 0; + int ret; if (key == IntPtr.Zero) { return BAD_FUNC_ARG; } - if (key != IntPtr.Zero) - { - ret = wc_MlKemKey_Delete(key, IntPtr.Zero); - key = IntPtr.Zero; - } + ret = wc_MlKemKey_Delete(key, IntPtr.Zero); + key = IntPtr.Zero; return ret; } @@ -3017,10 +3014,10 @@ namespace wolfSSL.CSharp try { ret = wc_MlKemKey_PublicKeySize(key, ref pubLen); - if (ret !=0 || pubLen == 0) + if (ret != 0 || pubLen == 0) { log(ERROR_LOG, "Failed to get MlKem public key length. Error code: " + ret); - return ret; + return (ret != 0) ? ret : BAD_FUNC_ARG; } if (pubLen > int.MaxValue) { @@ -3066,10 +3063,10 @@ namespace wolfSSL.CSharp try { ret = wc_MlKemKey_PrivateKeySize(key, ref privLen); - if (ret !=0 || privLen == 0) + if (ret != 0 || privLen == 0) { log(ERROR_LOG, "Failed to get MlKem private key length. Error code: " + ret); - return ret; + return (ret != 0) ? ret : BAD_FUNC_ARG; } if (privLen > int.MaxValue) { @@ -3123,14 +3120,14 @@ namespace wolfSSL.CSharp if (ret != 0 || pubLen == 0) { log(ERROR_LOG, "Failed to get MlKem public key length. Error code: " + ret); - return ret; + return (ret != 0) ? ret : BAD_FUNC_ARG; } if ((uint)publicKey.Length != pubLen) - { - log(ERROR_LOG, "MlKem public key buffer length mismatch. Expected: " + - pubLen + ", actual: " + publicKey.Length); - return BUFFER_E; - } + { + log(ERROR_LOG, "MlKem public key buffer length mismatch. Expected: " + + pubLen + ", actual: " + publicKey.Length); + return BUFFER_E; + } ret = wc_MlKemKey_DecodePublicKey(key, publicKey, pubLen); if (ret != 0) @@ -3172,12 +3169,12 @@ namespace wolfSSL.CSharp try { ret = wc_MlKemKey_PrivateKeySize(key, ref privLen); - if (privLen == 0) + if (ret != 0 || privLen == 0) { log(ERROR_LOG, "Failed to get MlKem private key length. Error code: " + ret); - return ret; + return (ret != 0) ? ret : BAD_FUNC_ARG; } - + if ((uint)privateKey.Length != privLen) { log(ERROR_LOG, "MlKem private key buffer length mismatch. Required: " + privLen + @@ -3416,18 +3413,15 @@ namespace wolfSSL.CSharp /// 0 on success, negative value on error. public static int DilithiumFreeKey(ref IntPtr key) { - int ret = 0; + int ret; if (key == IntPtr.Zero) { return BAD_FUNC_ARG; } - if (key != IntPtr.Zero) - { - ret = wc_dilithium_delete(key, IntPtr.Zero); - key = IntPtr.Zero; - } + ret = wc_dilithium_delete(key, IntPtr.Zero); + key = IntPtr.Zero; return ret; } @@ -3500,10 +3494,10 @@ namespace wolfSSL.CSharp try { ret = wc_MlDsaKey_GetPrivLen(key, ref privLen); - if (privLen <= 0) + if (ret != 0 || privLen <= 0) { log(ERROR_LOG, "Failed to get Dilithium private key length. Error code: " + ret); - return ret; + return (ret != 0) ? ret : BAD_FUNC_ARG; } privateKey = new byte[privLen]; @@ -3550,10 +3544,10 @@ namespace wolfSSL.CSharp try { ret = wc_MlDsaKey_GetPubLen(key, ref pubLen); - if (pubLen <= 0) + if (ret != 0 || pubLen <= 0) { log(ERROR_LOG, "Failed to get Dilithium public key length. Error code: " + ret); - return ret; + return (ret != 0) ? ret : BAD_FUNC_ARG; } publicKey = new byte[pubLen]; @@ -3602,10 +3596,10 @@ namespace wolfSSL.CSharp try { ret = wc_MlDsaKey_GetSigLen(key, ref sigLen); - if (sigLen <= 0) + if (ret != 0 || sigLen <= 0) { log(ERROR_LOG, "Failed to get Dilithium signature length. Error code: " + ret); - return ret; + return (ret != 0) ? ret : BAD_FUNC_ARG; } sig = new byte[sigLen]; @@ -3614,9 +3608,10 @@ namespace wolfSSL.CSharp if (rng == IntPtr.Zero) { log(ERROR_LOG, "Failed to create RNG for Dilithium signing."); - return EXCEPTION_E; + return MEMORY_E; } - ret = wc_dilithium_sign_msg(msg, (uint)msg.Length, sig, ref outLen, key, rng); + /* FIPS 204 sign with empty context (ctx=null, ctxLen=0). */ + ret = wc_dilithium_sign_ctx_msg(null, 0, msg, (uint)msg.Length, sig, ref outLen, key, rng); if (ret != 0) { log(ERROR_LOG, "Failed to sign message with Dilithium key. Error code: " + ret); @@ -3660,7 +3655,8 @@ namespace wolfSSL.CSharp try { - ret = wc_dilithium_verify_msg(sig, (uint)sig.Length, msg, (uint)msg.Length, ref res, key); + /* FIPS 204 verify with empty context (ctx=null, ctxLen=0). */ + ret = wc_dilithium_verify_ctx_msg(sig, (uint)sig.Length, null, 0, msg, (uint)msg.Length, ref res, key); if (ret != 0) { log(ERROR_LOG, "Failed to verify message with Dilithium key. Error code: " + ret); diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs index 644a699d67..106f3ffb6a 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs @@ -795,8 +795,6 @@ namespace wolfSSL.CSharp WOLFSSL_SECP521R1MLKEM1024 = 12109, WOLFSSL_X25519MLKEM512 = 12214, WOLFSSL_X448MLKEM768 = 12215, - - WOLF_ENUM_DUMMY_LAST_ELEMENT = 0 }