diff options
| author | Julian Krause <julian.krause@gmail.com> | 2013-12-04 14:49:50 -0800 |
|---|---|---|
| committer | Julian Krause <julian.krause@gmail.com> | 2013-12-04 14:49:50 -0800 |
| commit | 9c3088fe12d844a2007e0eff0eb947af53de7f60 (patch) | |
| tree | 784f9cccd6c10d6313272fd4e3441816bffe3382 /cryptography | |
| parent | 3029fe414a3dba0231a44e72ddfc398634c173de (diff) | |
| download | cryptography-9c3088fe12d844a2007e0eff0eb947af53de7f60.tar.gz cryptography-9c3088fe12d844a2007e0eff0eb947af53de7f60.tar.bz2 cryptography-9c3088fe12d844a2007e0eff0eb947af53de7f60.zip | |
Beginnings of a constant_time module.
Diffstat (limited to 'cryptography')
| -rw-r--r-- | cryptography/hazmat/primitives/constant_time.py | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/cryptography/hazmat/primitives/constant_time.py b/cryptography/hazmat/primitives/constant_time.py new file mode 100644 index 00000000..a8351504 --- /dev/null +++ b/cryptography/hazmat/primitives/constant_time.py @@ -0,0 +1,53 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import cffi + +import six + + +_ffi = cffi.FFI() +_ffi.cdef(""" +bool Cryptography_constant_time_bytes_eq(uint8_t *, size_t, uint8_t *, size_t); +""") +_lib = _ffi.verify(""" +#include <stdbool.h> + +bool Cryptography_constant_time_bytes_eq(uint8_t *a, size_t len_a, uint8_t *b, + size_t len_b) { + size_t i = 0; + uint8_t mismatch = 0; + if (len_a != len_b) { + return false; + } + for (i = 0; i < len_a; i++) { + mismatch |= a[i] ^ b[i]; + } + + /* Make sure any bits set are copied to the lowest bit */ + mismatch |= mismatch >> 4; + mismatch |= mismatch >> 2; + mismatch |= mismatch >> 1; + /* Now check the low bit to see if it's set */ + return (mismatch & 1) == 0; +} +""") + + +def bytes_eq(a, b): + if isinstance(a, six.text_type) or isinstance(b, six.text_type): + raise TypeError("Unicode-objects must be encoded before comparing") + + return _lib.Cryptography_constant_time_bytes_eq(a, len(a), b, len(b)) == 1 |
