pycrypto / pycrypto

The Python Cryptography Toolkit
https://www.pycrypto.org/
Other
2.45k stars 636 forks source link

AES.MODE_OFB should not require multiple of 16 in length #187

Open msoulier opened 8 years ago

msoulier commented 8 years ago

http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf

Section 6.4, page 14.

"For the last block, which may be a partial block of u bits, the most significant u bits of the last output block are used for the exclusive-OR operation; the remaining b-u bits of the last output block are discarded. "

So why is 16 byte multiple input required?

(pycrypt)msoulier@merlin:~$ pip freeze pycrypto==2.6.1

$ python
Python 2.7.10 (default, Oct 23 2015, 18:05:06)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> from Crypto.Cipher import AES
>>> import hashlib
>>> b = hashlib.sha1('password')
>>> key = b.digest()
>>> len(key)
20
>>> mode = AES.MODE_OFB
>>> IV = 'NoAEbTP0sjSJ6TzMTB0K5A=='
>>> IV = base64.b64decode(IV)
>>> encryptor = AES.new(key[:16], mode, IV)
>>> plaintext = 'mybigsecret'
>>> ciphertext = encryptor.encrypt(plaintext)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/msoulier/envs/pycrypt/lib/python2.7/site-packages/Crypto/Cipher/blockalgo.py", line 244, in encrypt
    return self._cipher.encrypt(plaintext)
ValueError: Input strings must be a multiple of 16 in length
MartyMacGyver commented 8 years ago

I just stumbled upon this bug in 2.6.1 - turns out it was first reported 4 years ago:

https://bugs.launchpad.net/pycrypto/+bug/996193

While this is clearly a fixed bug in the codebase, the fix (and a host of other fixes and updates since 2.6.1) have not been released yet:

https://github.com/dlitz/pycrypto/commit/af9b41cc4b0a58dd87f56e334a8d478f238f074d

I rebuilt this package from source, pip uninstalled 2.6.1 and installed the one I built. It works normally now.