/// <summary> /// Calls EVP_SealInit() and EVP_SealFinal() /// </summary> /// <param name="pkeys"></param> /// <param name="input"></param> /// <returns></returns> public Envelope Seal(CryptoKey[] pkeys, byte[] input) { Envelope env = new Envelope(); var ptrs = new IntPtr[pkeys.Length]; try { env.Keys = new byte[pkeys.Length][]; IntPtr[] pubkeys = new IntPtr[pkeys.Length]; int[] ekeylens = new int[pkeys.Length]; for (int i = 0; i < pkeys.Length; i++) { ptrs[i] = Marshal.AllocHGlobal(pkeys[i].Size); pubkeys[i] = pkeys[i].Handle; } if (this.Cipher.IVLength > 0) { env.IV = new byte[this.Cipher.IVLength]; } Native.ExpectSuccess(Native.EVP_SealInit( this.ptr, this.Cipher.Handle, ptrs, ekeylens, env.IV, pubkeys, pubkeys.Length)); for (int i = 0; i < pkeys.Length; i++) { env.Keys[i] = new byte[ekeylens[i]]; Marshal.Copy(ptrs[i], env.Keys[i], 0, ekeylens[i]); } MemoryStream memory = new MemoryStream(); byte[] output = new byte[input.Length + this.Cipher.BlockSize]; int len; Native.ExpectSuccess(Native.EVP_EncryptUpdate(this.ptr, output, out len, input, input.Length)); memory.Write(output, 0, len); Native.ExpectSuccess(Native.EVP_SealFinal(this.ptr, output, out len)); memory.Write(output, 0, len); env.Data = memory.ToArray(); return env; } finally { foreach (var ptr in ptrs) { Marshal.FreeHGlobal(ptr); } } }
/// <summary> /// Calls EVP_SealInit() and EVP_SealFinal() /// </summary> /// <param name="pkeys"></param> /// <param name="needsIV"></param> /// <returns></returns> public Envelope Seal(CryptoKey[] pkeys, bool needsIV) { Envelope ret = new Envelope(); byte[][] bufs = new byte[pkeys.Length][]; int[] lens = new int[pkeys.Length]; IntPtr[] pubkeys = new IntPtr[pkeys.Length]; ret.Keys = new ArraySegment<byte>[pkeys.Length]; for (int i = 0; i < pkeys.Length; ++i) { bufs[i] = new byte[pkeys[i].Size]; lens[i] = pkeys[i].Size; pubkeys[i] = pkeys[i].Handle; } if(needsIV) ret.IV = new byte[this.cipher.IVLength]; int len; Native.ExpectSuccess(Native.EVP_SealInit( this.ptr, this.cipher.Handle, bufs, lens, ret.IV, pubkeys, pubkeys.Length)); for (int i = 0; i < pkeys.Length; ++i) { ret.Keys[i] = new ArraySegment<byte>(bufs[i], 0, lens[i]); } Native.ExpectSuccess(Native.EVP_SealFinal(this.ptr, null, out len)); ret.Data = new byte[len]; Native.ExpectSuccess(Native.EVP_SealFinal(this.ptr, ret.Data, out len)); return ret; }