aboutsummaryrefslogtreecommitdiff
path: root/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-10-18 22:10:17 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2024-10-18 22:10:17 -0400
commit44044eb0fb28b774773e3284fd147c91d59d64e3 (patch)
tree429860e6ced91b02b7062f86c74120be5d5f0c11 /wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption
parent6a4a464d9fdc7821cd5c5695656a3fe385497cc5 (diff)
refactor: Wire up unit testing and refactor c# api
Diffstat (limited to 'wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption')
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCCipherUtil.cs (renamed from wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCUtilCipher.cs)65
-rw-r--r--wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptMessageCipher.cs (renamed from wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptCipher.cs)63
2 files changed, 100 insertions, 28 deletions
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCUtilCipher.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCCipherUtil.cs
index 72bb75a..5dc2a94 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCUtilCipher.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NCCipherUtil.cs
@@ -15,20 +15,24 @@
using System;
using System.Diagnostics;
+using System.Runtime.InteropServices;
+
using VNLib.Utils.Cryptography.Noscrypt.@internal;
+using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
+
using NCResult = System.Int64;
namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
{
- internal static class NCUtilCipher
+ public unsafe static class NCCipherUtil
{
/*
* This class wraps the low-level cipher functions provided by
* the Noscrypt utility side-car library.
*/
- public static nint Alloc(NCContext ctx, uint version, uint flags)
+ internal static nint Alloc(NCContext ctx, uint version, uint flags)
{
nint cipher = GetTable(ctx).NCUtilCipherAlloc(version, flags);
@@ -43,7 +47,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return cipher;
}
- public static uint GetFlags(NCContext ctx, nint cipher)
+ internal static uint GetFlags(NCContext ctx, nint cipher)
{
NCResult result = GetTable(ctx).NCUtilCipherGetFlags(cipher);
@@ -52,9 +56,9 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return (uint)result;
}
- public static void Free(NCContext ctx, nint cipher) => GetTable(ctx).NCUtilCipherFree(cipher);
+ internal static void Free(NCContext ctx, nint cipher) => GetTable(ctx).NCUtilCipherFree(cipher);
- public static int GetIvSize(NCContext ctx, nint cipher)
+ internal static int GetIvSize(NCContext ctx, nint cipher)
{
NCResult result = GetTable(ctx).NCUtilCipherGetIvSize(cipher);
@@ -63,7 +67,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return checked((int)result);
}
- public static unsafe void SetProperty(NCContext ctx, nint cipher, uint property, ref readonly byte value, uint valueLen)
+ internal static void SetProperty(NCContext ctx, nint cipher, uint property, ref readonly byte value, uint valueLen)
{
fixed (byte* valPtr = &value)
{
@@ -73,7 +77,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
}
- public static uint GetOutputSize(NCContext ctx, nint cipher)
+ internal static uint GetOutputSize(NCContext ctx, nint cipher)
{
NCResult result = GetTable(ctx).NCUtilCipherGetOutputSize(cipher);
@@ -82,7 +86,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
return (uint)result;
}
- public static unsafe uint ReadOutput(NCContext ctx, nint cipher, ref byte outputData, uint outLen)
+ internal static uint ReadOutput(NCContext ctx, nint cipher, ref byte outputData, uint outLen)
{
fixed (byte* outPtr = &outputData)
{
@@ -94,14 +98,14 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
}
- public static unsafe void InitCipher(NCContext ctx, nint cipher, byte* inputPtr, uint inputSize)
+ internal static void InitCipher(NCContext ctx, nint cipher, byte* inputPtr, uint inputSize)
{
NCResult result = GetTable(ctx).NCUtilCipherInit(cipher, inputPtr, inputSize);
NCUtil.CheckResult<FunctionTable.NCUtilCipherInitDelegate>(result, raiseOnFailure: true);
}
- public static unsafe void Update(
+ internal static void Update(
NCContext ctx,
nint cipher,
ref readonly NCSecretKey localKey,
@@ -122,7 +126,46 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
}
- private static ref readonly FunctionTable GetTable(NCContext ctx) => ref ctx.Library.Functions;
+
+#if DEBUG
+ /*
+ * Conversation key is not meant to be a public api. Callers
+ * should use Encrypt/Decrypt methods to handle encryption.
+ *
+ * This method exists for vector testing purposes only.
+ */
+ public static void GetConverstationKey(
+ NCContext ctx,
+ ref readonly NCSecretKey localKey,
+ ref readonly NCPublicKey remoteKey,
+ Span<byte> conversationKeyOut32
+ )
+ {
+ ArgumentNullException.ThrowIfNull(ctx);
+ ArgumentOutOfRangeException.ThrowIfNotEqual(
+ conversationKeyOut32.Length,
+ NC_CONVERSATION_KEY_SIZE,
+ nameof(conversationKeyOut32)
+ );
+
+ fixed (NCSecretKey* sk = &localKey)
+ fixed (NCPublicKey* pk = &remoteKey)
+ fixed(byte* convKey32Ptr = &MemoryMarshal.GetReference(conversationKeyOut32))
+ {
+ NCResult result = GetTable(ctx).NCGetConversationKey(
+ ctx: ctx.DangerousGetHandle(),
+ sk,
+ pk,
+ convKey32Ptr
+ );
+
+ NCUtil.CheckResult<FunctionTable.NCUtilCipherInitDelegate>(result, raiseOnFailure: true);
+ }
+ }
+#endif
+
+ private static ref readonly FunctionTable GetTable(NCContext ctx)
+ => ref ctx.Library.Functions;
}
}
diff --git a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptCipher.cs b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptMessageCipher.cs
index b30ea44..e44addf 100644
--- a/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptCipher.cs
+++ b/wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption/NoscryptMessageCipher.cs
@@ -18,6 +18,8 @@ using System.Threading;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
using VNLib.Utils.Memory;
using VNLib.Utils.Cryptography.Noscrypt.Random;
using static VNLib.Utils.Cryptography.Noscrypt.NoscryptLibrary;
@@ -27,29 +29,54 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
/// <summary>
/// The noscrypt util cipher wapper
/// </summary>
- /// <param name="ctx"></param>
- /// <param name="flags">Cipher creation flags</param>
+ /// <param name="ctx">A reference to the library context object</param>
+ /// <param name="cipher">A pointer to an existing cipher context that this instance owns</param>
/// <param name="version">The cipher specification version</param>
- public sealed class NoscryptCipher(NCContext ctx, NoscryptCipherVersion version, NoscryptCipherFlags flags) : VnDisposeable
+ public class NoscryptMessageCipher : SafeHandleMinusOneIsInvalid
{
+ private readonly NCContext _context;
+ private readonly NoscryptCipherVersion _version;
private IMemoryHandle<byte>? _ivBuffer;
- private readonly nint _cipher = NCUtilCipher.Alloc(ctx, (uint)version, (uint)flags);
+
+ private NoscryptMessageCipher(NCContext ctx, nint cipher, NoscryptCipherVersion version)
+ : base(ownsHandle: true)
+ {
+ SetHandle(cipher);
+ _context = ctx;
+ _version = version;
+ }
+
+ /// <summary>
+ /// Allocates and initializes a new cipher instance using the specified
+ /// </summary>
+ /// <param name="context">A reference to the noscrypt library context</param>
+ /// <param name="version">The encryption standard to use</param>
+ /// <param name="flags">The raw cipher flags to the pass to the cipher initialization function</param>
+ /// <returns>A new <see cref="NoscryptMessageCipher"/> instance</returns>
+ public static NoscryptMessageCipher Create(NCContext context, NoscryptCipherVersion version, NoscryptCipherFlags flags)
+ {
+ return new(
+ context,
+ NCCipherUtil.Alloc(context, (uint)version, (uint)flags),
+ version
+ );
+ }
/// <summary>
/// The cipher standard version used by this instance
/// </summary>
- public NoscryptCipherVersion Version => version;
+ public NoscryptCipherVersion Version => _version;
/// <summary>
/// Gets the flags set for the cipher instance
/// </summary>
- public uint GetFlags() => NCUtilCipher.GetFlags(ctx, _cipher);
+ public uint GetFlags() => NCCipherUtil.GetFlags(_context, handle);
/// <summary>
/// Gets the cipher's initilaization vector size (or nonce)
/// </summary>
/// <returns>The size of the IV in bytes</returns>
- public int GetIvSize() => NCUtilCipher.GetIvSize(ctx, _cipher);
+ public int GetIvSize() => NCCipherUtil.GetIvSize(_context, handle);
/// <summary>
/// Gets the internal heap buffer that holds the cipher's initalization
@@ -121,9 +148,9 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
fixed (byte* inputPtr = &inputData)
{
- NCUtilCipher.InitCipher(ctx, _cipher, inputPtr, inputSize);
+ NCCipherUtil.InitCipher(_context, handle, inputPtr, inputSize);
- NCUtilCipher.Update(ctx, _cipher, in localKey, in remoteKey);
+ NCCipherUtil.Update(_context, handle, in localKey, in remoteKey);
}
}
@@ -153,7 +180,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
/// Gets the size of the output buffer required to read the cipher output
/// </summary>
/// <returns>The size of the output in bytes</returns>
- public int GetOutputSize() => checked((int)NCUtilCipher.GetOutputSize(ctx, _cipher));
+ public int GetOutputSize() => checked((int)NCCipherUtil.GetOutputSize(_context, handle));
/// <summary>
/// Reads the output data from the cipher into the specified buffer
@@ -166,7 +193,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
{
ArgumentOutOfRangeException.ThrowIfLessThan(size, GetOutputSize());
- return checked((int)NCUtilCipher.ReadOutput(ctx, _cipher, ref outputData, (uint)size));
+ return checked((int)NCCipherUtil.ReadOutput(_context, handle, ref outputData, (uint)size));
}
/// <summary>
@@ -186,7 +213,7 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
private IMemoryHandle<byte> AllocIvBuffer()
{
//Use the context heap to allocate the internal iv buffer
- MemoryHandle<byte> buffer = MemoryUtil.SafeAlloc<byte>(ctx.Heap, GetIvSize(), zero: true);
+ MemoryHandle<byte> buffer = MemoryUtil.SafeAlloc<byte>(_context.Heap, GetIvSize(), zero: true);
try
{
@@ -199,9 +226,9 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
* buffer is required so we don't need to pin managed memory
* nor worry about the GC moving the buffer.
*/
- NCUtilCipher.SetProperty(
- ctx,
- _cipher,
+ NCCipherUtil.SetProperty(
+ _context,
+ DangerousGetHandle(),
NC_ENC_SET_IV,
ref buffer.GetReference(),
(uint)buffer.Length
@@ -217,10 +244,12 @@ namespace VNLib.Utils.Cryptography.Noscrypt.Encryption
}
///<inheritdoc/>
- protected override void Free()
+ protected override bool ReleaseHandle()
{
- NCUtilCipher.Free(ctx, _cipher);
+ NCCipherUtil.Free(_context, handle);
_ivBuffer?.Dispose();
+
+ return true;
}
}