Add a few more constant-time utility functions.
Imported from upstream's 9bed73adaa6f834177f29e478d9a2247a6577c04. Upstream's commit appears to have been based on BoringSSL's commits to improve the constant-time behaviour of RSA padding checks and thus I've not tried to import those bits of the change. Change-Id: I0ea5775b0f1e18741bbbc9f792a6af0d3d2a4caf
This commit is contained in:
parent
7530e3031d
commit
a952d96656
@ -169,7 +169,7 @@ void OPENSSL_cpuid_setup(void);
|
|||||||
* can be written as
|
* can be written as
|
||||||
*
|
*
|
||||||
* unsigned int lt = constant_time_lt(a, b);
|
* unsigned int lt = constant_time_lt(a, b);
|
||||||
* c = a & lt | b & ~lt; */
|
* c = constant_time_select(lt, a, b); */
|
||||||
|
|
||||||
/* constant_time_msb returns the given value with the MSB copied to all the
|
/* constant_time_msb returns the given value with the MSB copied to all the
|
||||||
* other bits. Uses the fact that arithmetic shift shifts-in the sign bit.
|
* other bits. Uses the fact that arithmetic shift shifts-in the sign bit.
|
||||||
@ -230,6 +230,27 @@ static inline uint8_t constant_time_eq_8(unsigned int a, unsigned int b) {
|
|||||||
return (uint8_t)(constant_time_eq(a, b));
|
return (uint8_t)(constant_time_eq(a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* constant_time_select returns (mask & a) | (~mask & b). When |mask| is all 1s
|
||||||
|
* or all 0s (as returned by the methods above), the select methods return
|
||||||
|
* either |a| (if |mask| is nonzero) or |b| (if |mask| is zero). */
|
||||||
|
static inline unsigned int constant_time_select(unsigned int mask,
|
||||||
|
unsigned int a, unsigned int b) {
|
||||||
|
return (mask & a) | (~mask & b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* constant_time_select_8 acts like |constant_time_select| but operates on
|
||||||
|
* 8-bit values. */
|
||||||
|
static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a,
|
||||||
|
uint8_t b) {
|
||||||
|
return (uint8_t)(constant_time_select(mask, a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* constant_time_select_int acts like |constant_time_select| but operates on
|
||||||
|
* ints. */
|
||||||
|
static inline int constant_time_select_int(unsigned int mask, int a, int b) {
|
||||||
|
return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
|
@ -96,7 +96,7 @@ int ssl3_cbc_remove_padding(const SSL* s,
|
|||||||
padding_length = good & (padding_length+1);
|
padding_length = good & (padding_length+1);
|
||||||
rec->length -= padding_length;
|
rec->length -= padding_length;
|
||||||
rec->type |= padding_length<<8; /* kludge: pass padding length */
|
rec->type |= padding_length<<8; /* kludge: pass padding length */
|
||||||
return (int)((good & 1) | (~good & -1));
|
return constant_time_select_int(good, 1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
|
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
|
||||||
@ -166,7 +166,7 @@ int tls1_cbc_remove_padding(const SSL* s,
|
|||||||
rec->length -= padding_length;
|
rec->length -= padding_length;
|
||||||
rec->type |= padding_length<<8; /* kludge: pass padding length */
|
rec->type |= padding_length<<8; /* kludge: pass padding length */
|
||||||
|
|
||||||
return (int)((good & 1) | (~good & -1));
|
return constant_time_select_int(good, 1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
|
/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
|
||||||
@ -562,7 +562,7 @@ void ssl3_cbc_digest_record(
|
|||||||
/* If this is the block containing the end of the
|
/* If this is the block containing the end of the
|
||||||
* application data, and we are at the offset for the
|
* application data, and we are at the offset for the
|
||||||
* 0x80 value, then overwrite b with 0x80. */
|
* 0x80 value, then overwrite b with 0x80. */
|
||||||
b = (b&~is_past_c) | (0x80&is_past_c);
|
b = constant_time_select_8(is_past_c, 0x80, b);
|
||||||
/* If this the the block containing the end of the
|
/* If this the the block containing the end of the
|
||||||
* application data and we're past the 0x80 value then
|
* application data and we're past the 0x80 value then
|
||||||
* just write zero. */
|
* just write zero. */
|
||||||
@ -578,7 +578,7 @@ void ssl3_cbc_digest_record(
|
|||||||
if (j >= md_block_size - md_length_size)
|
if (j >= md_block_size - md_length_size)
|
||||||
{
|
{
|
||||||
/* If this is index_b, write a length byte. */
|
/* If this is index_b, write a length byte. */
|
||||||
b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
|
b = constant_time_select_8(is_block_b, length_bytes[j-(md_block_size-md_length_size)], b);
|
||||||
}
|
}
|
||||||
block[j] = b;
|
block[j] = b;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user