summaryrefslogtreecommitdiff
path: root/lib/libssl
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2016-04-28 16:39:46 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2016-04-28 16:39:46 +0000
commit2c8e6bc45ea1aa5e5fa7f3587aae35cebd155387 (patch)
treecd271e04c81acd0434307a43c9ef661ee877b840 /lib/libssl
parentb7f9e86e0e3c0bf2ff34e20fcf1a1736128a7fd5 (diff)
Implement the IETF ChaCha20-Poly1305 cipher suites.
Rename the existing ChaCha20-Poly1305 cipher suites with an "-OLD" suffix, effectively replaces the original Google implementation. We continue to support both the IETF and Google versions, however the existing names now refer to the ciphers from draft-ietf-tls-chacha20-poly1305-04. Feedback from doug@
Diffstat (limited to 'lib/libssl')
-rw-r--r--lib/libssl/s3_lib.c63
-rw-r--r--lib/libssl/ssl_ciph.c22
-rw-r--r--lib/libssl/ssl_locl.h6
-rw-r--r--lib/libssl/t1_enc.c109
-rw-r--r--lib/libssl/tls1.h14
5 files changed, 168 insertions, 46 deletions
diff --git a/lib/libssl/s3_lib.c b/lib/libssl/s3_lib.c
index e7f71d6b6f4..e873c17c876 100644
--- a/lib/libssl/s3_lib.c
+++ b/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.107 2016/01/27 02:06:16 beck Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.108 2016/04/28 16:39:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1810,6 +1810,57 @@ SSL_CIPHER ssl3_ciphers[] = {
/* Cipher CC13 */
{
.valid = 1,
+ .name = TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD,
+ .id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
+ .algorithm_mkey = SSL_kECDHE,
+ .algorithm_auth = SSL_aRSA,
+ .algorithm_enc = SSL_CHACHA20POLY1305_OLD,
+ .algorithm_mac = SSL_AEAD,
+ .algorithm_ssl = SSL_TLSV1_2,
+ .algo_strength = SSL_HIGH,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|
+ SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+ .strength_bits = 256,
+ .alg_bits = 256,
+ },
+
+ /* Cipher CC14 */
+ {
+ .valid = 1,
+ .name = TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD,
+ .id = TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
+ .algorithm_mkey = SSL_kECDHE,
+ .algorithm_auth = SSL_aECDSA,
+ .algorithm_enc = SSL_CHACHA20POLY1305_OLD,
+ .algorithm_mac = SSL_AEAD,
+ .algorithm_ssl = SSL_TLSV1_2,
+ .algo_strength = SSL_HIGH,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|
+ SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+ .strength_bits = 256,
+ .alg_bits = 256,
+ },
+
+ /* Cipher CC15 */
+ {
+ .valid = 1,
+ .name = TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_OLD,
+ .id = TLS1_CK_DHE_RSA_CHACHA20_POLY1305_OLD,
+ .algorithm_mkey = SSL_kDHE,
+ .algorithm_auth = SSL_aRSA,
+ .algorithm_enc = SSL_CHACHA20POLY1305_OLD,
+ .algorithm_mac = SSL_AEAD,
+ .algorithm_ssl = SSL_TLSV1_2,
+ .algo_strength = SSL_HIGH,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|
+ SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+ .strength_bits = 256,
+ .alg_bits = 256,
+ },
+
+ /* Cipher CCA8 */
+ {
+ .valid = 1,
.name = TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
.id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
.algorithm_mkey = SSL_kECDHE,
@@ -1819,12 +1870,12 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|
- SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+ SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(12),
.strength_bits = 256,
.alg_bits = 256,
},
- /* Cipher CC14 */
+ /* Cipher CCA9 */
{
.valid = 1,
.name = TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
@@ -1836,12 +1887,12 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|
- SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+ SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(12),
.strength_bits = 256,
.alg_bits = 256,
},
- /* Cipher CC15 */
+ /* Cipher CCAA */
{
.valid = 1,
.name = TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305,
@@ -1853,7 +1904,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|
- SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+ SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(12),
.strength_bits = 256,
.alg_bits = 256,
},
diff --git a/lib/libssl/ssl_ciph.c b/lib/libssl/ssl_ciph.c
index 5d1d568ff84..526d98e2937 100644
--- a/lib/libssl/ssl_ciph.c
+++ b/lib/libssl/ssl_ciph.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_ciph.c,v 1.85 2016/04/28 16:06:53 jsing Exp $ */
+/* $OpenBSD: ssl_ciph.c,v 1.86 2016/04/28 16:39:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -414,7 +414,7 @@ static const SSL_CIPHER cipher_aliases[] = {
},
{
.name = SSL_TXT_CHACHA20,
- .algorithm_enc = SSL_CHACHA20POLY1305,
+ .algorithm_enc = SSL_CHACHA20POLY1305|SSL_CHACHA20POLY1305_OLD,
},
/* MAC aliases */
@@ -731,6 +731,9 @@ ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead)
#endif
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
case SSL_CHACHA20POLY1305:
+ *aead = EVP_aead_chacha20_poly1305();
+ return 1;
+ case SSL_CHACHA20POLY1305_OLD:
*aead = EVP_aead_chacha20_poly1305_old();
return 1;
#endif
@@ -1423,15 +1426,19 @@ ssl_create_cipher_list(const SSL_METHOD *ssl_method,
*/
ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0,
CIPHER_ADD, -1, &head, &tail);
- ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, 0, 0, 0,
- CIPHER_ADD, -1, &head, &tail);
+ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305,
+ 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305_OLD,
+ 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
} else {
/*
* CHACHA20 is fast and safe on all hardware and is thus our
* preferred symmetric cipher, with AES second.
*/
- ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, 0, 0, 0,
- CIPHER_ADD, -1, &head, &tail);
+ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305,
+ 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305_OLD,
+ 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0,
CIPHER_ADD, -1, &head, &tail);
}
@@ -1667,6 +1674,9 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_CHACHA20POLY1305:
enc = "ChaCha20-Poly1305";
break;
+ case SSL_CHACHA20POLY1305_OLD:
+ enc = "ChaCha20-Poly1305-Old";
+ break;
case SSL_eGOST2814789CNT:
enc = "GOST-28178-89-CNT";
break;
diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h
index e05578e4a31..2a521fe26a3 100644
--- a/lib/libssl/ssl_locl.h
+++ b/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.128 2015/09/12 15:08:54 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.129 2016/04/28 16:39:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -283,6 +283,7 @@
#define SSL_AES128GCM 0x00000400L
#define SSL_AES256GCM 0x00000800L
#define SSL_CHACHA20POLY1305 0x00001000L
+#define SSL_CHACHA20POLY1305_OLD 0x00002000L
#define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256)
@@ -529,9 +530,10 @@ struct ssl_aead_ctx_st {
* fixed_nonce contains any bytes of the nonce that are fixed for all
* records.
*/
- unsigned char fixed_nonce[8];
+ unsigned char fixed_nonce[12];
unsigned char fixed_nonce_len;
unsigned char variable_nonce_len;
+ unsigned char xor_fixed_nonce;
unsigned char tag_len;
/*
* variable_nonce_in_record is non-zero if the variable nonce
diff --git a/lib/libssl/t1_enc.c b/lib/libssl/t1_enc.c
index 5d95419e7e8..53570b2d4f7 100644
--- a/lib/libssl/t1_enc.c
+++ b/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_enc.c,v 1.84 2016/03/06 14:52:15 beck Exp $ */
+/* $OpenBSD: t1_enc.c,v 1.85 2016/04/28 16:39:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -471,14 +471,26 @@ tls1_change_cipher_state_aead(SSL *s, char is_read, const unsigned char *key,
aead_ctx->variable_nonce_in_record =
(s->s3->tmp.new_cipher->algorithm2 &
SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD) != 0;
- if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len !=
- EVP_AEAD_nonce_length(aead)) {
- SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD,
- ERR_R_INTERNAL_ERROR);
- return (0);
- }
+ aead_ctx->xor_fixed_nonce =
+ s->s3->tmp.new_cipher->algorithm_enc == SSL_CHACHA20POLY1305;
aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
+ if (aead_ctx->xor_fixed_nonce) {
+ if (aead_ctx->fixed_nonce_len != EVP_AEAD_nonce_length(aead) ||
+ aead_ctx->variable_nonce_len > EVP_AEAD_nonce_length(aead)) {
+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD,
+ ERR_R_INTERNAL_ERROR);
+ return (0);
+ }
+ } else {
+ if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len !=
+ EVP_AEAD_nonce_length(aead)) {
+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD,
+ ERR_R_INTERNAL_ERROR);
+ return (0);
+ }
+ }
+
return (1);
}
@@ -819,8 +831,8 @@ tls1_enc(SSL *s, int send)
if (aead) {
unsigned char ad[13], *in, *out, nonce[16];
- unsigned nonce_used;
- size_t out_len;
+ size_t out_len, pad_len = 0;
+ unsigned int nonce_used;
if (SSL_IS_DTLS(s)) {
dtls1_build_sequence_number(ad, seq,
@@ -834,13 +846,20 @@ tls1_enc(SSL *s, int send)
ad[9] = (unsigned char)(s->version >> 8);
ad[10] = (unsigned char)(s->version);
- if (aead->fixed_nonce_len +
- aead->variable_nonce_len > sizeof(nonce) ||
- aead->variable_nonce_len > 8)
- return -1; /* internal error - should never happen. */
+ if (aead->variable_nonce_len > 8 ||
+ aead->variable_nonce_len > sizeof(nonce))
+ return -1;
- memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
- nonce_used = aead->fixed_nonce_len;
+ if (aead->xor_fixed_nonce) {
+ if (aead->fixed_nonce_len > sizeof(nonce) ||
+ aead->variable_nonce_len > aead->fixed_nonce_len)
+ return -1; /* Should never happen. */
+ pad_len = aead->fixed_nonce_len - aead->variable_nonce_len;
+ } else {
+ if (aead->fixed_nonce_len +
+ aead->variable_nonce_len > sizeof(nonce))
+ return -1; /* Should never happen. */
+ }
if (send) {
size_t len = rec->length;
@@ -848,15 +867,30 @@ tls1_enc(SSL *s, int send)
in = rec->input;
out = rec->data;
- /*
- * When sending we use the sequence number as the
- * variable part of the nonce.
- */
- if (aead->variable_nonce_len > 8)
- return -1;
- memcpy(nonce + nonce_used, ad,
- aead->variable_nonce_len);
- nonce_used += aead->variable_nonce_len;
+ if (aead->xor_fixed_nonce) {
+ /*
+ * The sequence number is left zero
+ * padded, then xored with the fixed
+ * nonce.
+ */
+ memset(nonce, 0, pad_len);
+ memcpy(nonce + pad_len, ad,
+ aead->variable_nonce_len);
+ for (i = 0; i < aead->fixed_nonce_len; i++)
+ nonce[i] ^= aead->fixed_nonce[i];
+ nonce_used = aead->fixed_nonce_len;
+ } else {
+ /*
+ * When sending we use the sequence number as
+ * the variable part of the nonce.
+ */
+ memcpy(nonce, aead->fixed_nonce,
+ aead->fixed_nonce_len);
+ nonce_used = aead->fixed_nonce_len;
+ memcpy(nonce + nonce_used, ad,
+ aead->variable_nonce_len);
+ nonce_used += aead->variable_nonce_len;
+ }
/*
* In do_ssl3_write, rec->input is moved forward by
@@ -890,10 +924,29 @@ tls1_enc(SSL *s, int send)
if (len < aead->variable_nonce_len)
return 0;
- memcpy(nonce + nonce_used,
- aead->variable_nonce_in_record ? in : ad,
- aead->variable_nonce_len);
- nonce_used += aead->variable_nonce_len;
+
+ if (aead->xor_fixed_nonce) {
+ /*
+ * The sequence number is left zero
+ * padded, then xored with the fixed
+ * nonce.
+ */
+ memset(nonce, 0, pad_len);
+ memcpy(nonce + pad_len, ad,
+ aead->variable_nonce_len);
+ for (i = 0; i < aead->fixed_nonce_len; i++)
+ nonce[i] ^= aead->fixed_nonce[i];
+ nonce_used = aead->fixed_nonce_len;
+ } else {
+ memcpy(nonce, aead->fixed_nonce,
+ aead->fixed_nonce_len);
+ nonce_used = aead->fixed_nonce_len;
+
+ memcpy(nonce + nonce_used,
+ aead->variable_nonce_in_record ? in : ad,
+ aead->variable_nonce_len);
+ nonce_used += aead->variable_nonce_len;
+ }
if (aead->variable_nonce_in_record) {
in += aead->variable_nonce_len;
diff --git a/lib/libssl/tls1.h b/lib/libssl/tls1.h
index e564ec23e9a..e1231178661 100644
--- a/lib/libssl/tls1.h
+++ b/lib/libssl/tls1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls1.h,v 1.27 2016/03/07 19:33:26 mmcc Exp $ */
+/* $OpenBSD: tls1.h,v 1.28 2016/04/28 16:39:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -537,9 +537,12 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032
/* ChaCha20-Poly1305 based ciphersuites. */
-#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 0x0300CC13
-#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CC14
-#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305 0x0300CC15
+#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC13
+#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD 0x0300CC14
+#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC15
+#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 0x0300CCA8
+#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CCA9
+#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305 0x0300CCAA
#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5"
#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5"
@@ -701,6 +704,9 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384"
/* ChaCha20-Poly1305 based ciphersuites. */
+#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD "ECDHE-RSA-CHACHA20-POLY1305-OLD"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD "ECDHE-ECDSA-CHACHA20-POLY1305-OLD"
+#define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_OLD "DHE-RSA-CHACHA20-POLY1305-OLD"
#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305"
#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305"
#define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305"