diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2013-11-15 11:17:36 -0800 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2013-11-15 11:17:36 -0800 |
commit | 4a6f5dcddef1b9a3afbe8cc47b7483e3589781fe (patch) | |
tree | 0dee301ad68348c834bbe1e25c8d7f652667a438 | |
parent | c65204eddf4cb029343c586a8c849b4ace67b25e (diff) | |
download | cryptography-4a6f5dcddef1b9a3afbe8cc47b7483e3589781fe.tar.gz cryptography-4a6f5dcddef1b9a3afbe8cc47b7483e3589781fe.tar.bz2 cryptography-4a6f5dcddef1b9a3afbe8cc47b7483e3589781fe.zip |
Move all unpadding logic to C
-rw-r--r-- | cryptography/hazmat/primitives/padding.py | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/cryptography/hazmat/primitives/padding.py b/cryptography/hazmat/primitives/padding.py index 34bdfd89..ec575195 100644 --- a/cryptography/hazmat/primitives/padding.py +++ b/cryptography/hazmat/primitives/padding.py @@ -21,9 +21,11 @@ from cryptography.hazmat.primitives import interfaces _ffi = cffi.FFI() _ffi.cdef(""" -unsigned int Cryptography_constant_time_lt(unsigned int, unsigned int); +bool Cryptography_check_padding(uint8_t *, unsigned int); """) _lib = _ffi.verify(""" +#include <stdbool.h> + /* Returns the value of the input with the most-significant-bit copied to all of the bits. This relies on implementation details of computers with 2's complement representations of integers, which is not required by the C @@ -38,9 +40,22 @@ unsigned int Cryptography_constant_time_lt(unsigned int a, unsigned int b) { a -= b; return Cryptography_DUPLICATE_MSB_TO_ALL(a); } + +bool Cryptography_check_padding(uint8_t *data, unsigned int block_len) { + unsigned int i; + uint8_t pad_size = data[block_len - 1]; + uint8_t mismatch = 0; + for (i = 0; i < block_len; i++) { + unsigned int mask = Cryptography_constant_time_lt(i, pad_size); + uint8_t b = data[block_len - 1 - i]; + mismatch |= (mask & (pad_size ^ b)); + } + return mismatch == 0; +} """) + class PKCS7(object): def __init__(self, block_size): super(PKCS7, self).__init__() @@ -131,13 +146,9 @@ class _PKCS7UnpaddingContext(object): pad_size = six.indexbytes(self._buffer, -1) - mismatch = 0 - for i in xrange(self.block_size // 8): - mask = _lib.Cryptography_constant_time_lt(i, pad_size) - b = six.indexbytes(self._buffer, self.block_size // 8 - 1 - i) - mismatch |= (mask & (pad_size ^ b)) + valid = _lib.Cryptography_check_padding(self._buffer, self.block_size // 8) - if mismatch != 0 or not (0 < pad_size <= self.block_size // 8): + if not valid or not (0 < pad_size <= self.block_size // 8): raise ValueError("Invalid padding bytes") res = self._buffer[:-pad_size] |