Skip to content

Commit f6533c4

Browse files
committed
Further peer review fixes
1 parent 8617f00 commit f6533c4

2 files changed

Lines changed: 70 additions & 4 deletions

File tree

wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,23 @@ private static void hpke_test(wolfcrypt.HpkeKem kem,
996996
}
997997
Console.WriteLine("HPKE convenience overload test PASSED.");
998998

999+
/* Empty plaintext round-trip - native API accepts ptSz == 0 */
1000+
Console.WriteLine("Testing HpkeSealBase/OpenBase with empty plaintext...");
1001+
byte[] emptyPt = new byte[0];
1002+
byte[] encEmpty = wolfcrypt.HpkeSealBase(hpke, receiverKey,
1003+
info, aad, emptyPt, kem);
1004+
if (encEmpty == null)
1005+
{
1006+
throw new Exception("HpkeSealBase with empty plaintext failed");
1007+
}
1008+
byte[] decEmpty = wolfcrypt.HpkeOpenBase(hpke, receiverKey,
1009+
encEmpty, info, aad, kem);
1010+
if (decEmpty == null || decEmpty.Length != 0)
1011+
{
1012+
throw new Exception("HpkeOpenBase with empty plaintext: round-trip failed");
1013+
}
1014+
Console.WriteLine("Empty plaintext round-trip test PASSED.");
1015+
9991016
/* Negative test: tampered ciphertext should fail */
10001017
Console.WriteLine("Testing HpkeOpenBase with tampered ciphertext...");
10011018
byte[] tampered = (byte[])encCiphertext.Clone();

wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
*/
2121

2222
using System;
23+
using System.Collections.Generic;
24+
#if !WindowsCE
2325
using System.Collections.Concurrent;
26+
#endif
2427
using System.Runtime.InteropServices;
2528
using System.Security.Cryptography;
2629
using System.Text;
@@ -3289,9 +3292,53 @@ private struct HpkeContextState
32893292
public IntPtr rng;
32903293
public HpkeKem kem;
32913294
}
3295+
3296+
#if WindowsCE
3297+
/* .NET Compact Framework / Windows CE does not provide
3298+
* System.Collections.Concurrent, so fall back to a plain Dictionary
3299+
* guarded by an explicit lock. */
3300+
private static readonly Dictionary<IntPtr, HpkeContextState> hpkeContexts =
3301+
new Dictionary<IntPtr, HpkeContextState>();
3302+
private static readonly object hpkeContextsLock = new object();
3303+
3304+
private static void HpkeContextStore(IntPtr hpke, HpkeContextState state)
3305+
{
3306+
lock (hpkeContextsLock) { hpkeContexts[hpke] = state; }
3307+
}
3308+
private static bool HpkeContextTryGet(IntPtr hpke, out HpkeContextState state)
3309+
{
3310+
lock (hpkeContextsLock) { return hpkeContexts.TryGetValue(hpke, out state); }
3311+
}
3312+
private static bool HpkeContextTryRemove(IntPtr hpke, out HpkeContextState state)
3313+
{
3314+
lock (hpkeContextsLock)
3315+
{
3316+
if (hpkeContexts.TryGetValue(hpke, out state))
3317+
{
3318+
hpkeContexts.Remove(hpke);
3319+
return true;
3320+
}
3321+
return false;
3322+
}
3323+
}
3324+
#else
32923325
private static readonly ConcurrentDictionary<IntPtr, HpkeContextState> hpkeContexts =
32933326
new ConcurrentDictionary<IntPtr, HpkeContextState>();
32943327

3328+
private static void HpkeContextStore(IntPtr hpke, HpkeContextState state)
3329+
{
3330+
hpkeContexts[hpke] = state;
3331+
}
3332+
private static bool HpkeContextTryGet(IntPtr hpke, out HpkeContextState state)
3333+
{
3334+
return hpkeContexts.TryGetValue(hpke, out state);
3335+
}
3336+
private static bool HpkeContextTryRemove(IntPtr hpke, out HpkeContextState state)
3337+
{
3338+
return hpkeContexts.TryRemove(hpke, out state);
3339+
}
3340+
#endif
3341+
32953342
/// <summary>
32963343
/// Get the enc (encapsulated key) length for a given KEM
32973344
/// </summary>
@@ -3355,7 +3402,7 @@ public static IntPtr HpkeInit(HpkeKem kem, HpkeKdf kdf, HpkeAead aead)
33553402
return IntPtr.Zero;
33563403
}
33573404

3358-
hpkeContexts[hpke] = new HpkeContextState { rng = rng, kem = kem };
3405+
HpkeContextStore(hpke, new HpkeContextState { rng = rng, kem = kem });
33593406
}
33603407
catch (Exception e)
33613408
{
@@ -3392,7 +3439,7 @@ public static IntPtr HpkeGenerateKeyPair(IntPtr hpke)
33923439
}
33933440

33943441
HpkeContextState state;
3395-
if (!hpkeContexts.TryGetValue(hpke, out state) || state.rng == IntPtr.Zero)
3442+
if (!HpkeContextTryGet(hpke, out state) || state.rng == IntPtr.Zero)
33963443
{
33973444
log(ERROR_LOG, "HPKE generate keypair: no RNG associated with context");
33983445
return IntPtr.Zero;
@@ -3527,7 +3574,7 @@ public static void HpkeFree(IntPtr hpke)
35273574
if (hpke != IntPtr.Zero)
35283575
{
35293576
HpkeContextState state;
3530-
if (hpkeContexts.TryRemove(hpke, out state) && state.rng != IntPtr.Zero)
3577+
if (HpkeContextTryRemove(hpke, out state) && state.rng != IntPtr.Zero)
35313578
{
35323579
RandomFree(state.rng);
35333580
}
@@ -3558,7 +3605,9 @@ public static byte[] HpkeSealBase(IntPtr hpke, IntPtr ephemeralKey, IntPtr recei
35583605
log(ERROR_LOG, "HPKE seal base: invalid parameter");
35593606
return null;
35603607
}
3561-
if (plaintext == null || plaintext.Length == 0)
3608+
/* Native wc_HpkeSealBase only requires plaintext to be non-NULL;
3609+
* ptSz == 0 is valid (output is just the AEAD tag). */
3610+
if (plaintext == null)
35623611
{
35633612
log(ERROR_LOG, "HPKE seal base: invalid plaintext");
35643613
return null;

0 commit comments

Comments
 (0)