diff options
author | vnugent <public@vaughnnugent.com> | 2024-10-18 22:10:17 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2024-10-18 22:10:17 -0400 |
commit | 44044eb0fb28b774773e3284fd147c91d59d64e3 (patch) | |
tree | 429860e6ced91b02b7062f86c74120be5d5f0c11 /wrappers/dotnet/VNLib.Utils.Cryptography.Noscrypt/src/Encryption | |
parent | 6a4a464d9fdc7821cd5c5695656a3fe385497cc5 (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; } } |