We were getting this error on Python 3.2:
ERROR: runTest (Crypto.SelfTest.Hash.common.MACSelfTest)
CMAC #17: NIST SP 800 38B D.7 Example 17
----------------------------------------------------------------------
Traceback (most recent call last):
File "build/lib.linux-x86_64-3.2/Crypto/SelfTest/Hash/common.py", line 199, in runTest
self.assertRaises(ValueError, h.hexverify, "4556")
File "/home/dwon/py/pythons/python3.2/lib/python3.2/unittest/case.py", line 557, in assertRaises
callableObj(*args, **kwargs)
File "build/lib.linux-x86_64-3.2/Crypto/Hash/CMAC.py", line 323, in hexverify
self.verify(unhexlify(hex_mac_tag))
TypeError: 'str' does not support the buffer interface
The MAC unit tests assume that the MAC algorithm is
based on hash functions (HMAC).
Additionally, a single test vector is quite complex
in that it includes result for multiple tests (each
performed on the same data, but with different
hashes).
This patch simplifies the MAC unit test so that it does
not depend on hashes and a test vector is simply made up by:
* 1 input
* 1 result
* All parameters to pass to the new() function
[dlitz@dlitz.net: Replaced custom MacMismatchError with ValueError.]
[dlitz@dlitz.net: Replaced 'import *' with appropriate imports.]
[dlitz@dlitz.net: Whitespace fixed with "git rebase --whitespace=fix"]
In the current implementation, it is left up to the caller
to assess if the locally computed MAC matches the MAC associated
to the received message.
However, the most natural way to do that (use == operator)
is also deepy unsecure, see here:
http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf
With this patch, the new HMAC.verify() method accepts
the given MAC and perform the check on behalf of the caller.
The method will use constant-time code (still dependent on the length
of the MAC, but not on the actual content).
[dlitz@dlitz.net: Modified commit message subject line.]
[dlitz@dlitz.net: Whitespace fixed with "git rebase --whitespace=fix"]
The patch contains the following changes:
- Private RSA keys can be imported/exported in encrypted form,
protected according to PKCS#8 and:
* PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC.
* PBKDF2WithHMAC-SHA1AndAES128-CBC
* PBKDF2WithHMAC-SHA1AndAES192-CBC
* PBKDF2WithHMAC-SHA1AndAES256-CBC
In addition to that, it is possible to import keys i the
following weak formats:
* pbeWithMD5AndDES-CBC
* pbeWithSHA1AndRC2-CBC
* pbeWithMD5AndRC2-CBC
* pbeWithSHA1AndDES-CBC
- The following new module (and 1 new package) are added:
* Crypto.Util.Padding for simple padding/unpadding logic
* Crypto.IO._PBES for PBE-related PKCS#5 logic
* Crypto.IO.PEM for PEM wrapping/unwrapping
* Crypto.IO.PKCS8 for PKCS#8 wrapping/unwrapping
- All Object ID (OIDs) are now in dotted form to increase
readability.
- Add AES support to PEM format (decode only).
The PEM module can decrypt messages protected with AES-CBC.
- Update RSA import test cases.
- Updated to PKCS8 test cases
The pure Python wrappers around Crypto.Hash.* were convenient, but they
slowed down hash initialization by 4-7x.
There is a speed trade-off here: The MD5 and SHA1 objects are just
wrapped hashlib objects (or old-style md5/sha objects). To maintain API
compatibility with the rest of PyCrypto, we still have to wrap them, so
they're slower to initialize than the rest of the hash functions. If
hashlib ever adds a .new() method, we will automatically use hashlib
directly and gain the initialization speed-up.
In PyCrypto v2.5, the "oid" attribute was added to hash objects. In
retrospect, this was not a good idea, since the OID is not really a
property of the hash algorithm, it's a protocol-specific identifer for
the hash functions. PKCS#1 v1.5 uses it, but other protocols (e.g.
OpenPGP, DNSSEC, SSH, etc.) use different identifiers, and it doesn't make
sense to add these to Crypto.Hash.* every time a new algorithm is added.
This also has the benefit of being compatible with the Python standard
library's "hashlib" objects, which also have a name attribute.
(as submitted here https://bugs.launchpad.net/pycrypto/+bug/544792)
so that they are available also in Python 2.1, 2.2, 2.3 and 2.4.
Regardless where the implementation comes from (Python standard
library or our native modules, depending on the Python version),
all Crypto.Hash objects are always used as front-ends.
According to Jean-Paul Calderone at https://bugs.launchpad.net/pycrypto/+bug/785150:
`__builtins__` is an implementation detail of CPython. It takes on
inconsistent values at various times. The use in `common.py` happens to
work on recent version of CPython, but it doesn't work on PyPy. The only
thing you should ever do, when you're doing this sort of thing, is "import
__builtin__; __builtin__.foo".
o _fastmath now builds and runs on PY3K
o Changes to setup.py to allow /usr/include for gmp.h
o Changes to setup.py to allow linking fastmath w/ static mpir
on Windows without warning messages
o Changes to test_DSA/test_RSA to throw an exception if _fastmath
is present but cannot be imported (due to an issue building
_fastmath or the shared gmp/mpir libraries not being reachable)
o number.py has the code to flag a failing _fastmath, but that
code is commented out for a better runtime experience
o Clean up the if for py21compat import - should have been == not is
o Clean up some '== None' occurences, now 'is None' instead
In an attempt to simplify the copyright status of PyCrypto, I'm placing my
code into the public domain, and encouraging other contributors to do the
same.
I have used a public domain dedication that was recommended in a book on FOSS legal
issues[1], followed by the warranty disclaimer boilerplate from the MIT license.
[1] _Intellectual Property and Open Source: A Practical Guide to Protecting
Code_, a book written by Van Lindberg and published by O'Reilly Media.
(ISBN 978-0-596-51796-0)
This will avoid the previous situation where scripts like the old "test.py"
get included accidentally in a release. It also frees us to put additional
build scripts in the top-level directory of the source tree.