Commit | Line | Data |
---|---|---|
aa21c764 LF |
1 | Fix CVE-2013-7459: |
2 | ||
3 | https://github.com/dlitz/pycrypto/issues/176 | |
4 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-7459 | |
5 | ||
6 | Copied from Debian: | |
7 | ||
8 | https://anonscm.debian.org/cgit/collab-maint/python-crypto.git/commit/?id=0de2243837ed369a086f15c50cca2be85bdfab9d | |
9 | ||
10 | Debian adapts this upstream commit: | |
11 | ||
12 | https://github.com/dlitz/pycrypto/commit/8dbe0dc3eea5c689d4f76b37b93fe216cf1f00d4 | |
13 | ||
14 | From 8dbe0dc3eea5c689d4f76b37b93fe216cf1f00d4 Mon Sep 17 00:00:00 2001 | |
15 | From: Legrandin <helderijs@gmail.com> | |
16 | Date: Sun, 22 Dec 2013 22:24:46 +0100 | |
17 | Subject: [PATCH] Throw exception when IV is used with ECB or CTR | |
18 | ||
19 | The IV parameter is currently ignored when initializing | |
20 | a cipher in ECB or CTR mode. | |
21 | ||
22 | For CTR mode, it is confusing: it takes some time to see | |
23 | that a different parameter is needed (the counter). | |
24 | ||
25 | For ECB mode, it is outright dangerous. | |
26 | ||
27 | This patch forces an exception to be raised. | |
28 | --- | |
29 | lib/Crypto/SelfTest/Cipher/common.py | 31 +++++++++++++++++++++++-------- | |
30 | src/block_template.c | 11 +++++++++++ | |
31 | 2 files changed, 34 insertions(+), 8 deletions(-) | |
32 | ||
33 | --- a/lib/Crypto/SelfTest/Cipher/common.py | |
34 | +++ b/lib/Crypto/SelfTest/Cipher/common.py | |
35 | @@ -239,19 +239,34 @@ class RoundtripTest(unittest.TestCase): | |
36 | return """%s .decrypt() output of .encrypt() should not be garbled""" % (self.module_name,) | |
37 | ||
38 | def runTest(self): | |
39 | - for mode in (self.module.MODE_ECB, self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB, self.module.MODE_OPENPGP): | |
40 | + | |
41 | + ## ECB mode | |
42 | + mode = self.module.MODE_ECB | |
43 | + encryption_cipher = self.module.new(a2b_hex(self.key), mode) | |
44 | + ciphertext = encryption_cipher.encrypt(self.plaintext) | |
45 | + decryption_cipher = self.module.new(a2b_hex(self.key), mode) | |
46 | + decrypted_plaintext = decryption_cipher.decrypt(ciphertext) | |
47 | + self.assertEqual(self.plaintext, decrypted_plaintext) | |
48 | + | |
49 | + ## OPENPGP mode | |
50 | + mode = self.module.MODE_OPENPGP | |
51 | + encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) | |
52 | + eiv_ciphertext = encryption_cipher.encrypt(self.plaintext) | |
53 | + eiv = eiv_ciphertext[:self.module.block_size+2] | |
54 | + ciphertext = eiv_ciphertext[self.module.block_size+2:] | |
55 | + decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv) | |
56 | + decrypted_plaintext = decryption_cipher.decrypt(ciphertext) | |
57 | + self.assertEqual(self.plaintext, decrypted_plaintext) | |
58 | + | |
59 | + ## All other non-AEAD modes (but CTR) | |
60 | + for mode in (self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB): | |
61 | encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) | |
62 | ciphertext = encryption_cipher.encrypt(self.plaintext) | |
63 | - | |
64 | - if mode != self.module.MODE_OPENPGP: | |
65 | - decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) | |
66 | - else: | |
67 | - eiv = ciphertext[:self.module.block_size+2] | |
68 | - ciphertext = ciphertext[self.module.block_size+2:] | |
69 | - decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv) | |
70 | + decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) | |
71 | decrypted_plaintext = decryption_cipher.decrypt(ciphertext) | |
72 | self.assertEqual(self.plaintext, decrypted_plaintext) | |
73 | ||
74 | + | |
75 | class PGPTest(unittest.TestCase): | |
76 | def __init__(self, module, params): | |
77 | unittest.TestCase.__init__(self) | |
78 | --- a/src/block_template.c | |
79 | +++ b/src/block_template.c | |
80 | @@ -170,6 +170,17 @@ ALGnew(PyObject *self, PyObject *args, P | |
81 | "Key cannot be the null string"); | |
82 | return NULL; | |
83 | } | |
84 | + if (IVlen != 0 && mode == MODE_ECB) | |
85 | + { | |
86 | + PyErr_Format(PyExc_ValueError, "ECB mode does not use IV"); | |
87 | + return NULL; | |
88 | + } | |
89 | + if (IVlen != 0 && mode == MODE_CTR) | |
90 | + { | |
91 | + PyErr_Format(PyExc_ValueError, | |
92 | + "CTR mode needs counter parameter, not IV"); | |
93 | + return NULL; | |
94 | + } | |
95 | if (IVlen != BLOCK_SIZE && mode != MODE_ECB && mode != MODE_CTR) | |
96 | { | |
97 | PyErr_Format(PyExc_ValueError, |