[Cryptography-dev] Low level API for Symmetric Encryption
Alex Gaynor
alex.gaynor at gmail.com
Thu Aug 8 00:56:49 CEST 2013
Sounds sane, I guess for primitives we really don't have to include
buffering. You can always do SomeClass(cipher) which adds buffering on top.
Alex
On Wed, Aug 7, 2013 at 3:55 PM, Donald Stufft <donald at stufft.io> wrote:
> Using an Unauthenticated cipher to remove the distraction of the MAC and
> AAD.
>
> cipher = AES128CBC(key, iv)
> enciphered = "".join(cipher.encrypt(chunk) for chunk in CHUNKS) +
> cipher.finalize()
>
> cipher = AES128CBC(key, iv)
> plaintext = "".join(cipher.decrypt(chunk) for chunk in
> make_chunks(enciphered)) + cipher.finalize()
>
> There is no internal buffer.
>
> If you do
>
> cipher = AES128CBC(key, iv)
> cipher.encrypt(data)
> cipher.decrypt(enciphered)
>
> You'll get an error calling decrypt() because the first call to encrypt()
> toggled the cipher into "encryption mode". And if you call either of them
> after it's been finalized you'll get an error because it's been finalized.
>
>
> On Aug 7, 2013, at 6:41 PM, Alex Gaynor <alex.gaynor at gmail.com> wrote:
>
> I'm not sure I totally follow what you said, can you show an example of
> using such an API?
>
> Alex
>
>
> On Wed, Aug 7, 2013 at 3:40 PM, Donald Stufft <donald at stufft.io> wrote:
>
>>
>> On Aug 7, 2013, at 6:31 PM, Alex Gaynor <alex.gaynor at gmail.com> wrote:
>>
>>
>>
>>
>> On Wed, Aug 7, 2013 at 3:27 PM, Donald Stufft <donald at stufft.io> wrote:
>>
>>>
>>> On Aug 7, 2013, at 6:21 PM, Alex Gaynor <alex.gaynor at gmail.com> wrote:
>>>
>>> A few thoughts:
>>>
>>> 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.
>>>
>>>
>>> The idea behind returning data is it enables the ability to stream the
>>> cipher (albeit at whatever the block size is for block ciphers). If you
>>> just buffer it and return it at the end then you can't really do that. Like
>>> a list comprehension vs an generator.
>>>
>>>
>> Different API then? I think most people assume update() won't return
>> anything (also they'll do bufferring slowly with stuff like += on bytes).
>>
>>
>> Yea we probably need two separate API's now that I think about it,
>> because you likely want to either do streaming OR internal buffering. As
>> suggested if I was trying to stream 50GB of data through encryption I'd be
>> pretty upset if it was getting stored in an internal buffer chewing up 50Gb
>> worth of ram by the time we're done.
>>
>> The other option is to just always have the api take data in, operate on
>> it, and return data and never worry about doing any internal buffering.
>> Probably need a different name than update though.
>>
>> This might be a bad idea but we could do ``decrypt()`` and ``encrypt()``
>> which function as above (take data in, operate on it, return it) and
>> whichever one you call first sets the encrypt vs decrypt flag on that
>> instance (so calling one and than the other would be an error).
>>
>>
>>
>>>
>>> b) I assume it raises an error if you try to do anything after
>>> finalization?
>>>
>>>
>>> That'd make the most sense I think, the other alternative is garbage but
>>> I think that's bad.
>>>
>>>
>> Garbage bad.
>>
>>
>>>
>>> c) I think params like a MAC should just be added to __init__ for
>>> ciphers which need them
>>>
>>>
>>> Well for instance for AES-GCM when encrypting you wouldn't add anything
>>> to __init__, you'd just need a way to fetch the MAC data that you can use
>>> to authenticate the ciphertext. When decrypting you need a way to pass the
>>> MAC data in so it can be authenticated (so this could use __init__).
>>>
>>> The same sort of thing exists for authenticated plaintext too, when
>>> encrypting you need to pass it in, when decrypting you get it back out.
>>>
>>
>> Yeah I think passing MAC on decrypt to __init__, and a method to get the
>> mac makes the most sense (or have finalize return a tuple?).
>>
>>
>>>
>>>
>>> d) I don't have any ideas about specifying encrypt vs. decrypt.
>>>
>>> Alex
>>>
>>>
>>> On Wed, Aug 7, 2013 at 3:16 PM, Donald Stufft <donald at stufft.io> wrote:
>>>
>>>> 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.
>>>>
>>>> I'm thinking cryptography.primitives.aes which has classes named like
>>>> AES128GCM, AES256CBC, etc. The obvious naming scheme being
>>>> AlgorithmKeysizeMode.
>>>>
>>>> classes look something like
>>>>
>>>> class AES128GCM:
>>>>
>>>> # Information about the Cipher
>>>> authenticated = True
>>>> block_size = 128
>>>>
>>>> def __init__(self, key, iv, …)
>>>>
>>>> def update(self, plaintext) # Updates an internal buffer as well
>>>> as returns the encrypted chunk of data
>>>>
>>>> def finalize(self) # Updates the internal buffer witth finalized
>>>> data and returns the same finalized data
>>>>
>>>>
>>>> Some open questions:
>>>>
>>>> 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?
>>>>
>>>> How do we decrypt vs encrypt. I think that:
>>>>
>>>> cipher = AES128GCM(key, iv)
>>>> enciphered = cipher.update(plaintext) + cipher.finalize()
>>>>
>>>> cipher = AES128GCM(key, iv)
>>>> plaintext = cipher.update(enciphered) + cipher.finalize()
>>>>
>>>> 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)?
>>>>
>>>> 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?
>>>>
>>>> Any other thoughts? I'm just spitballing here so let's see what we can
>>>> come up with!
>>>>
>>>>
>>>> -----------------
>>>> Donald Stufft
>>>> PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372
>>>> DCFA
>>>>
>>>>
>>>> _______________________________________________
>>>> Cryptography-dev mailing list
>>>> Cryptography-dev at python.org
>>>> http://mail.python.org/mailman/listinfo/cryptography-dev
>>>>
>>>>
>>>
>>>
>>> --
>>> "I disapprove of what you say, but I will defend to the death your right
>>> to say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
>>> "The people's good is the highest law." -- Cicero
>>> GPG Key fingerprint: 125F 5C67 DFE9 4084
>>> _______________________________________________
>>> Cryptography-dev mailing list
>>> Cryptography-dev at python.org
>>> http://mail.python.org/mailman/listinfo/cryptography-dev
>>>
>>>
>>>
>>> -----------------
>>> Donald Stufft
>>> PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372
>>> DCFA
>>>
>>>
>>> _______________________________________________
>>> Cryptography-dev mailing list
>>> Cryptography-dev at python.org
>>> http://mail.python.org/mailman/listinfo/cryptography-dev
>>>
>>>
>>
>>
>> --
>> "I disapprove of what you say, but I will defend to the death your right
>> to say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
>> "The people's good is the highest law." -- Cicero
>> GPG Key fingerprint: 125F 5C67 DFE9 4084
>> _______________________________________________
>> Cryptography-dev mailing list
>> Cryptography-dev at python.org
>> http://mail.python.org/mailman/listinfo/cryptography-dev
>>
>>
>>
>> -----------------
>> Donald Stufft
>> PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372
>> DCFA
>>
>>
>> _______________________________________________
>> Cryptography-dev mailing list
>> Cryptography-dev at python.org
>> http://mail.python.org/mailman/listinfo/cryptography-dev
>>
>>
>
>
> --
> "I disapprove of what you say, but I will defend to the death your right
> to say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
> "The people's good is the highest law." -- Cicero
> GPG Key fingerprint: 125F 5C67 DFE9 4084
> _______________________________________________
> Cryptography-dev mailing list
> Cryptography-dev at python.org
> http://mail.python.org/mailman/listinfo/cryptography-dev
>
>
>
> -----------------
> Donald Stufft
> PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372
> DCFA
>
>
> _______________________________________________
> Cryptography-dev mailing list
> Cryptography-dev at python.org
> http://mail.python.org/mailman/listinfo/cryptography-dev
>
>
--
"I disapprove of what you say, but I will defend to the death your right to
say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
"The people's good is the highest law." -- Cicero
GPG Key fingerprint: 125F 5C67 DFE9 4084
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cryptography-dev/attachments/20130807/f8c9bd7d/attachment.html>
More information about the Cryptography-dev
mailing list