diff --git a/wrapper/CSharp/user_settings.h b/wrapper/CSharp/user_settings.h
index 21a72a69b9..c38bc8da7f 100644
--- a/wrapper/CSharp/user_settings.h
+++ b/wrapper/CSharp/user_settings.h
@@ -85,6 +85,16 @@
#define ECC_TIMING_RESISTANT
#define HAVE_COMP_KEY
+/* Enable ML-KEM, ML-DSA */
+#define HAVE_MLKEM
+#define WOLFSSL_WC_MLKEM
+#define WOLFSSL_HAVE_MLKEM
+#define WOLFSSL_DTLS_CH_FRAG
+#define HAVE_DILITHIUM
+#define WOLFSSL_WC_DILITHIUM
+#define WOLFSSL_SHAKE128
+#define WOLFSSL_SHAKE256
+
/* Disable features */
#define NO_PSK
diff --git a/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs b/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs
index b9a1be3519..253de8199b 100644
--- a/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs
+++ b/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs
@@ -648,6 +648,289 @@ private static void curve25519_test()
if (publicKeyB != IntPtr.Zero) wolfcrypt.Curve25519FreeKey(publicKeyB);
} /* END curve25519_test */
+ private static void mlkem_test(wolfcrypt.MlKemTypes type)
+ {
+ int ret = 0;
+ IntPtr keyA = IntPtr.Zero;
+ IntPtr keyB = IntPtr.Zero;
+ IntPtr heap = IntPtr.Zero;
+ int devId = wolfcrypt.INVALID_DEVID;
+ byte[] pubA, privA, cipherText, sharedSecretA, sharedSecretB;
+
+ try
+ {
+ Console.WriteLine("\nStarting " + type + " shared secret test ...");
+
+ /* Generate Key Pair */
+ Console.WriteLine("Testing ML-KEM Key Generation...");
+
+ Console.WriteLine("Generate Key Pair A...");
+ keyA = wolfcrypt.MlKemMakeKey(type, heap, devId);
+ if (keyA == IntPtr.Zero)
+ {
+ ret = -1;
+ Console.Error.WriteLine("Failed to generate key pair A.");
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("Generate Key Pair B...");
+ keyB = wolfcrypt.MlKemMakeKey(type, heap, devId);
+ if (keyB == IntPtr.Zero)
+ {
+ ret = -1;
+ Console.Error.WriteLine("Failed to generate key pair B.");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-KEM Key Generation test passed.");
+ }
+
+ /* Encode */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-KEM Key Encode...");
+ ret = wolfcrypt.MlKemEncodePublicKey(keyA, out pubA);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to encode public key of A.");
+ }
+ }
+ if (ret == 0)
+ {
+ ret = wolfcrypt.MlKemEncodePrivateKey(keyA, out privA);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to encode private key of A.");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-KEM Key Encode test passed.");
+ }
+
+ /* Encapsulate */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-KEM Encapsulation...");
+ ret = wolfcrypt.MlKemEncapsulate(keyA, out cipherText, out sharedSecretA);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to encapsulate.");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-KEM Encapsulation test passed.");
+ }
+
+ /* Decode */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-KEM Decode...");
+ ret = wolfcrypt.MlKemDecodePrivateKey(keyB, privA);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to decode private key of A.");
+ }
+ }
+ if (ret == 0)
+ {
+ ret = wolfcrypt.MlKemDecodePublicKey(keyB, pubA);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to decode public key of B.");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-KEM Decode test passed.");
+ }
+
+ /* Decapsulate */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-KEM Decapsulation...");
+ ret = wolfcrypt.MlKemDecapsulate(keyB, cipherText, out sharedSecretB);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to decapsulate.");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-KEM Decapsulation test passed.");
+ }
+
+ /* DEBUG CODE FOR REVIEW */
+ ret = BAD_FUNC_ARG;
+
+ /* Check */
+ if (ret == 0)
+ {
+ Console.WriteLine("Comparing Shared Secrets...");
+ if (!wolfcrypt.ByteArrayVerify(sharedSecretA, sharedSecretB))
+ {
+ Console.Error.WriteLine("Shared secrets do not match.");
+ }
+ else
+ {
+ Console.WriteLine("ML-KEM shared secret match.");
+ }
+ }
+ }
+ catch
+ {
+ // todo:
+ // ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386193630
+ // ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386194020
+ }
+ finally
+ {
+ /* Cleanup */
+ if (keyA != IntPtr.Zero)
+ {
+ ret = wolfcrypt.MlKemFreeKey(keyA);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to free MlKem key A. Error code: " + ret);
+ }
+ }
+ if (keyB != IntPtr.Zero)
+ {
+ ret = wolfcrypt.MlKemFreeKey(keyB);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to free MlKem key B. Error code: " + ret);
+ }
+ }
+ }
+ } /* END mlkem_test */
+
+ private static void mldsa_test(wolfcrypt.MlDsaTypes type)
+ {
+ int ret = 0;
+ IntPtr key = IntPtr.Zero;
+ IntPtr heap = IntPtr.Zero;
+ int devId = wolfcrypt.INVALID_DEVID;
+ byte[] privateKey;
+ byte[] publicKey;
+ byte[] message = Encoding.UTF8.GetBytes("This is some data to sign with ML-DSA");
+ byte[] signature;
+
+ try
+ {
+ Console.WriteLine("\nStarting " + type + " shared secret test ...");
+
+ /* Generate Key */
+ Console.WriteLine("Testing ML-DSA Key Generation...");
+ key = wolfcrypt.DilithiumMakeKey(heap, devId, type);
+ if (key == IntPtr.Zero)
+ {
+ ret = -1;
+ Console.Error.WriteLine("DilithiumMakeKey failed");
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-DSA Key Generation test passed.");
+ }
+
+ /* Export */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-DSA Key Export...");
+ ret = DilithiumExportPrivateKey(key, out privateKey);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("DilithiumExportPrivateKey failed");
+ }
+ }
+ if (ret == 0)
+ {
+ ret = DilithiumExportPublicKey(key, out publicKey);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("DilithiumExportPublicKey failed");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-DSA Key Export test passed.");
+ }
+
+ /* Import */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-DSA Key Import...");
+ ret = DilithiumImportPrivateKey(privateKey, key);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("DilithiumImportPrivateKey failed");
+ }
+ }
+ if (ret == 0)
+ {
+ ret = DilithiumImportPublicKey(publicKey, key);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("DilithiumImportPrivateKey failed");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-DSA Key Import test passed.");
+ }
+
+ /* Sign */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-DSA Signature Creation...");
+ ret = wolfcrypt.DilithiumSignMsg(key, message, out signature);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("DilithiumSign failed");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine($"ML-DSA Signature Creation test passed. Signature Length: {signature.Length}");
+ }
+
+ /* Verify */
+ if (ret == 0)
+ {
+ Console.WriteLine("Testing ML-DSA Signature Verification...");
+ ret = wolfcrypt.DilithiumVerifyMsg(key, message, signature);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("DilithiumVerify failed");
+ }
+ }
+ if (ret == 0)
+ {
+ Console.WriteLine("ML-DSA Signature Verification test passed.");
+ }
+ }
+ catch
+ {
+ // todo:
+ // ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386193630
+ // ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386194020
+ }
+ finally
+ {
+ if (key != IntPtr.Zero)
+ {
+ ret = wolfcrypt.DilithiumFreeKey(key);
+ if (ret != 0)
+ {
+ Console.Error.WriteLine("Failed to free Dilithium key. Error code: " + ret);
+ }
+ }
+ }
+
+ } /* END mldsa_test */
+
private static void aes_gcm_test()
{
IntPtr aes = IntPtr.Zero;
@@ -904,6 +1187,18 @@ public static void Main(string[] args)
curve25519_test(); /* curve25519 shared secret test */
+ Console.WriteLine("\nStarting ML-KEM test");
+
+ mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_512); /* ML-KEM test */
+ mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_768); /* ML-KEM test */
+ mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_1024); /* ML-KEM test */
+
+ Console.WriteLine("\nStarting ML-DSA test");
+
+ mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_44); /* ML-DSA test */
+ mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_65); /* ML-DSA test */
+ mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_87); /* ML-DSA test */
+
Console.WriteLine("\nStarting AES-GCM test");
aes_gcm_test(); /* AES_GCM test */
diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs
index 4f58139c25..4f0913f8ec 100644
--- a/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs
+++ b/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs
@@ -428,6 +428,147 @@ public class wolfcrypt
private extern static int wc_curve25519_export_private_raw(IntPtr key, IntPtr outPrivKey, IntPtr outPubKey);
#endif
+ /********************************
+ * ML-KEM
+ */
+#if WindowsCE
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_CipherTextSize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_SharedSecretSize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_PrivateKeySize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_PublicKeySize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern IntPtr wc_MlKemKey_New(int type, IntPtr heap, int devId);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_Delete(IntPtr key, ref IntPtr key_p);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_Init(IntPtr key, int type, IntPtr heap, int devId);
+ [DllImport(wolfssl_dll)]
+ private static extern void wc_MlKemKey_Free(IntPtr key);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_MakeKey(IntPtr key, IntPtr rng);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_MakeKeyWithRandom(IntPtr key, byte[] rand, int len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_EncodePublicKey(IntPtr key, byte[] output, uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_DecodePublicKey(IntPtr key, byte[] input, uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_Encapsulate(IntPtr key, byte[] ct, byte[] ss, IntPtr rng);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_EncapsulateWithRandom(IntPtr key, byte[] ct, byte[] ss, byte[] rand, int len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_Decapsulate(IntPtr key, byte[] ss, byte[] ct, uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_EncodePrivateKey(IntPtr key, byte[] output, uint len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlKemKey_DecodePrivateKey(IntPtr key, byte[] input, uint len);
+#else
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_CipherTextSize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_SharedSecretSize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_PrivateKeySize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_PublicKeySize(IntPtr key, ref uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern IntPtr wc_MlKemKey_New(int type, IntPtr heap, int devId);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_Delete(IntPtr key, ref IntPtr key_p);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_Init(IntPtr key, int type, IntPtr heap, int devId);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern void wc_MlKemKey_Free(IntPtr key);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_MakeKey(IntPtr key, IntPtr rng);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_MakeKeyWithRandom(IntPtr key, byte[] rand, int len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_EncodePublicKey(IntPtr key, byte[] output, uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_DecodePublicKey(IntPtr key, byte[] input, uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_Encapsulate(IntPtr key, byte[] ct, byte[] ss, IntPtr rng);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_EncapsulateWithRandom(IntPtr key, byte[] ct, byte[] ss, byte[] rand, int len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_Decapsulate(IntPtr key, byte[] ss, byte[] ct, uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_EncodePrivateKey(IntPtr key, byte[] output, uint len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlKemKey_DecodePrivateKey(IntPtr key, byte[] input, uint len);
+#endif
+
+ /********************************
+ * ML-DSA
+ */
+#if WindowsCE
+ [DllImport(wolfssl_dll)]
+ private static extern IntPtr wc_dilithium_new(IntPtr heap, int devId);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_delete(IntPtr key, ref IntPtr key_p);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_init_ex(IntPtr key, IntPtr heap, int devId);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_set_level(IntPtr key, byte level);
+ [DllImport(wolfssl_dll)]
+ private static extern void wc_dilithium_free(IntPtr key);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_make_key(IntPtr key, IntPtr rng);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_export_private(IntPtr key, byte[] output, ref uint outLen);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_import_private(byte[] priv, uint privSz, IntPtr key);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_export_public(IntPtr key, byte[] output, ref uint outLen);
+ [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);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_dilithium_verify_msg(byte[] sig, uint sigLen, 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)]
+ private static extern int wc_MlDsaKey_GetPubLen(IntPtr key, ref int len);
+ [DllImport(wolfssl_dll)]
+ private static extern int wc_MlDsaKey_GetSigLen(IntPtr key, ref int len);
+#else
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern IntPtr wc_dilithium_new(IntPtr heap, int devId);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_dilithium_delete(IntPtr key, ref IntPtr key_p);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_dilithium_init_ex(IntPtr key, IntPtr heap, int devId);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_dilithium_set_level(IntPtr key, byte level);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern void wc_dilithium_free(IntPtr key);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_dilithium_make_key(IntPtr key, IntPtr rng);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_dilithium_export_private(IntPtr key, byte[] output, ref uint outLen);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_dilithium_import_private(byte[] priv, uint privSz, IntPtr key);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_dilithium_export_public(IntPtr key, byte[] output, ref uint outLen);
+ [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);
+ [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);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlDsaKey_GetPrivLen(IntPtr key, ref int len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlDsaKey_GetPubLen(IntPtr key, ref int len);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wc_MlDsaKey_GetSigLen(IntPtr key, ref int len);
+#endif
/********************************
* AES-GCM
@@ -2709,6 +2850,710 @@ public static void Curve25519ExportKeyRaw(IntPtr key, out byte[] privateKey, out
/* END RAW Curve25519 */
+ /***********************************************************************
+ * ML-KEM
+ **********************************************************************/
+
+ // These APIs work by adding several options to wolfCrypt.
+ // Please refer to `../user_settings.h`.
+
+ ///
+ /// Create a new ML-KEM key pair and initialize it with random values
+ ///
+ /// ML-KEM parameter set type
+ /// Heap pointer for memory allocation
+ /// Device ID (if applicable)
+ /// Pointer to the MlKem key structure, or IntPtr.Zero on failure
+ public static IntPtr MlKemMakeKey(MlKemTypes type, IntPtr heap, int devId)
+ {
+ int ret = 0;
+ IntPtr key = IntPtr.Zero;
+ IntPtr rng = IntPtr.Zero;
+ bool success = false;
+
+ try
+ {
+ key = wc_MlKemKey_New((int)type, heap, devId);
+ if (key == IntPtr.Zero)
+ {
+ log(ERROR_LOG, "Failed to allocate or initialize MlKem key.");
+ return IntPtr.Zero;
+ }
+
+ rng = RandomNew();
+ if (rng == IntPtr.Zero)
+ {
+ log(ERROR_LOG, "Failed to create RNG for MlKem key.");
+ return IntPtr.Zero;
+ }
+
+ ret = wc_MlKemKey_MakeKey(key, rng);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to make MlKem key. Error code: " + ret);
+ return IntPtr.Zero;
+ }
+
+ success = true;
+ return key;
+ }
+ catch (Exception ex)
+ {
+ log(ERROR_LOG, "MlKem key creation exception: " + ex.ToString());
+ return IntPtr.Zero;
+ }
+ finally
+ {
+ if (rng != IntPtr.Zero)
+ {
+ RandomFree(rng);
+ }
+ if (!success && key != IntPtr.Zero)
+ {
+ ret = MlKemFreeKey(key);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to free MlKem key. Error code: " + ret);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Free a MlKem key structure and release its memory
+ ///
+ /// Pointer to the MlKem key structure
+ /// 0 on success, negative value on error.
+ public static int MlKemFreeKey(IntPtr key)
+ {
+ int ret = 0;
+ IntPtr heap = IntPtr.Zero;
+
+ if (key != IntPtr.Zero)
+ {
+ ret = wc_MlKemKey_Delete(key, ref heap);
+ key = IntPtr.Zero;
+ }
+ return ret;
+ }
+
+ ///
+ /// Encode the ML-KEM public key to a byte array.
+ ///
+ /// Pointer to the MlKem key structure.
+ /// Output byte array containing the encoded public key.
+ /// 0 on success, negative value on error.
+ public static int MlKemEncodePublicKey(IntPtr key, out byte[] publicKey)
+ {
+ publicKey = null;
+ int ret = 0;
+ uint pubLen = 0;
+
+ if (key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlKemKey_PublicKeySize(key, ref pubLen);
+ if (pubLen == 0)
+ {
+ log(ERROR_LOG, "Failed to get MlKem public key length. Error code: " + ret);
+ return ret;
+ }
+
+ publicKey = new byte[pubLen];
+ ret = wc_MlKemKey_EncodePublicKey(key, publicKey, pubLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to encode MlKem public key. Error code: " + ret);
+ publicKey = null;
+ return ret;
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "MlKem encode public key exception: " + e.ToString());
+ publicKey = null;
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Encode the ML-KEM private key to a byte array.
+ ///
+ /// Pointer to the MlKem key structure.
+ /// Output byte array containing the encoded private key.
+ /// 0 on success, negative value on error.
+ public static int MlKemEncodePrivateKey(IntPtr key, out byte[] privateKey)
+ {
+ privateKey = null;
+ int ret = 0;
+ uint privLen = 0;
+
+ if (key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlKemKey_PrivateKeySize(key, ref privLen);
+ if (ret !=0 || privLen == 0)
+ {
+ log(ERROR_LOG, "Failed to get MlKem private key length. Error code: " + ret);
+ return ret;
+ }
+
+ privateKey = new byte[privLen];
+ ret = wc_MlKemKey_EncodePrivateKey(key, privateKey, privLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to encode MlKem private key. Error code: " + ret);
+ privateKey = null;
+ return ret;
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "MlKem encode private key exception: " + e.ToString());
+ privateKey = null;
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Decode a ML-KEM public key from a byte array.
+ ///
+ /// Pointer to the MlKem key structure.
+ /// Encoded public key as byte array.
+ /// 0 on success, negative value on error.
+ public static int MlKemDecodePublicKey(IntPtr key, byte[] publicKey)
+ {
+ int ret = 0;
+ uint pubLen = 0;
+
+ if (key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlKemKey_PublicKeySize(key, ref pubLen);
+ if (ret != 0 || pubLen == 0)
+ {
+ log(ERROR_LOG, "Failed to get MlKem public key length. Error code: " + ret);
+ return ret;
+ }
+
+ ret = wc_MlKemKey_DecodePublicKey(key, publicKey, pubLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to decode MlKem public key. Error code: " + ret);
+ return ret;
+ }
+ }
+ catch (Exception ex)
+ {
+ log(ERROR_LOG, "MlKem decode public key exception: " + ex.ToString());
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Decode a ML-KEM private key from a byte array.
+ ///
+ /// Pointer to the MlKem key structure.
+ /// Encoded private key as byte array.
+ /// 0 on success, negative value on error.
+ public static int MlKemDecodePrivateKey(IntPtr key, byte[] privateKey)
+ {
+ int ret = 0;
+ uint privLen = 0;
+
+ if (key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlKemKey_PrivateKeySize(key, ref privLen);
+ if (privLen == 0)
+ {
+ log(ERROR_LOG, "Failed to get MlKem private key length. Error code: " + ret);
+ return ret;
+ }
+
+ ret = wc_MlKemKey_DecodePrivateKey(key, privateKey, privLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to decode MlKem private key. Error code: " + ret);
+ return ret;
+ }
+ }
+ catch (Exception ex)
+ {
+ log(ERROR_LOG, "MlKem decode private key exception: " + ex.ToString());
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Perform ML-KEM encapsulation to generate a ciphertext and shared secret
+ ///
+ /// Pointer to the MlKem key structure
+ /// Output buffer for the ciphertext
+ /// Output buffer for the shared secret
+ /// 0 on success, otherwise an error code
+ public static int MlKemEncapsulate(IntPtr key, out byte[] ct, out byte[] ss)
+ {
+ int ret;
+ ct = null;
+ ss = null;
+ uint ctLen = 0;
+ uint ssLen = 0;
+ IntPtr rng;
+
+ if (key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlKemKey_CipherTextSize(key, ref ctLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to determine ciphertext length. Error code: " + ret);
+ return ret;
+ }
+ ret = wc_MlKemKey_SharedSecretSize(key, ref ssLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to determine shared secret length. Error code: " + ret);
+ return ret;
+ }
+
+ ct = new byte[ctLen];
+ ss = new byte[ssLen];
+ rng = RandomNew();
+ ret = wc_MlKemKey_Encapsulate(key, ct, ss, rng);
+ RandomFree(rng);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to encapsulate MlKem key. Error code: " + ret);
+ return ret;
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "MlKem encapsulate exception: " + e.ToString());
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Perform ML-KEM decapsulation to recover the shared secret from ciphertext
+ ///
+ /// Pointer to the MlKem key structure
+ /// Ciphertext buffer
+ /// Output buffer for the shared secret
+ /// 0 on success, otherwise an error code
+ public static int MlKemDecapsulate(IntPtr key, byte[] ct, out byte[] ss)
+ {
+ int ret;
+ ss = null;
+ uint ssLen = 0;
+
+ if (key == IntPtr.Zero || ct == null)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlKemKey_SharedSecretSize(key, ref ssLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to determine shared secret length. Error code: " + ret);
+ return ret;
+ }
+ ss = new byte[ssLen];
+ ret = wc_MlKemKey_Decapsulate(key, ss, ct, (uint)ct.Length);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to decapsulate MlKem key. Error code: " + ret);
+ return ret;
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "MlKem decapsulate exception: " + e.ToString());
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ /********************************
+ * ENUMS
+ */
+ public enum MlKemTypes
+ {
+ ML_KEM_512 = 0,
+ ML_KEM_768 = 1,
+ ML_KEM_1024 = 2
+ }
+ /* END ML-KEM */
+
+
+ /***********************************************************************
+ * ML-DSA
+ **********************************************************************/
+
+ // These APIs work by adding several options to wolfCrypt.
+ // Please refer to `../user_settings.h`.
+
+ ///
+ /// Create a new Dilithium key pair and initialize it with random values
+ ///
+ /// Heap pointer for memory allocation
+ /// Device ID (if applicable)
+ /// Dilithium security level
+ /// Pointer to the Dilithium key structure, or IntPtr.Zero on failure
+ public static IntPtr DilithiumMakeKey(IntPtr heap, int devId, MlDsaTypes type)
+ {
+ IntPtr key = IntPtr.Zero;
+ IntPtr rng = IntPtr.Zero;
+ int ret;
+ bool success = false;
+
+ try
+ {
+ key = wc_dilithium_new(heap, devId);
+ if (key == IntPtr.Zero)
+ {
+ log(ERROR_LOG, "Failed to allocate and initialize Dilithium key.");
+ return IntPtr.Zero;
+ }
+
+ ret = wc_dilithium_set_level(key, (byte)type);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to set Dilithium level. Error code: " + ret);
+ return IntPtr.Zero;
+ }
+
+ rng = RandomNew();
+ if (rng == IntPtr.Zero)
+ {
+ log(ERROR_LOG, "Failed to create RNG for Dilithium key.");
+ return IntPtr.Zero;
+ }
+
+ ret = wc_dilithium_make_key(key, rng);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to make Dilithium key. Error code: " + ret);
+ return IntPtr.Zero;
+ }
+
+ success = true;
+ return key;
+ }
+ catch (Exception ex)
+ {
+ log(ERROR_LOG, "Dilithium key creation exception: " + ex.ToString());
+ return IntPtr.Zero;
+ }
+ finally
+ {
+ if (rng != IntPtr.Zero)
+ {
+ RandomFree(rng);
+ }
+ if (!success && key != IntPtr.Zero)
+ {
+ ret = DilithiumFreeKey(key);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to free Dilithium key. Error code: " + ret);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Free a Dilithium key structure and release its memory
+ ///
+ /// Pointer to the Dilithium key structure
+ /// 0 on success, negative value on error.
+ public static int DilithiumFreeKey(IntPtr key)
+ {
+ int ret = 0;
+ IntPtr heap = IntPtr.Zero;
+
+ if (key != IntPtr.Zero)
+ {
+ ret = wc_dilithium_delete(key, ref heap);
+ key = IntPtr.Zero;
+ }
+ return ret;
+ }
+
+ ///
+ /// Import a Dilithium public key from a byte array.
+ ///
+ /// Byte array containing the public key (big-endian).
+ /// Pointer to the Dilithium key structure (must be initialized).
+ /// 0 on success, negative value on error.
+ public static int DilithiumImportPublicKey(byte[] publicKey, IntPtr key)
+ {
+ if (publicKey == null || key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ return wc_dilithium_import_public(publicKey, (uint)publicKey.Length, key);
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "Dilithium import public key exception: " + e.ToString());
+ return EXCEPTION_E;
+ }
+ }
+
+ ///
+ /// Import a Dilithium private key from a byte array.
+ ///
+ /// Byte array containing the private key.
+ /// Pointer to the Dilithium key structure (must be initialized and have level set).
+ /// 0 on success, negative value on error.
+ public static int DilithiumImportPrivateKey(byte[] privateKey, IntPtr key)
+ {
+ if (privateKey == null || key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ return wc_dilithium_import_private(privateKey, (uint)privateKey.Length, key);
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "Dilithium import private key exception: " + e.ToString());
+ return EXCEPTION_E;
+ }
+ }
+
+ ///
+ /// Export a Dilithium private key to a byte array.
+ ///
+ /// Pointer to the Dilithium key structure.
+ /// Output byte array containing the private key.
+ /// 0 on success, negative value on error.
+ public static int DilithiumExportPrivateKey(IntPtr key, out byte[] privateKey)
+ {
+ privateKey = null;
+ int ret = 0;
+ int privLen = 0;
+ uint outLen;
+
+ if (key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlDsaKey_GetPrivLen(key, ref privLen);
+ if (privLen == 0)
+ {
+ log(ERROR_LOG, "Failed to get Dilithium private key length. Error code: " + ret);
+ return ret;
+ }
+
+ privateKey = new byte[privLen];
+ outLen = (uint)privLen;
+ ret = wc_dilithium_export_private(key, privateKey, ref outLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to export Dilithium private key. Error code: " + ret);
+ privateKey = null;
+ return ret;
+ }
+ if (outLen != privLen)
+ {
+ Array.Resize(ref privateKey, (int)outLen);
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "Dilithium export private key exception: " + e.ToString());
+ privateKey = null;
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Export a Dilithium public key to a byte array.
+ ///
+ /// Pointer to the Dilithium key structure.
+ /// Output byte array containing the public key.
+ /// 0 on success, negative value on error.
+ public static int DilithiumExportPublicKey(IntPtr key, out byte[] publicKey)
+ {
+ publicKey = null;
+ int ret = 0;
+ int pubLen = 0;
+ uint outLen;
+
+ if (key == IntPtr.Zero)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlDsaKey_GetPubLen(key, ref pubLen);
+ if (pubLen <= 0)
+ {
+ log(ERROR_LOG, "Failed to get Dilithium public key length. Error code: " + ret);
+ return ret;
+ }
+
+ publicKey = new byte[pubLen];
+ outLen = (uint)pubLen;
+ ret = wc_dilithium_export_public(key, publicKey, ref outLen);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to export Dilithium public key. Error code: " + ret);
+ publicKey = null;
+ return ret;
+ }
+ if (outLen != (uint)pubLen)
+ {
+ Array.Resize(ref publicKey, (int)outLen);
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "Dilithium export public key exception: " + e.ToString());
+ publicKey = null;
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Sign a message using a Dilithium private key
+ ///
+ /// Pointer to the Dilithium key structure
+ /// Message to sign
+ /// Output byte array for the signature
+ /// 0 on success, otherwise an error code
+ public static int DilithiumSignMsg(IntPtr key, byte[] msg, out byte[] sig)
+ {
+ int ret;
+ int sigLen = 0;
+ uint outLen;
+ sig = null;
+ IntPtr rng;
+
+ if (key == IntPtr.Zero || msg == null)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_MlDsaKey_GetSigLen(key, ref sigLen);
+ if (sigLen <= 0)
+ {
+ log(ERROR_LOG, "Failed to get Dilithium signature length. Error code: " + ret);
+ return ret;
+ }
+
+ sig = new byte[sigLen];
+ outLen = (uint)sigLen;
+ rng = RandomNew();
+ ret = wc_dilithium_sign_msg(msg, (uint)msg.Length, sig, ref outLen, key, rng);
+ RandomFree(rng);
+ if (ret != 0)
+ {
+ log(ERROR_LOG, "Failed to sign message with Dilithium key. Error code: " + ret);
+ return ret;
+ }
+ if (outLen != (uint)sigLen)
+ {
+ Array.Resize(ref sig, (int)outLen);
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "Dilithium sign message exception: " + e.ToString());
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ ///
+ /// Verify a Dilithium signature
+ ///
+ /// Pointer to the Dilithium key structure
+ /// Message that was signed
+ /// Signature to verify
+ /// 0 if the signature is valid, otherwise an error code
+ public static int DilithiumVerifyMsg(IntPtr key, byte[] msg, byte[] sig)
+ {
+ int ret;
+ int res = 0;
+
+ if (key == IntPtr.Zero || msg == null || sig == null)
+ {
+ return BAD_FUNC_ARG;
+ }
+
+ try
+ {
+ ret = wc_dilithium_verify_msg(sig, (uint)sig.Length, msg, (uint)msg.Length, ref res, key);
+ if (res != 1)
+ {
+ log(ERROR_LOG, "Failed to verify message with Dilithium key. Error code: " + ret);
+ return ret;
+ }
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "Dilithium verify message exception: " + e.ToString());
+ return EXCEPTION_E;
+ }
+ return SUCCESS;
+ }
+
+ /********************************
+ * ENUMS
+ */
+ public enum MlDsaTypes
+ {
+ ML_DSA_44 = 2,
+ ML_DSA_65 = 3,
+ ML_DSA_87 = 5
+ }
+ /* END ML-DSA */
+
+
/***********************************************************************
* AES-GCM
**********************************************************************/
diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs
index 0ee293f2f5..56c9502468 100644
--- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs
+++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs
@@ -509,6 +509,8 @@ public void free()
private extern static int wolfSSL_shutdown(IntPtr ssl);
[DllImport(wolfssl_dll)]
private extern static void wolfSSL_free(IntPtr ssl);
+ [DllImport(wolfssl_dll)]
+ private static extern int wolfSSL_UseKeyShare(IntPtr ssl, ushort group);
#else
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr wolfSSL_new(IntPtr ctx);
@@ -524,6 +526,8 @@ public void free()
private extern static int wolfSSL_shutdown(IntPtr ssl);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static void wolfSSL_free(IntPtr ssl);
+ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int wolfSSL_UseKeyShare(IntPtr ssl, ushort group);
#endif
/********************************
@@ -709,6 +713,90 @@ public void free()
public static readonly int WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE = 0x00000010;
public static readonly int WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS = WOLFSSL_LOAD_FLAG_NONE;
+ /* from ssl.h */
+ public enum NamedGroup
+ {
+ WOLFSSL_NAMED_GROUP_INVALID = 0,
+
+ WOLFSSL_ECC_SECP160K1 = 15,
+ WOLFSSL_ECC_SECP160R1 = 16,
+ WOLFSSL_ECC_SECP160R2 = 17,
+ WOLFSSL_ECC_SECP192K1 = 18,
+ WOLFSSL_ECC_SECP192R1 = 19,
+ WOLFSSL_ECC_SECP224K1 = 20,
+ WOLFSSL_ECC_SECP224R1 = 21,
+ WOLFSSL_ECC_SECP256K1 = 22,
+ WOLFSSL_ECC_SECP256R1 = 23,
+ WOLFSSL_ECC_SECP384R1 = 24,
+ WOLFSSL_ECC_SECP521R1 = 25,
+ WOLFSSL_ECC_BRAINPOOLP256R1 = 26,
+ WOLFSSL_ECC_BRAINPOOLP384R1 = 27,
+ WOLFSSL_ECC_BRAINPOOLP512R1 = 28,
+ WOLFSSL_ECC_X25519 = 29,
+ WOLFSSL_ECC_X448 = 30,
+ WOLFSSL_ECC_SM2P256V1 = 41,
+ WOLFSSL_ECC_MAX = 41,
+ WOLFSSL_ECC_MAX_AVAIL = 46,
+ /* Update use of disabled curves when adding value greater than 46. */
+
+ WOLFSSL_FFDHE_START = 256,
+ WOLFSSL_FFDHE_2048 = 256,
+ WOLFSSL_FFDHE_3072 = 257,
+ WOLFSSL_FFDHE_4096 = 258,
+ WOLFSSL_FFDHE_6144 = 259,
+ WOLFSSL_FFDHE_8192 = 260,
+ WOLFSSL_FFDHE_END = 511,
+
+ /* Old code points to keep compatibility with MlKem Round 3.
+ * Taken from OQS's openssl provider, see:
+ * https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/
+ * oqs-kem-info.md
+ */
+ WOLFSSL_MlKem_LEVEL1 = 570, /* MlKem_512 */
+ WOLFSSL_MlKem_LEVEL3 = 572, /* MlKem_572 */
+ WOLFSSL_MlKem_LEVEL5 = 573, /* MlKem_573 */
+
+ WOLFSSL_P256_MlKem_LEVEL1 = 12090,
+ WOLFSSL_P384_MlKem_LEVEL3 = 12092,
+ WOLFSSL_P521_MlKem_LEVEL5 = 12093,
+ WOLFSSL_X25519_MlKem_LEVEL1 = 12089,
+ WOLFSSL_X448_MlKem_LEVEL3 = 12176,
+ WOLFSSL_X25519_MlKem_LEVEL3 = 25497,
+ WOLFSSL_P256_MlKem_LEVEL3 = 25498,
+
+ /* Taken from draft-connolly-tls-mlkem-key-agreement, see:
+ * https://github.com/dconnolly/draft-connolly-tls-mlkem-key-agreement/
+ */
+ WOLFSSL_ML_KEM_512 = 512,
+ WOLFSSL_ML_KEM_768 = 513,
+ WOLFSSL_ML_KEM_1024 = 514,
+
+ /* Taken from draft-kwiatkowski-tls-ecdhe-mlkem. see:
+ * https://github.com/post-quantum-cryptography/
+ * draft-kwiatkowski-tls-ecdhe-mlkem/
+ */
+ WOLFSSL_P256_ML_KEM_768 = 4587,
+ WOLFSSL_X25519_ML_KEM_768 = 4588,
+ WOLFSSL_P384_ML_KEM_1024 = 4589,
+
+ /* Taken from OQS's openssl provider, see:
+ * https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/
+ * oqs-kem-info.md
+ */
+ WOLFSSL_P256_ML_KEM_512_OLD = 12103,
+ WOLFSSL_P384_ML_KEM_768_OLD = 12104,
+ WOLFSSL_P521_ML_KEM_1024_OLD = 12105,
+
+ WOLFSSL_P256_ML_KEM_512 = 12107,
+ WOLFSSL_P384_ML_KEM_768 = 12108,
+ WOLFSSL_P521_ML_KEM_1024 = 12109,
+ WOLFSSL_X25519_ML_KEM_512 = 12214,
+ WOLFSSL_X448_ML_KEM_768 = 12215,
+
+ WOLF_ENUM_DUMMY_LAST_ELEMENT = 0
+ }
+
+
private static IntPtr unwrap_ctx(IntPtr ctx)
{
@@ -1288,6 +1376,36 @@ public static int shutdown(IntPtr ssl)
}
+ ///
+ /// Creates a key share entry for the specified group on the given SSL/TLS connection.
+ ///
+ /// Pointer to the SSL structure to use.
+ /// The key exchange group identifier to use for key share (e.g., TLS supported group ID).
+ /// 1 on success
+ public static int UseKeyShare(IntPtr ssl, NamedGroup group)
+ {
+ if (ssl == IntPtr.Zero)
+ {
+ return FAILURE;
+ }
+ try
+ {
+ IntPtr sslCtx = unwrap_ssl(ssl);
+ if (sslCtx == IntPtr.Zero)
+ {
+ log(ERROR_LOG, "UseKeyShare ssl unwrap error");
+ return FAILURE;
+ }
+ return wolfSSL_UseKeyShare(sslCtx, (ushort)group);
+ }
+ catch (Exception e)
+ {
+ log(ERROR_LOG, "wolfSSL_UseKeyShare error " + e.ToString());
+ return FAILURE;
+ }
+ }
+
+
///
/// Optional, can be used to set a custom receive function
///