Skip to content
This repository has been archived by the owner on Jan 27, 2022. It is now read-only.

Commit

Permalink
Throw exception when IV is used with ECB or CTR
Browse files Browse the repository at this point in the history
The IV parameter is currently ignored when initializing
a cipher in ECB or CTR mode.

For CTR mode, it is confusing: it takes some time to see
that a different parameter is needed (the counter).

For ECB mode, it is outright dangerous.

This patch forces an exception to be raised.
  • Loading branch information
Legrandin authored and dlitz committed Feb 22, 2014
1 parent 860523d commit 8dbe0dc
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
31 changes: 23 additions & 8 deletions lib/Crypto/SelfTest/Cipher/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,19 +605,34 @@ def shortDescription(self):
return """%s .decrypt() output of .encrypt() should not be garbled""" % (self.module_name,)

def runTest(self):
for mode in (self.module.MODE_ECB, self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB, self.module.MODE_OPENPGP):

## ECB mode
mode = self.module.MODE_ECB
encryption_cipher = self.module.new(a2b_hex(self.key), mode)
ciphertext = encryption_cipher.encrypt(self.plaintext)
decryption_cipher = self.module.new(a2b_hex(self.key), mode)
decrypted_plaintext = decryption_cipher.decrypt(ciphertext)
self.assertEqual(self.plaintext, decrypted_plaintext)

## OPENPGP mode
mode = self.module.MODE_OPENPGP
encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
eiv_ciphertext = encryption_cipher.encrypt(self.plaintext)
eiv = eiv_ciphertext[:self.module.block_size+2]
ciphertext = eiv_ciphertext[self.module.block_size+2:]
decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv)
decrypted_plaintext = decryption_cipher.decrypt(ciphertext)
self.assertEqual(self.plaintext, decrypted_plaintext)

## All other non-AEAD modes (but CTR)
for mode in (self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB):
encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
ciphertext = encryption_cipher.encrypt(self.plaintext)

if mode != self.module.MODE_OPENPGP:
decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
else:
eiv = ciphertext[:self.module.block_size+2]
ciphertext = ciphertext[self.module.block_size+2:]
decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv)
decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
decrypted_plaintext = decryption_cipher.decrypt(ciphertext)
self.assertEqual(self.plaintext, decrypted_plaintext)


class PGPTest(unittest.TestCase):
def __init__(self, module, params):
unittest.TestCase.__init__(self)
Expand Down
11 changes: 11 additions & 0 deletions src/block_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,17 @@ ALGnew(PyObject *self, PyObject *args, PyObject *kwdict)
"Key cannot be the null string");
return NULL;
}
if (IVlen != 0 && mode == MODE_ECB)
{
PyErr_Format(PyExc_ValueError, "ECB mode does not use IV");
return NULL;
}
if (IVlen != 0 && mode == MODE_CTR)
{
PyErr_Format(PyExc_ValueError,
"CTR mode needs counter parameter, not IV");
return NULL;
}
if (IVlen != BLOCK_SIZE && mode != MODE_ECB && mode != MODE_CTR)
{
PyErr_Format(PyExc_ValueError,
Expand Down

0 comments on commit 8dbe0dc

Please sign in to comment.