diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2014-09-17 10:14:48 -0700 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2014-09-17 10:14:48 -0700 |
commit | 506f65b47f52377b0144669cfb41835762b25bb4 (patch) | |
tree | ffbb102fefa0297a145bb12d378d414fe8d1b0ad /cryptography | |
parent | 7a5629a718c787c671e0ed9573d0b8805758f660 (diff) | |
parent | 9a11c00b464225f4aa3e761e103930c6b8b9115b (diff) | |
download | cryptography-506f65b47f52377b0144669cfb41835762b25bb4.tar.gz cryptography-506f65b47f52377b0144669cfb41835762b25bb4.tar.bz2 cryptography-506f65b47f52377b0144669cfb41835762b25bb4.zip |
Merge pull request #1330 from reaperhulk/fix-commoncrypto-gcm
Fix two bugs with CommonCrypto GCM that can result in invalid output.
Diffstat (limited to 'cryptography')
-rw-r--r-- | cryptography/hazmat/backends/commoncrypto/ciphers.py | 12 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/ciphers.py | 8 |
2 files changed, 20 insertions, 0 deletions
diff --git a/cryptography/hazmat/backends/commoncrypto/ciphers.py b/cryptography/hazmat/backends/commoncrypto/ciphers.py index 525500c8..6d3ba863 100644 --- a/cryptography/hazmat/backends/commoncrypto/ciphers.py +++ b/cryptography/hazmat/backends/commoncrypto/ciphers.py @@ -151,6 +151,12 @@ class _GCMCipherContext(object): len(mode.initialization_vector) ) self._backend._check_cipher_response(res) + # CommonCrypto has a bug where calling update without at least one + # call to authenticate_additional_data will result in null byte output + # for ciphertext. The following empty byte string call prevents the + # issue, which is present in at least 10.8 and 10.9. + # Filed as rdar://18314544 + self.authenticate_additional_data(b"") def update(self, data): buf = self._backend._ffi.new("unsigned char[]", len(data)) @@ -164,6 +170,12 @@ class _GCMCipherContext(object): return self._backend._ffi.buffer(buf)[:] def finalize(self): + # CommonCrypto has a yet another bug where you must make at least one + # call to update. If you pass just AAD and call finalize without a call + # to update you'll get null bytes for tag. The following update call + # prevents this issue, which is present in at least 10.8 and 10.9. + # Filed as rdar://18314580 + self.update(b"") tag_size = self._cipher.block_size // 8 tag_buf = self._backend._ffi.new("unsigned char[]", tag_size) tag_len = self._backend._ffi.new("size_t *", tag_size) diff --git a/cryptography/hazmat/backends/openssl/ciphers.py b/cryptography/hazmat/backends/openssl/ciphers.py index c3a5499a..d37bb014 100644 --- a/cryptography/hazmat/backends/openssl/ciphers.py +++ b/cryptography/hazmat/backends/openssl/ciphers.py @@ -128,6 +128,14 @@ class _CipherContext(object): return self._backend._ffi.buffer(buf)[:outlen[0]] def finalize(self): + # OpenSSL 1.0.1 on Ubuntu 12.04 (and possibly other distributions) + # appears to have a bug where you must make at least one call to update + # even if you are only using authenticate_additional_data or the + # GCM tag will be wrong. An (empty) call to update resolves this + # and is harmless for all other versions of OpenSSL. + if isinstance(self._mode, GCM): + self.update(b"") + buf = self._backend._ffi.new("unsigned char[]", self._block_size) outlen = self._backend._ffi.new("int *") res = self._backend._lib.EVP_CipherFinal_ex(self._ctx, buf, outlen) |