/// <summary> /// Creates a new randomly generated key. /// </summary> /// <returns>A new randomly generated key.</returns> public static XChaChaKey Generate() { Sodium.Initialize(); GuardedMemoryHandle.Alloc(KeyLengthBytes, out var handle); var keySpan = handle.DangerousGetSpan(); crypto_secretstream_xchacha20poly1305_keygen(ref MemoryMarshal.GetReference(keySpan)); handle.MakeReadOnly(); return(new XChaChaKey(handle)); }
public static void Alloc(int length, out GuardedMemoryHandle handle) { handle = sodium_malloc((UIntPtr)length); handle.length = length; // GC.AddMemoryPressure informs the runtime of a large allocation of unmanaged memory that should be // taken into account when scheduling garbage collection. // 16 = length of the canary // 0x3FFF = 4 * dwPageSize (on Windows x64 dwPageSize is 0xFFF = 4096 bytes). // Sodium rounds (length + dwPageSize) down to the nearest dwPageSize, and then adds 3 * dwPageSize extra. // Thus (length + 16 + 0x3FFF) is initial amount to allocate and & ~(0xFFF) rounds down to the nearest dwPageSize GC.AddMemoryPressure((length + 16 + 0x3FFF) & ~0xFFF); }
/// <summary> /// Create a new instance from an existing key. /// </summary> /// <param name="key">The key.</param> public XChaChaKey(ReadOnlySpan <byte> key) { Sodium.Initialize(); if (key.Length != KeyLengthBytes) { throw new ArgumentException("key has invalid length", nameof(key)); } GuardedMemoryHandle.Alloc(KeyLengthBytes, out this.handle); this.handle.Write(key); this.handle.MakeReadOnly(); }
internal XChaChaStreamState() { GuardedMemoryHandle.Alloc(Length, out this.handle); }
public static extern int crypto_secretstream_xchacha20poly1305_push( GuardedMemoryHandle state, ref byte c, out UInt64 clen_p, in byte m,
public static extern int crypto_secretstream_xchacha20poly1305_init_push( GuardedMemoryHandle state, byte[] header, GuardedMemoryHandle k);
private XChaChaKey(GuardedMemoryHandle handle) { this.handle = handle; }