<div dir="ltr">A few thoughts:<div><br></div><div>a) I don't like each call to update() returning data, it seems like it should all be buffered in the cipher and then returned at the end.</div><div><br></div><div>b) I assume it raises an error if you try to do anything after finalization?</div>
<div><br></div><div>c) I think params like a MAC should just be added to __init__ for ciphers which need them</div><div><br></div><div>d) I don't have any ideas about specifying encrypt vs. decrypt.</div><div><br></div>
<div>Alex</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Aug 7, 2013 at 3:16 PM, Donald Stufft <span dir="ltr"><<a href="mailto:donald@stufft.io" target="_blank">donald@stufft.io</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">So to kick things off I'd like to get AES-GCM exposed and figured it could be a good way to start the ball rolling for figuring out how we want to expose symmetric ciphers at the low level API.<br>

<br>
I'm thinking cryptography.primitives.aes which has classes named like AES128GCM, AES256CBC, etc. The obvious naming scheme being AlgorithmKeysizeMode.<br>
<br>
classes look something like<br>
<br>
class AES128GCM:<br>
<br>
    # Information about the Cipher<br>
    authenticated = True<br>
    block_size = 128<br>
<br>
    def __init__(self, key, iv, …)<br>
<br>
    def update(self, plaintext)  # Updates an internal buffer as well as returns the encrypted chunk of data<br>
<br>
    def finalize(self)  # Updates the internal buffer witth finalized data and returns the same finalized data<br>
<br>
<br>
Some open questions:<br>
<br>
A lot of these are going to be block ciphers, do we want to do padding for people or expect them to hand us chunks of the correct block size?<br>
<br>
How do we decrypt vs encrypt. I think that:<br>
<br>
    cipher = AES128GCM(key, iv)<br>
    enciphered = cipher.update(plaintext) + cipher.finalize()<br>
<br>
    cipher = AES128GCM(key, iv)<br>
    plaintext = cipher.update(enciphered) + cipher.finalize()<br>
<br>
Makes a decent API here, but we need a way to make a decryption vs encryption cipher. Possibly something like encrypt=True, or decrypt=True (specifying both being an error)?<br>
<br>
Some ciphers (AES-GCM included) are authenticated and thus return (and require giving) a MAC in order to authenticate it, some authenticated ciphers also support the ability to pass along unencrypted but still authenticated data as well. I can't think of a decent way of doing this besides just adding functions (or __init__ args) to pass this data in, does anyone else have any ideas?<br>

<br>
Any other thoughts? I'm just spitballing here so let's see what we can come up with!<br>
<br>
<br>
-----------------<br>
Donald Stufft<br>
PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA<br>
<br>
<br>_______________________________________________<br>
Cryptography-dev mailing list<br>
<a href="mailto:Cryptography-dev@python.org">Cryptography-dev@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/cryptography-dev" target="_blank">http://mail.python.org/mailman/listinfo/cryptography-dev</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div dir="ltr">"I disapprove of what you say, but I will defend to the death your right to say it." -- Evelyn Beatrice Hall (summarizing Voltaire)<br>
"The people's good is the highest law." -- Cicero<br><div>GPG Key fingerprint: 125F 5C67 DFE9 4084</div></div>
</div>