Skip to content

Commit 9c294aa

Browse files
authored
Merge pull request #126 from dorssel/improve_unsafe
Improve "unsafe" code
2 parents b7a3640 + 7bbb901 commit 9c294aa

File tree

3 files changed

+82
-82
lines changed

3 files changed

+82
-82
lines changed

UnitTests/Internal.UnitTests/OpaqueStructuresTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace Internal.UnitTests;
88

99
[TestClass]
10-
sealed unsafe class OpaqueStructuresTests
10+
sealed class OpaqueStructuresTests
1111
{
1212
[TestMethod]
1313
public void XMSS_SIGNING_CONTEXT_SIZE()

Xmss/Internal/Errors.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ static partial class UnsafeNativeMethods
1212
{
1313
[LibraryImport("xmss", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(ErrorStringMarshaller))]
1414
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
15-
internal static unsafe partial string xmss_error_to_name(XmssError error);
15+
internal static partial string xmss_error_to_name(XmssError error);
1616

1717
[LibraryImport("xmss", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(ErrorStringMarshaller))]
1818
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
19-
internal static unsafe partial string xmss_error_to_description(XmssError error);
19+
internal static partial string xmss_error_to_description(XmssError error);
2020
}

Xmss/Xmss.cs

Lines changed: 79 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -227,59 +227,56 @@ public void GeneratePrivateKey(IXmssStateManager stateManager, XmssParameterSet
227227

228228
XmssError result;
229229

230+
// Step 3: Create key.
231+
232+
using var keyContext = new CriticalXmssKeyContextHandle();
233+
using var signingContext = new CriticalXmssSigningContextHandle();
234+
using var privateKeyStatelessBlob = new CriticalXmssPrivateKeyStatelessBlobHandle();
235+
using var privateKeyStatefulBlob = new CriticalXmssPrivateKeyStatefulBlobHandle();
236+
230237
unsafe
231238
{
232-
// Step 3: Create key.
233-
234-
using var keyContext = new CriticalXmssKeyContextHandle();
235-
using var signingContext = new CriticalXmssSigningContextHandle();
236-
{
237-
result = UnsafeNativeMethods.xmss_context_initialize(ref signingContext.AsPointerRef(), (XmssParameterSetOID)parameterSet,
238-
&UnmanagedFunctions.Realloc, &UnmanagedFunctions.Free, &UnmanagedFunctions.Zeroize);
239-
XmssException.ThrowIfNotOkay(result);
240-
}
239+
result = UnsafeNativeMethods.xmss_context_initialize(ref signingContext.AsPointerRef(), (XmssParameterSetOID)parameterSet,
240+
&UnmanagedFunctions.Realloc, &UnmanagedFunctions.Free, &UnmanagedFunctions.Zeroize);
241+
XmssException.ThrowIfNotOkay(result);
241242

242-
using var privateKeyStatelessBlob = new CriticalXmssPrivateKeyStatelessBlobHandle();
243-
using var privateKeyStatefulBlob = new CriticalXmssPrivateKeyStatefulBlobHandle();
244-
{
245-
var allRandomPtr = stackalloc byte[96 + 32];
246-
var allRandom = new Span<byte>(allRandomPtr, 96 + 32);
243+
var allRandomPtr = stackalloc byte[96 + 32];
244+
var allRandom = new Span<byte>(allRandomPtr, 96 + 32);
247245

248-
RandomNumberGenerator.Fill(allRandom);
246+
RandomNumberGenerator.Fill(allRandom);
249247

250-
XmssBuffer secure_random = new() { data = allRandomPtr, data_size = 96 };
251-
XmssBuffer random = new() { data = allRandomPtr + 96, data_size = 32 };
248+
XmssBuffer secure_random = new() { data = allRandomPtr, data_size = 96 };
249+
XmssBuffer random = new() { data = allRandomPtr + 96, data_size = 32 };
252250

253-
result = UnsafeNativeMethods.xmss_generate_private_key(ref keyContext.AsPointerRef(), ref privateKeyStatelessBlob.AsPointerRef(),
254-
ref privateKeyStatefulBlob.AsPointerRef(), secure_random, enableIndexObfuscation
255-
? XmssIndexObfuscationSetting.XMSS_INDEX_OBFUSCATION_ON : XmssIndexObfuscationSetting.XMSS_INDEX_OBFUSCATION_OFF,
256-
random, signingContext.AsRef());
257-
XmssException.ThrowIfNotOkay(result);
251+
result = UnsafeNativeMethods.xmss_generate_private_key(ref keyContext.AsPointerRef(), ref privateKeyStatelessBlob.AsPointerRef(),
252+
ref privateKeyStatefulBlob.AsPointerRef(), secure_random, enableIndexObfuscation
253+
? XmssIndexObfuscationSetting.XMSS_INDEX_OBFUSCATION_ON : XmssIndexObfuscationSetting.XMSS_INDEX_OBFUSCATION_OFF,
254+
random, signingContext.AsRef());
255+
XmssException.ThrowIfNotOkay(result);
258256

259-
CryptographicOperations.ZeroMemory(allRandom);
260-
}
257+
CryptographicOperations.ZeroMemory(allRandom);
258+
}
261259

262-
// Step 4: Store state (failure erases any partial storage, then throws).
260+
// Step 4: Store state (failure erases any partial storage, then throws).
263261

264-
try
265-
{
266-
wrappedStateManager.Store(XmssKeyPart.PrivateStateless, privateKeyStatelessBlob.Data);
267-
wrappedStateManager.Store(XmssKeyPart.PrivateStateful, privateKeyStatefulBlob.Data);
268-
}
269-
catch (XmssStateManagerException ex)
270-
{
271-
wrappedStateManager.DeleteAllAfterFailure(ex);
272-
throw;
273-
}
262+
try
263+
{
264+
wrappedStateManager.Store(XmssKeyPart.PrivateStateless, privateKeyStatelessBlob.Data);
265+
wrappedStateManager.Store(XmssKeyPart.PrivateStateful, privateKeyStatefulBlob.Data);
266+
}
267+
catch (XmssStateManagerException ex)
268+
{
269+
wrappedStateManager.DeleteAllAfterFailure(ex);
270+
throw;
271+
}
274272

275-
// Step 5: Replace KeyContext.
273+
// Step 5: Replace KeyContext.
276274

277-
ResetState();
278-
ParameterSet = parameterSet;
279-
PrivateKey = new(wrappedStateManager);
280-
PrivateKey.KeyContext.SwapWith(keyContext);
281-
PrivateKey.StatefulBlob.SwapWith(privateKeyStatefulBlob);
282-
}
275+
ResetState();
276+
ParameterSet = parameterSet;
277+
PrivateKey = new(wrappedStateManager);
278+
PrivateKey.KeyContext.SwapWith(keyContext);
279+
PrivateKey.StatefulBlob.SwapWith(privateKeyStatefulBlob);
283280
}
284281

285282
/// <summary>
@@ -296,62 +293,66 @@ public void ImportPrivateKey(IXmssStateManager stateManager)
296293

297294
XmssError result;
298295

299-
unsafe
296+
using var privateKeyStatefulBlob = CriticalXmssPrivateKeyStatefulBlobHandle.Alloc();
297+
using var privateKeyStatelessBlob = CriticalXmssPrivateKeyStatelessBlobHandle.Alloc();
298+
wrappedStateManager.Load(XmssKeyPart.PrivateStateless, privateKeyStatelessBlob.Data);
299+
wrappedStateManager.Load(XmssKeyPart.PrivateStateful, privateKeyStatefulBlob.Data);
300+
301+
foreach (var oid in Enum.GetValues<XmssParameterSetOID>())
300302
{
301-
using var privateKeyStatefulBlob = CriticalXmssPrivateKeyStatefulBlobHandle.Alloc();
302-
using var privateKeyStatelessBlob = CriticalXmssPrivateKeyStatelessBlobHandle.Alloc();
303-
wrappedStateManager.Load(XmssKeyPart.PrivateStateless, privateKeyStatelessBlob.Data);
304-
wrappedStateManager.Load(XmssKeyPart.PrivateStateful, privateKeyStatefulBlob.Data);
303+
using var keyContext = new CriticalXmssKeyContextHandle();
304+
using var signingContext = new CriticalXmssSigningContextHandle();
305305

306-
foreach (var oid in Enum.GetValues<XmssParameterSetOID>())
306+
unsafe
307307
{
308-
using var keyContext = new CriticalXmssKeyContextHandle();
309-
using var signingContext = new CriticalXmssSigningContextHandle();
310308
result = UnsafeNativeMethods.xmss_context_initialize(ref signingContext.AsPointerRef(), oid,
311309
&UnmanagedFunctions.Realloc, &UnmanagedFunctions.Free, &UnmanagedFunctions.Zeroize);
312310
XmssException.ThrowIfNotOkay(result);
313311

314312
result = UnsafeNativeMethods.xmss_load_private_key(ref keyContext.AsPointerRef(),
315313
privateKeyStatelessBlob.AsRef(), privateKeyStatefulBlob.AsRef(), signingContext.AsRef());
316-
if (result == XmssError.XMSS_OKAY)
314+
}
315+
if (result == XmssError.XMSS_OKAY)
316+
{
317+
ResetState();
318+
ParameterSet = (XmssParameterSet)oid;
319+
PrivateKey = new(wrappedStateManager);
320+
PrivateKey.KeyContext.SwapWith(keyContext);
321+
PrivateKey.StatefulBlob.SwapWith(privateKeyStatefulBlob);
322+
323+
// Now try to load the internal public key part, but failure is not fatal.
324+
try
317325
{
318-
ResetState();
319-
ParameterSet = (XmssParameterSet)oid;
320-
PrivateKey = new(wrappedStateManager);
321-
PrivateKey.KeyContext.SwapWith(keyContext);
322-
PrivateKey.StatefulBlob.SwapWith(privateKeyStatefulBlob);
323-
324-
// Now try to load the internal public key part, but failure is not fatal.
325326
try
326327
{
327-
try
328+
using var publicKeyInternalBlob = CriticalXmssPublicKeyInternalBlobHandle.Alloc(XmssCacheType.XMSS_CACHE_TOP, 0,
329+
ParameterSet);
330+
wrappedStateManager.Load(XmssKeyPart.Public, publicKeyInternalBlob.Data);
331+
332+
unsafe
328333
{
329-
using var publicKeyInternalBlob = CriticalXmssPublicKeyInternalBlobHandle.Alloc(XmssCacheType.XMSS_CACHE_TOP, 0,
330-
ParameterSet);
331-
wrappedStateManager.Load(XmssKeyPart.Public, publicKeyInternalBlob.Data);
332334
// The cache will be automatically freed with the key context; we don't need it.
333335
XmssInternalCache* cache = null;
334336
result = UnsafeNativeMethods.xmss_load_public_key(ref cache, ref PrivateKey.KeyContext.AsRef(),
335337
publicKeyInternalBlob.AsRef());
336338
XmssException.ThrowIfNotOkay(result);
337-
338-
result = UnsafeNativeMethods.xmss_export_public_key(out PublicKey, PrivateKey.KeyContext.AsRef());
339-
XmssException.ThrowIfNotOkay(result);
340-
HasPublicKey = true;
341-
}
342-
catch (Exception ex)
343-
{
344-
throw new IgnoreException(ex);
345339
}
340+
result = UnsafeNativeMethods.xmss_export_public_key(out PublicKey, PrivateKey.KeyContext.AsRef());
341+
XmssException.ThrowIfNotOkay(result);
342+
HasPublicKey = true;
343+
}
344+
catch (Exception ex)
345+
{
346+
throw new IgnoreException(ex);
346347
}
347-
catch (IgnoreException) { }
348-
return;
349348
}
350-
}
349+
catch (IgnoreException) { }
351350

352-
// None of the OIDs worked.
353-
throw new XmssException(XmssError.XMSS_ERR_INVALID_BLOB);
351+
return;
352+
}
354353
}
354+
// None of the OIDs worked.
355+
throw new XmssException(XmssError.XMSS_ERR_INVALID_BLOB);
355356
}
356357

357358
/// <summary>
@@ -598,11 +599,10 @@ Task OptionalDelayTask()
598599
result = UnsafeNativeMethods.xmss_finish_calculate_public_key(ref publicKeyInternalBlob.AsPointerRef(),
599600
ref keyGenerationContext.AsPointerRef(), ref PrivateKey.KeyContext.AsRef());
600601
XmssException.ThrowIfNotOkay(result);
601-
602-
result = UnsafeNativeMethods.xmss_export_public_key(out PublicKey, PrivateKey.KeyContext.AsRef());
603-
XmssException.ThrowIfNotOkay(result);
604-
HasPublicKey = true;
605602
}
603+
result = UnsafeNativeMethods.xmss_export_public_key(out PublicKey, PrivateKey.KeyContext.AsRef());
604+
XmssException.ThrowIfNotOkay(result);
605+
HasPublicKey = true;
606606

607607
// NOTE: our KeyContext and StateManager are now out of sync, but that does not affect security (only the public part)
608608

0 commit comments

Comments
 (0)