/// <summary> /// Encrypts a message with an authentication tag and additional data. /// </summary> /// <param name="message">The message to be encrypted.</param> /// <param name="nonce">The 8 byte nonce.</param> /// <param name="key">The 32 byte key.</param> /// <param name="additionalData">The additional data; may be null, otherwise between 0 and 16 bytes.</param> /// <returns>The encrypted message with additional data.</returns> /// <remarks>The nonce should never ever be reused with the same key.</remarks> /// <remarks>The recommended way to generate it is to use GenerateNonce() for the first message, and increment it for each subsequent message using the same key.</remarks> /// <exception cref="KeyOutOfRangeException"></exception> /// <exception cref="NonceOutOfRangeException"></exception> /// <exception cref="AdditionalDataOutOfRangeException"></exception> /// <exception cref="CryptographicException"></exception> public ArraySegment <byte> Encrypt(ArraySegment <byte> message, byte[] nonce, byte[] key, ArraySegment <byte> additionalData = default) { //additionalData can be null if (additionalData.Array == null) { additionalData = new ArraySegment <byte>(Array.Empty <byte>()); } //validate the length of the key if (key == null || key.Length != KEYBYTES) { throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", KEYBYTES)); } //validate the length of the nonce if (nonce == null || nonce.Length != NPUBBYTES) { throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", NPUBBYTES)); } // //validate the length of the additionalData // if (additionalData.Length > ABYTES || additionalData.Length < 0) // throw new AdditionalDataOutOfRangeException( // string.Format("additionalData must be between {0} and {1} bytes in length.", 0, ABYTES)); long cipherLength; var hMsg = GCHandle.Alloc(message.Array, GCHandleType.Pinned); var hAData = GCHandle.Alloc(additionalData.Array, GCHandleType.Pinned); var msg = _bufferPool.Rent(message.Count + ABYTES); var hCipher = GCHandle.Alloc(msg, GCHandleType.Pinned); var ret = SodiumLibrary.crypto_aead_xchacha20poly1305_ietf_encrypt(hCipher.AddrOfPinnedObject(), out cipherLength, hMsg.AddrOfPinnedObject() + message.Offset, message.Count, hAData.AddrOfPinnedObject() + additionalData.Offset, additionalData.Count, null, nonce, key); hMsg.Free(); hAData.Free(); hCipher.Free(); if (ret != 0) { throw new CryptographicException("Error encrypting message."); } return(new ArraySegment <byte>(msg, 0, (int)cipherLength)); }
public SocketAsyncEventArgs Acquire(IActorRef actor) { var buffer = _bufferPool.Rent(); var e = new SocketAsyncEventArgs(); e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count); e.UserToken = actor; e.Completed += _onComplete; return(e); }
public static Memory <T> RentMemory <T>(this IBufferPool <T> bufferPool, int length) => bufferPool.Rent(length).AsMemory(0, length);
private static byte[] GetBuffer(int size) => BufferPool != null?BufferPool.Rent(size) : new byte[size];