diff options
Diffstat (limited to 'src/_cffi_src/hazmat_src/padding.c')
| -rw-r--r-- | src/_cffi_src/hazmat_src/padding.c | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/src/_cffi_src/hazmat_src/padding.c b/src/_cffi_src/hazmat_src/padding.c index 570bad9f..a6e05dee 100644 --- a/src/_cffi_src/hazmat_src/padding.c +++ b/src/_cffi_src/hazmat_src/padding.c @@ -4,25 +4,25 @@ /* Returns the value of the input with the most-significant-bit copied to all of the bits. */ -static uint8_t Cryptography_DUPLICATE_MSB_TO_ALL(uint8_t a) { - return (1 - (a >> (sizeof(uint8_t) * 8 - 1))) - 1; +static uint16_t Cryptography_DUPLICATE_MSB_TO_ALL(uint16_t a) { + return (1 - (a >> (sizeof(uint16_t) * 8 - 1))) - 1; } -/* This returns 0xFF if a < b else 0x00, but does so in a constant time +/* This returns 0xFFFF if a < b else 0x0000, but does so in a constant time fashion */ -static uint8_t Cryptography_constant_time_lt(uint8_t a, uint8_t b) { +static uint16_t Cryptography_constant_time_lt(uint16_t a, uint16_t b) { a -= b; return Cryptography_DUPLICATE_MSB_TO_ALL(a); } uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data, - uint8_t block_len) { - uint8_t i; - uint8_t pad_size = data[block_len - 1]; - uint8_t mismatch = 0; + uint16_t block_len) { + uint16_t i; + uint16_t pad_size = data[block_len - 1]; + uint16_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]; + uint16_t b = data[block_len - 1 - i]; mismatch |= (mask & (pad_size ^ b)); } @@ -31,6 +31,32 @@ uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data, mismatch |= Cryptography_constant_time_lt(block_len, pad_size); /* Make sure any bits set are copied to the lowest bit */ + mismatch |= mismatch >> 8; + mismatch |= mismatch >> 4; + mismatch |= mismatch >> 2; + mismatch |= mismatch >> 1; + /* Now check the low bit to see if it's set */ + return (mismatch & 1) == 0; +} + +uint8_t Cryptography_check_ansix923_padding(const uint8_t *data, + uint16_t block_len) { + uint16_t i; + uint16_t pad_size = data[block_len - 1]; + uint16_t mismatch = 0; + /* Skip the first one with the pad size */ + for (i = 1; i < block_len; i++) { + unsigned int mask = Cryptography_constant_time_lt(i, pad_size); + uint16_t b = data[block_len - 1 - i]; + mismatch |= (mask & b); + } + + /* Check to make sure the pad_size was within the valid range. */ + mismatch |= ~Cryptography_constant_time_lt(0, pad_size); + mismatch |= Cryptography_constant_time_lt(block_len, pad_size); + + /* Make sure any bits set are copied to the lowest bit */ + mismatch |= mismatch >> 8; mismatch |= mismatch >> 4; mismatch |= mismatch >> 2; mismatch |= mismatch >> 1; |
