> On 16 Jun 2016, at 09:19, Stefan Krah <ste...@bytereef.org> wrote:
> 
> This should only concern code that a) was specifically written for
> 3.5.0/3.5.1 and b) implements a serious cryptographic application
> in Python.
> 
> I think b) is not a good idea anyway due to timing and side channel
> attacks and the lack of secure wiping of memory. Such applications
> should be written in C, where one does not have to predict the
> behavior of multiple layers of abstractions.

No, it concerns code that generates its random numbers from Python. For 
example, you may want to use AES GCM to encrypt a file at rest. AES GCM 
requires the use of an nonce, and has only one rule about this nonce: you MUST 
NOT, under any circumstances, re-use an nonce/key combination. If you do, AES 
GCM fails catastrophically (I cannot emphasise this enough, re-using a 
nonce/key combination in AES GCM totally destroys all the properties the 
algorithm provides)[0].

You can use a C implementation of all of the AES logic, including offload to 
your x86 CPU with its fancy AES GCM instruction set. However, you *need* to 
provide an nonce: AES GCM can’t magically guess what it is, and it needs to be 
communicated in some way for the decryption[1]. In situations where you do not 
have an easily available nonce (you do have it for TLS, for example), you will 
need to provide one, and the logical and obvious thing to do is to use a random 
number. Your Python application needs to obtain that random number, and the 
safest way to do it is via os.urandom().

This is the problem with this argument: we cannot wave our hands and say 
“os.urandom can be as unsafe as we want because crypto code must not be written 
in Python”. Even if we never implement an algorithm in Python (and I agree with 
you that crypto primitives in general should not be implemented in Python for 
the exact reasons you suggest), most algorithms require the ability to be 
provided with good random numbers by their callers. As long as crypto 
algorithms require good nonces, Python needs access to a secure CSPRNG. Kernel 
CSPRNGs are *strongly* favoured for many reasons that I won’t go into here, so 
os.urandom is our winner.

python-dev cannot wash its hands of the security decision here. As I’ve said 
many times, I’m pleased to see the decision makers have not done that: while I 
don’t agree with their decision, I totally respect that it was theirs to make, 
and they made it with all of the facts.

Cory


[0]: Someone will *inevitably* point out that other algorithms resist nonce 
misuse somewhat better than this. While that’s true, it’s a) not relevant, 
because some standards require use of the non-NMR algorithms, and b) unhelpful, 
because even if we could switch, we’d need access to the better primitives, 
which we don’t have.

[1]: Again, to head off some questions at the pass: the reason nonces are 
usually provided by the user of the algorithm is that sometimes they’re 
generated semi-deterministically. For example, TLS generates a unique key for 
each session (again, requiring randomness, but that’s neither here nor there), 
and so TLS can use deterministic *but non-repeated* nonces, which in practice 
it derives from record numbers. Because you have two options (re-use keys with 
random nonces, or random keys with deterministic nonces), a generic algorithm 
implementation does not constrain your choice of nonce.

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to