Add a compile time verification ciphers are sorted for bsearch()
Change-Id: Ibdf5b5194087a44088563141f1de2801cade231b
Reviewed-on: https://boringssl-review.googlesource.com/30144
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc
index 54459a1..5899500 100644
--- a/ssl/ssl_cipher.cc
+++ b/ssl/ssl_cipher.cc
@@ -157,7 +157,7 @@
namespace bssl {
// kCiphers is an array of all supported ciphers, sorted by id.
-static const SSL_CIPHER kCiphers[] = {
+static constexpr SSL_CIPHER kCiphers[] = {
// The RSA ciphers
// Cipher 02
{
@@ -556,19 +556,6 @@
static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases);
-static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
- const SSL_CIPHER *a = reinterpret_cast<const SSL_CIPHER *>(in_a);
- const SSL_CIPHER *b = reinterpret_cast<const SSL_CIPHER *>(in_b);
-
- if (a->id > b->id) {
- return 1;
- } else if (a->id < b->id) {
- return -1;
- } else {
- return 0;
- }
-}
-
bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
size_t *out_mac_secret_len,
size_t *out_fixed_iv_len, const SSL_CIPHER *cipher,
@@ -1323,6 +1310,36 @@
using namespace bssl;
+static constexpr int ssl_cipher_id_cmp_inner(const SSL_CIPHER *a,
+ const SSL_CIPHER *b) {
+ // C++11's constexpr functions must have a body consisting of just a
+ // return-statement.
+ return (a->id > b->id) ? 1 : ((a->id < b->id) ? -1 : 0);
+}
+
+static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
+ return ssl_cipher_id_cmp_inner(reinterpret_cast<const SSL_CIPHER *>(in_a),
+ reinterpret_cast<const SSL_CIPHER *>(in_b));
+}
+
+template <typename T, size_t N>
+static constexpr size_t countof(T const (&)[N]) {
+ return N;
+}
+
+template <typename T, size_t I>
+static constexpr int check_order(const T (&arr)[I], size_t N) {
+ // C++11's constexpr functions must have a body consisting of just a
+ // return-statement.
+ return N > 1 ? ((ssl_cipher_id_cmp_inner(&arr[N - 2], &arr[N - 1]) < 0)
+ ? check_order(arr, N - 1)
+ : 0)
+ : 1;
+}
+
+static_assert(check_order(kCiphers, countof(kCiphers)) == 1,
+ "Ciphers are not sorted, bsearch won't work");
+
const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
SSL_CIPHER c;