summaryrefslogtreecommitdiffstats
path: root/ssl/s3_lib.c
diff options
context:
space:
mode:
authorTodd Short <tshort@akamai.com>2015-12-21 15:19:29 -0500
committerPauli <paul.dale@oracle.com>2017-11-30 07:13:08 +1000
commite1c7871de80029b81824df4d59edc6de5293835f (patch)
tree8b5e34751cbc70493dbbb36cddaf7f85cd943ccd /ssl/s3_lib.c
parent92b1b9a8871530f26ef7df972111297ffa721be2 (diff)
Use ChaCha only if prioritized by clnt
IFF the client has ChaCha first, and server cipher priority is used, and the new SSL_OP_PRIORITIZE_CHACHA_FOR_MOBILE option is used, then reprioritize ChaCha above everything else. This way, A matching ChaCha cipher will be selected if there is a match. If no ChaCha ciphers match, then the other ciphers are used. Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Andy Polyakov <appro@openssl.org> (Merged from https://github.com/openssl/openssl/pull/4436)
Diffstat (limited to 'ssl/s3_lib.c')
-rw-r--r--ssl/s3_lib.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index f4423b2855..c063fff87a 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -4120,6 +4120,9 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
STACK_OF(SSL_CIPHER) *prio, *allow;
int i, ii, ok;
unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0;
+#ifndef OPENSSL_NO_CHACHA
+ STACK_OF(SSL_CIPHER) *prio_chacha = NULL;
+#endif
/* Let's see which ciphers we can support */
@@ -4145,9 +4148,53 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
}
#endif
- if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) {
+ /* SUITE-B takes precedence over server preference and ChaCha priortiy */
+ if (tls1_suiteb(s)) {
+ prio = srvr;
+ allow = clnt;
+ } else if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
prio = srvr;
allow = clnt;
+#ifndef OPENSSL_NO_CHACHA
+ /* If ChaCha20 is at the top of the client preference list,
+ and there are ChaCha20 ciphers in the server list, then
+ temporarily prioritize all ChaCha20 ciphers in the servers list. */
+ if (s->options & SSL_OP_PRIORITIZE_CHACHA && sk_SSL_CIPHER_num(clnt) > 0) {
+ c = sk_SSL_CIPHER_value(clnt, 0);
+ if (c->algorithm_enc == SSL_CHACHA20POLY1305) {
+ /* ChaCha20 is client preferred, check server... */
+ int num = sk_SSL_CIPHER_num(srvr);
+ int found = 0;
+ for (i = 0; i < num; i++) {
+ c = sk_SSL_CIPHER_value(srvr, i);
+ if (c->algorithm_enc == SSL_CHACHA20POLY1305) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ prio_chacha = sk_SSL_CIPHER_new_null();
+ /* if reserve fails, then there's likely a memory issue */
+ if (prio_chacha != NULL) {
+ /* Put all ChaCha20 at the top, starting with the one we just found */
+ sk_SSL_CIPHER_push(prio_chacha, c);
+ for (i++; i < num; i++) {
+ c = sk_SSL_CIPHER_value(srvr, i);
+ if (c->algorithm_enc == SSL_CHACHA20POLY1305)
+ sk_SSL_CIPHER_push(prio_chacha, c);
+ }
+ /* Pull in the rest */
+ for (i = 0; i < num; i++) {
+ c = sk_SSL_CIPHER_value(srvr, i);
+ if (c->algorithm_enc != SSL_CHACHA20POLY1305)
+ sk_SSL_CIPHER_push(prio_chacha, c);
+ }
+ prio = prio_chacha;
+ }
+ }
+ }
+ }
+# endif
} else {
prio = clnt;
allow = srvr;
@@ -4229,6 +4276,9 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
break;
}
}
+#ifndef OPENSSL_NO_CHACHA
+ sk_SSL_CIPHER_free(prio_chacha);
+#endif
return ret;
}