diff options
Diffstat (limited to 'ssl/ssl_ciph.c')
-rw-r--r-- | ssl/ssl_ciph.c | 63 |
1 files changed, 57 insertions, 6 deletions
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 376b7b62d5..acf5c00dad 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -278,6 +278,11 @@ static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { #define CIPHER_DEL 3 #define CIPHER_ORD 4 #define CIPHER_SPECIAL 5 +/* + * Bump the ciphers to the top of the list. + * This rule isn't currently supported by the public cipherstring API. + */ +#define CIPHER_BUMP 6 typedef struct cipher_order_st { const SSL_CIPHER *cipher; @@ -896,7 +901,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, algo_strength, strength_bits); #endif - if (rule == CIPHER_DEL) + if (rule == CIPHER_DEL || rule == CIPHER_BUMP) reverse = 1; /* needed to maintain sorting between * currently deleted ciphers */ @@ -986,6 +991,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, ll_append_head(&head, curr, &tail); curr->active = 0; } + } else if (rule == CIPHER_BUMP) { + if (curr->active) + ll_append_head(&head, curr, &tail); } else if (rule == CIPHER_KILL) { /* reverse == 0 */ if (head == curr) @@ -1420,20 +1428,36 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK disabled_mac, disabled_ssl, co_list, &head, &tail); - /* Now arrange all ciphers by preference: */ + /* Now arrange all ciphers by preference. */ /* * Everything else being equal, prefer ephemeral ECDH over other key - * exchange mechanisms + * exchange mechanisms. + * For consistency, prefer ECDSA over RSA (though this only matters if the + * server has both certificates, and is using the DEFAULT, or a client + * preference). */ + ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD, + -1, &head, &tail); ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); - /* AES is our preferred symmetric cipher */ - ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, - &tail); + + /* Within each strength group, we prefer GCM over CHACHA... */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1, + &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1, + &head, &tail); + + /* + * ...and generally, our preferred cipher is AES. + * Note that AEADs will be bumped to take preference after sorting by + * strength. + */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD, + -1, &head, &tail); /* Temporarily enable everything else for sorting */ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); @@ -1472,6 +1496,33 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK return NULL; } + /* + * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs. + * TODO(openssl-team): is there an easier way to accomplish all this? + */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, SSL_TLSV1_2, 0, CIPHER_BUMP, -1, + &head, &tail); + + /* + * Irrespective of strength, enforce the following order: + * (EC)DHE + AEAD > (EC)DHE > rest of AEAD > rest. + * Within each group, ciphers remain sorted by strength and previous + * preference, i.e., + * 1) ECDHE > DHE + * 2) GCM > CHACHA + * 3) AES > rest + * 4) TLS 1.2 > legacy + * + * Because we now bump ciphers to the top of the list, we proceed in + * reverse order of preference. + */ + ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1, + &head, &tail); + ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0, + CIPHER_BUMP, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0, + CIPHER_BUMP, -1, &head, &tail); + /* Now disable everything (maintaining the ordering!) */ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); |