
On Tue, Jul 11, 2017 at 03:35:56PM +0100, David Turner wrote:
I can't think of a terribly good way to achieve GPG/PGP-compatibility without simply using GPG/PGP, since the file format is quite involved.
That said, here is how to implement a CBC-mode block cipher encryption using Conduit, which is suitable for something like AES256 encryption. It is almost certainly vulnerable to side-channel attacks (timing, cache-poisoning, etc) but as a pure function from input to output it is equivalent to `openssl aes-256-cbc -e -K <KEY-IN-HEX> -iv <IV-IN-HEX> -in data/plain-text.txt` which I should hope would be standard enough for analysis.
Just straight CBC lacks integrity protection. A MAC is still required, and usually one wants asymmetric key exchange, rather than a shared symmetric key. So in practice one wants something like CMS (successor to S/MIME). The OpenSSL cms(1) command can do clear signing, encryption, or both (in either order) by piping the output of one to the other. In many applications it is safer to encrypt then sign, rather than sign and then encrypt. Packetizing large input streams is well worth it, but while each "packet" can use any of a number of standar formats, some standards (notably CMS AFAIK) may lack support for packetizing large input streams. The OpenPGP standard does support breaking streams into "packets", so for large streams that may be optimal, you just need an OpenPGP library implementation that supports sensible packet sizes, and perhaps an FFI interface for Haskell. Alternatively, just a pipe to a CLI will do, bug the "gpg" CLI does not appear to support creating streams with more than one packet (Unless this happens implicitly for "large-enough" streams). -- Viktor.