Created
March 8, 2017 10:25
-
-
Save tmthrgd/b6f9bd53e75f01738255c2be0497ac1c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ssl/ngx_http_ether_ssl_module.c b/ssl/ngx_http_ether_ssl_module.c | |
index 99eb507..87d3f2e 100644 | |
--- a/ssl/ngx_http_ether_ssl_module.c | |
+++ b/ssl/ngx_http_ether_ssl_module.c | |
@@ -25,15 +25,13 @@ static char *ngx_http_ether_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, voi | |
static char *ngx_http_ether_ssl_set_opt_env_str(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
-static ngx_inline const EVP_AEAD *ngx_http_ether_ssl_select_aead(const ngx_ether_key_st *key); | |
- | |
static int ngx_http_ether_ssl_session_ticket_key_handler(ngx_ssl_conn_t *ssl_conn, | |
unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, | |
int enc); | |
static int ngx_http_ether_ssl_session_ticket_key_enc(ngx_ssl_conn_t *ssl_conn, uint8_t *name, | |
- uint8_t *nonce, EVP_AEAD_CTX *ctx); | |
+ uint8_t *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx); | |
static int ngx_http_ether_ssl_session_ticket_key_dec(ngx_ssl_conn_t *ssl_conn, const uint8_t *name, | |
- EVP_AEAD_CTX *ctx); | |
+ const uint8_t *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx); | |
static int ngx_http_ether_ssl_new_session_handler(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess); | |
static ngx_ssl_session_t *ngx_http_ether_ssl_get_session_handler(ngx_ssl_conn_t *ssl_conn, | |
@@ -329,42 +327,23 @@ static char *ngx_http_ether_ssl_set_opt_env_str(ngx_conf_t *cf, ngx_command_t *c | |
return NGX_CONF_OK; | |
} | |
-static ngx_inline const EVP_AEAD *ngx_http_ether_ssl_select_aead(const ngx_ether_key_st *key) | |
-{ | |
- switch (key->len*8) { | |
- case 128: | |
- return EVP_aead_aes_128_gcm(); | |
- case 256: | |
- return EVP_aead_aes_256_gcm(); | |
- default: | |
- return NULL; | |
- } | |
-} | |
- | |
static int ngx_http_ether_ssl_session_ticket_key_handler(ngx_ssl_conn_t *ssl_conn, | |
unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, | |
int enc) | |
{ | |
- if (hctx != SSL_magic_tlsext_ticket_key_cb_aead_ptr()) { | |
- return TLSEXT_TICKET_CB_WANT_AEAD; | |
- } | |
- | |
if (enc) { | |
- return ngx_http_ether_ssl_session_ticket_key_enc(ssl_conn, name, iv, | |
- (EVP_AEAD_CTX *)ectx); | |
+ return ngx_http_ether_ssl_session_ticket_key_enc(ssl_conn, name, iv, ectx, hctx); | |
} else { | |
- return ngx_http_ether_ssl_session_ticket_key_dec(ssl_conn, name, | |
- (EVP_AEAD_CTX *)ectx); | |
+ return ngx_http_ether_ssl_session_ticket_key_dec(ssl_conn, name, iv, ectx, hctx); | |
} | |
} | |
static int ngx_http_ether_ssl_session_ticket_key_enc(ngx_ssl_conn_t *ssl_conn, uint8_t *name, | |
- uint8_t *nonce, EVP_AEAD_CTX *ctx) { | |
+ uint8_t *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx) { | |
const SSL_CTX *ssl_ctx; | |
const ngx_connection_t *c; | |
const ngx_http_ether_ssl_srv_conf_st *conf; | |
const ngx_ether_key_st *key; | |
- const EVP_AEAD *aead; | |
#if NGX_DEBUG | |
u_char buf[SSL_TICKET_KEY_NAME_LEN*2]; | |
#endif /* NGX_DEBUG */ | |
@@ -387,17 +366,20 @@ static int ngx_http_ether_ssl_session_ticket_key_enc(ngx_ssl_conn_t *ssl_conn, u | |
ngx_hex_dump(buf, (u_char *)key->name, SSL_TICKET_KEY_NAME_LEN) - buf, buf, | |
SSL_session_reused(ssl_conn) ? "reused" : "new"); | |
- aead = ngx_http_ether_ssl_select_aead(key); | |
- if (!aead) { | |
+ if (key->len != 32) { | |
ngx_log_error(NGX_LOG_EMERG, c->log, 0, "invalid key length: %d", key->len); | |
return -1; | |
} | |
- if (RAND_bytes(nonce, EVP_AEAD_nonce_length(aead)) != 1) { | |
+ if (RAND_bytes(iv, 16) != 1) { | |
+ return -1; | |
+ } | |
+ | |
+ if (!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key->key, iv)) { | |
return -1; | |
} | |
- if (!EVP_AEAD_CTX_init(ctx, aead, key->key, key->len, EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) { | |
+ if (!HMAC_Init_ex(hctx, key->key + 16, 16, EVP_sha256(), NULL)) { | |
return -1; | |
} | |
@@ -406,12 +388,11 @@ static int ngx_http_ether_ssl_session_ticket_key_enc(ngx_ssl_conn_t *ssl_conn, u | |
} | |
static int ngx_http_ether_ssl_session_ticket_key_dec(ngx_ssl_conn_t *ssl_conn, const uint8_t *name, | |
- EVP_AEAD_CTX *ctx) { | |
+ const uint8_t *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx) { | |
const SSL_CTX *ssl_ctx; | |
const ngx_connection_t *c; | |
const ngx_http_ether_ssl_srv_conf_st *conf; | |
const ngx_ether_key_st *key; | |
- const EVP_AEAD *aead; | |
#if NGX_DEBUG | |
u_char buf[SSL_TICKET_KEY_NAME_LEN*2]; | |
#endif /* NGX_DEBUG */ | |
@@ -437,13 +418,16 @@ static int ngx_http_ether_ssl_session_ticket_key_dec(ngx_ssl_conn_t *ssl_conn, c | |
ngx_hex_dump(buf, (u_char *)key->name, SSL_TICKET_KEY_NAME_LEN) - buf, buf, | |
(key == conf->peer.default_key) ? " (default)" : ""); | |
- aead = ngx_http_ether_ssl_select_aead(key); | |
- if (!aead) { | |
+ if (key->len != 32) { | |
ngx_log_error(NGX_LOG_EMERG, c->log, 0, "invalid key length: %d", key->len); | |
return -1; | |
} | |
- if (!EVP_AEAD_CTX_init(ctx, aead, key->key, key->len, EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) { | |
+ if (!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key->key, iv)) { | |
+ return -1; | |
+ } | |
+ | |
+ if (!HMAC_Init_ex(hctx, key->key + 16, 16, EVP_sha256(), NULL)) { | |
return -1; | |
} | |
@@ -464,10 +448,12 @@ static int ngx_http_ether_ssl_new_session_handler(ngx_ssl_conn_t *ssl_conn, | |
ngx_str_t key; | |
ngx_keyval_t kv; | |
unsigned int len; | |
- EVP_AEAD_CTX aead_ctx; | |
+ int len1, len2; | |
+ EVP_CIPHER_CTX cipher_ctx; | |
+ HMAC_CTX hmac_ctx; | |
CBB cbb; | |
- u_char *session = NULL, *name, *nonce, *p; | |
- size_t session_len, out_len; | |
+ u_char *session = NULL, *name, *iv, *p; | |
+ size_t session_len; | |
protocol_binary_request_add req; | |
u_char buf[NGX_ETHER_MEMC_MAX_KEY_PREFIX_LEN + SSL_MAX_SSL_SESSION_ID_LENGTH*2]; | |
@@ -490,21 +476,25 @@ static int ngx_http_ether_ssl_new_session_handler(ngx_ssl_conn_t *ssl_conn, | |
} | |
ngx_str_null(&kv.value); | |
- EVP_AEAD_CTX_zero(&aead_ctx); | |
+ EVP_CIPHER_CTX_init(&cipher_ctx); | |
+ HMAC_CTX_init(&hmac_ctx); | |
if (SSL_SESSION_to_bytes_for_ticket(sess, &session, &session_len) | |
- && CBB_init(&cbb, SSL_TICKET_KEY_NAME_LEN + EVP_AEAD_MAX_NONCE_LENGTH + session_len | |
- + EVP_AEAD_MAX_OVERHEAD) | |
+ && CBB_init(&cbb, SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH + session_len | |
+ + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE) | |
&& CBB_add_space(&cbb, &name, SSL_TICKET_KEY_NAME_LEN) | |
- && CBB_reserve(&cbb, &nonce, EVP_AEAD_MAX_NONCE_LENGTH) | |
- && ngx_http_ether_ssl_session_ticket_key_enc(ssl_conn, name, nonce, &aead_ctx) >= 0 | |
- && CBB_did_write(&cbb, EVP_AEAD_nonce_length(aead_ctx.aead)) | |
- && CBB_reserve(&cbb, &p, session_len + EVP_AEAD_max_overhead(aead_ctx.aead)) | |
- && EVP_AEAD_CTX_seal(&aead_ctx, | |
- p, &out_len, session_len + EVP_AEAD_max_overhead(aead_ctx.aead), | |
- nonce, EVP_AEAD_nonce_length(aead_ctx.aead), | |
- session, session_len, key.data, key.len) | |
- && CBB_did_write(&cbb, out_len) | |
+ && CBB_reserve(&cbb, &iv, EVP_MAX_IV_LENGTH) | |
+ && ngx_http_ether_ssl_session_ticket_key_enc(ssl_conn, name, iv, &cipher_ctx, | |
+ &hmac_ctx) >= 0 | |
+ && CBB_did_write(&cbb, EVP_CIPHER_CTX_iv_length(&cipher_ctx)) | |
+ && CBB_reserve(&cbb, &p, session_len + EVP_MAX_BLOCK_LENGTH) | |
+ && EVP_EncryptUpdate(&cipher_ctx, p, &len1, session, session_len) | |
+ && EVP_EncryptFinal_ex(&cipher_ctx, p + len1, &len2) | |
+ && CBB_did_write(&cbb, len1 + len2) | |
+ && HMAC_Update(&hmac_ctx, CBB_data(&cbb), CBB_len(&cbb)) | |
+ && CBB_reserve(&cbb, &p, EVP_MAX_MD_SIZE) | |
+ && HMAC_Final(&hmac_ctx, p, &len) | |
+ && CBB_did_write(&cbb, len) | |
&& CBB_finish(&cbb, &kv.value.data, &kv.value.len)) { | |
ngx_memzero(&req, sizeof(protocol_binary_request_set)); | |
req.message.body.expiration = | |
@@ -517,7 +507,8 @@ static int ngx_http_ether_ssl_new_session_handler(ngx_ssl_conn_t *ssl_conn, | |
OPENSSL_free(kv.value.data); | |
CBB_cleanup(&cbb); | |
- EVP_AEAD_CTX_cleanup(&aead_ctx); | |
+ EVP_CIPHER_CTX_cleanup(&cipher_ctx); | |
+ HMAC_CTX_cleanup(&hmac_ctx); | |
return 0; | |
} | |
@@ -536,9 +527,12 @@ static ngx_ssl_session_t *ngx_http_ether_ssl_get_session_handler(ngx_ssl_conn_t | |
ngx_http_ether_ssl_get_session_cleanup_st *cln_data; | |
ngx_event_t *ev; | |
ngx_ssl_session_t *sess; | |
- EVP_AEAD_CTX aead_ctx; | |
- CBS cbs, name, nonce; | |
- size_t plaintext_len; | |
+ EVP_CIPHER_CTX cipher_ctx; | |
+ HMAC_CTX hmac_ctx; | |
+ CBS cbs, name, p; | |
+ uint8_t mac[EVP_MAX_MD_SIZE]; | |
+ size_t mac_len; | |
+ int len1, len2; | |
u_char buf[NGX_ETHER_MEMC_MAX_KEY_PREFIX_LEN + SSL_MAX_SSL_SESSION_ID_LENGTH*2]; | |
c = ngx_ssl_get_connection(ssl_conn); | |
@@ -625,22 +619,38 @@ static ngx_ssl_session_t *ngx_http_ether_ssl_get_session_handler(ngx_ssl_conn_t | |
/* rc == NGX_OK */ | |
CBS_init(&cbs, value.data, value.len); | |
- EVP_AEAD_CTX_zero(&aead_ctx); | |
+ EVP_CIPHER_CTX_init(&cipher_ctx); | |
+ HMAC_CTX_init(&hmac_ctx); | |
if (!CBS_get_bytes(&cbs, &name, SSL_TICKET_KEY_NAME_LEN) | |
- || ngx_http_ether_ssl_session_ticket_key_dec(ssl_conn, CBS_data(&name), &aead_ctx) | |
- <= 0 | |
- || !CBS_get_bytes(&cbs, &nonce, EVP_AEAD_nonce_length(aead_ctx.aead)) | |
- || !EVP_AEAD_CTX_open(&aead_ctx, | |
- (uint8_t *)CBS_data(&cbs), &plaintext_len, CBS_len(&cbs), | |
- CBS_data(&nonce), CBS_len(&nonce), CBS_data(&cbs), CBS_len(&cbs), | |
- id, len)) { | |
- EVP_AEAD_CTX_cleanup(&aead_ctx); | |
- return NULL; | |
+ || ngx_http_ether_ssl_session_ticket_key_dec(ssl_conn, CBS_data(&name), | |
+ CBS_data(&cbs), &cipher_ctx, &hmac_ctx) <= 0 | |
+ || !CBS_skip(&cbs, EVP_CIPHER_CTX_iv_length(&cipher_ctx))) { | |
+ goto fail; | |
+ } | |
+ | |
+ mac_len = HMAC_size(&hmac_ctx); | |
+ | |
+ if (!HMAC_Update(&hmac_ctx, value.data, value.len - mac_len) | |
+ || !HMAC_Final(&hmac_ctx, mac, NULL)) { | |
+ ERR_clear_error(); /* Don't leave an error on the queue. */ | |
+ goto fail; | |
+ } | |
+ | |
+ if (CRYPTO_memcmp(mac, value.data + (value.len - mac_len), mac_len) != 0 | |
+ || !CBS_get_bytes(&cbs, &p, CBS_len(&cbs) - mac_len)) { | |
+ goto fail; | |
+ } | |
+ | |
+ if (!EVP_DecryptUpdate(&cipher_ctx, (uint8_t *)CBS_data(&p), &len1, CBS_data(&p), | |
+ (int)CBS_len(&p)) | |
+ || EVP_DecryptFinal_ex(&cipher_ctx, (uint8_t *)CBS_data(&p) + len1, &len2)) { | |
+ ERR_clear_error(); /* Don't leave an error on the queue. */ | |
+ goto fail; | |
} | |
*copy = 0; | |
- sess = SSL_SESSION_from_bytes(CBS_data(&cbs), plaintext_len); | |
+ sess = SSL_SESSION_from_bytes(CBS_data(&p), len1 + len2); | |
if (sess) { | |
ngx_memcpy(sess->session_id, id, len); | |
sess->session_id_length = len; | |
@@ -648,8 +658,14 @@ static ngx_ssl_session_t *ngx_http_ether_ssl_get_session_handler(ngx_ssl_conn_t | |
ERR_clear_error(); /* Don't leave an error on the queue. */ | |
} | |
- EVP_AEAD_CTX_cleanup(&aead_ctx); | |
+ EVP_CIPHER_CTX_cleanup(&cipher_ctx); | |
+ HMAC_CTX_cleanup(&hmac_ctx); | |
return sess; | |
+ | |
+fail: | |
+ EVP_CIPHER_CTX_cleanup(&cipher_ctx); | |
+ HMAC_CTX_cleanup(&hmac_ctx); | |
+ return NULL; | |
} | |
static void ngx_http_ether_ssl_remove_session_handler(SSL_CTX *ssl, ngx_ssl_session_t *sess) | |
diff --git a/ssl/patches/boringssl-aead-ticket-key.patch b/ssl/patches/boringssl-aead-ticket-key.patch | |
deleted file mode 100644 | |
index 82bfe4b..0000000 | |
--- a/ssl/patches/boringssl-aead-ticket-key.patch | |
+++ /dev/null | |
@@ -1,281 +0,0 @@ | |
-diff -rupN a/include/openssl/ssl.h b/include/openssl/ssl.h | |
---- a/include/openssl/ssl.h 2016-03-29 21:14:01.000000000 +1030 | |
-+++ b/include/openssl/ssl.h 2016-04-03 13:34:08.839228163 +0930 | |
-@@ -1775,7 +1775,10 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_ti | |
- * In both modes, |ctx| and |hmac_ctx| will already have been initialized with | |
- * |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback| | |
- * configures |hmac_ctx| with an HMAC digest and key, and configures |ctx| | |
-- * for encryption or decryption, based on the mode. | |
-+ * for encryption or decryption, based on the mode. If |callback| returns | |
-+ * TLSEXT_TICKET_CB_WANT_AEAD then |callback| will be called a second time | |
-+ * with |ctx| set to a |EVP_AEAD_CTX|* on which |EVP_AEAD_CTX_zero| has been | |
-+ * called, and |hmac_ctx| will be set to |SSL_magic_tlsext_ticket_key_cb_aead_ptr|. | |
- * | |
- * When encrypting a new ticket, |encrypt| will be one. It writes a public | |
- * 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length | |
-@@ -1796,6 +1799,17 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_ti | |
- EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, | |
- int encrypt)); | |
- | |
-+/* SSL_magic_tlsext_ticket_key_cb_aead_ptr returns a magic |HMAC_CTX|* which | |
-+ * indicates that the |ctx| variable passed into |callback| is not | |
-+ * a |EVP_CIPHER_CTX|* but is instead a |EVP_AEAD_CTX|*. */ | |
-+OPENSSL_EXPORT HMAC_CTX *SSL_magic_tlsext_ticket_key_cb_aead_ptr(void); | |
-+ | |
-+/* The return value of the ticket callback that requests AEAD operation. | |
-+ * | |
-+ * See |SSL_CTX_set_tlsext_ticket_key_cb| | |
-+ * and |SSL_magic_tlsext_ticket_key_cb_aead_ptr|. */ | |
-+#define TLSEXT_TICKET_CB_WANT_AEAD -0xAEAD | |
-+ | |
- | |
- /* Elliptic curve Diffie-Hellman. | |
- * | |
-diff -rupN a/ssl/s3_lib.c b/ssl/s3_lib.c | |
---- a/ssl/s3_lib.c 2016-03-29 21:14:01.000000000 +1030 | |
-+++ b/ssl/s3_lib.c 2016-04-03 12:42:09.671761047 +0930 | |
-@@ -162,6 +162,11 @@ | |
- #include "internal.h" | |
- | |
- | |
-+/* The address of this is a magic value, a pointer to which is returned by | |
-+ * SSL_magic_tlsext_ticket_key_cb_aead_ptr(). It indicated that AEAD mode is | |
-+ * being used. */ | |
-+static const char g_tlsext_ticket_cb_aead_magic = 0; | |
-+ | |
- int ssl3_supports_cipher(const SSL_CIPHER *cipher) { | |
- return 1; | |
- } | |
-@@ -442,6 +447,10 @@ int SSL_CTX_set_tlsext_ticket_key_cb( | |
- return 1; | |
- } | |
- | |
-+HMAC_CTX *SSL_magic_tlsext_ticket_key_cb_aead_ptr(void) { | |
-+ return (HMAC_CTX *)&g_tlsext_ticket_cb_aead_magic; | |
-+} | |
-+ | |
- struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *ssl) { | |
- if (ssl->cipher_list != NULL) { | |
- return ssl->cipher_list; | |
-diff -rupN a/ssl/s3_srvr.c b/ssl/s3_srvr.c | |
---- a/ssl/s3_srvr.c 2016-03-29 21:14:01.000000000 +1030 | |
-+++ b/ssl/s3_srvr.c 2016-04-03 14:04:06.560142579 +0930 | |
-@@ -1981,10 +1981,12 @@ int ssl3_send_server_certificate(SSL *ss | |
- /* send a new session ticket (not necessarily for a new session) */ | |
- int ssl3_send_new_session_ticket(SSL *ssl) { | |
- int ret = -1; | |
-+ int is_aead = 0; | |
- uint8_t *session = NULL; | |
- size_t session_len; | |
- EVP_CIPHER_CTX ctx; | |
- HMAC_CTX hctx; | |
-+ EVP_AEAD_CTX aead_ctx; | |
- | |
- EVP_CIPHER_CTX_init(&ctx); | |
- HMAC_CTX_init(&hctx); | |
-@@ -1994,12 +1996,16 @@ int ssl3_send_new_session_ticket(SSL *ss | |
- int len; | |
- unsigned int hlen; | |
- SSL_CTX *tctx = ssl->initial_ctx; | |
-- uint8_t iv[EVP_MAX_IV_LENGTH]; | |
-+ uint8_t iv[EVP_MAX_IV_LENGTH < EVP_AEAD_MAX_NONCE_LENGTH | |
-+ ? EVP_AEAD_MAX_NONCE_LENGTH : EVP_MAX_IV_LENGTH]; | |
- uint8_t key_name[16]; | |
- /* The maximum overhead of encrypting the session is 16 (key name) + IV + | |
- * one block of encryption overhead + HMAC. */ | |
-- const size_t max_ticket_overhead = | |
-- 16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE; | |
-+ const size_t max_ticket_overhead = 16 + | |
-+ (EVP_MAX_IV_LENGTH < EVP_AEAD_MAX_NONCE_LENGTH | |
-+ ? EVP_AEAD_MAX_NONCE_LENGTH : EVP_MAX_IV_LENGTH) + | |
-+ ((EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE) < EVP_AEAD_MAX_OVERHEAD | |
-+ ? EVP_AEAD_MAX_OVERHEAD : EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE); | |
- | |
- /* Serialize the SSL_SESSION to be encoded into the ticket. */ | |
- if (!SSL_SESSION_to_bytes_for_ticket(ssl->session, &session, | |
-@@ -2043,8 +2049,19 @@ int ssl3_send_new_session_ticket(SSL *ss | |
- /* Initialize HMAC and cipher contexts. If callback present it does all the | |
- * work otherwise use generated values from parent ctx. */ | |
- if (tctx->tlsext_ticket_key_cb) { | |
-- if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, &ctx, &hctx, | |
-- 1 /* encrypt */) < 0) { | |
-+ int cb_ret = tctx->tlsext_ticket_key_cb(ssl, key_name, iv, &ctx, &hctx, | |
-+ 1 /* encrypt */); | |
-+ if (cb_ret == TLSEXT_TICKET_CB_WANT_AEAD) { | |
-+ is_aead = 1; | |
-+ | |
-+ EVP_AEAD_CTX_zero(&aead_ctx); | |
-+ | |
-+ cb_ret = tctx->tlsext_ticket_key_cb(ssl, key_name, iv, | |
-+ (EVP_CIPHER_CTX *)&aead_ctx, | |
-+ SSL_magic_tlsext_ticket_key_cb_aead_ptr(), | |
-+ 1 /* encrypt */); | |
-+ } | |
-+ if (cb_ret < 0) { | |
- goto err; | |
- } | |
- } else { | |
-@@ -2069,25 +2086,43 @@ int ssl3_send_new_session_ticket(SSL *ss | |
- macstart = p; | |
- memcpy(p, key_name, 16); | |
- p += 16; | |
-- /* output IV */ | |
-- memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); | |
-- p += EVP_CIPHER_CTX_iv_length(&ctx); | |
-- /* Encrypt session data */ | |
-- if (!EVP_EncryptUpdate(&ctx, p, &len, session, session_len)) { | |
-- goto err; | |
-- } | |
-- p += len; | |
-- if (!EVP_EncryptFinal_ex(&ctx, p, &len)) { | |
-- goto err; | |
-- } | |
-- p += len; | |
- | |
-- if (!HMAC_Update(&hctx, macstart, p - macstart) || | |
-- !HMAC_Final(&hctx, p, &hlen)) { | |
-- goto err; | |
-+ if (is_aead) { | |
-+ size_t out_len; | |
-+ size_t nonce_len = EVP_AEAD_nonce_length(aead_ctx.aead); | |
-+ | |
-+ /* output nonce */ | |
-+ memcpy(p, iv, nonce_len); | |
-+ p += nonce_len; | |
-+ /* Encrypt session data */ | |
-+ if (!EVP_AEAD_CTX_seal(&aead_ctx, p, &out_len, | |
-+ session_len + (max_ticket_overhead - nonce_len - 16), | |
-+ iv, nonce_len, session, session_len, NULL, 0)) { | |
-+ goto err; | |
-+ } | |
-+ p += out_len; | |
-+ } else { | |
-+ /* output IV */ | |
-+ memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); | |
-+ p += EVP_CIPHER_CTX_iv_length(&ctx); | |
-+ /* Encrypt session data */ | |
-+ if (!EVP_EncryptUpdate(&ctx, p, &len, session, session_len)) { | |
-+ goto err; | |
-+ } | |
-+ p += len; | |
-+ if (!EVP_EncryptFinal_ex(&ctx, p, &len)) { | |
-+ goto err; | |
-+ } | |
-+ p += len; | |
-+ | |
-+ if (!HMAC_Update(&hctx, macstart, p - macstart) || | |
-+ !HMAC_Final(&hctx, p, &hlen)) { | |
-+ goto err; | |
-+ } | |
-+ | |
-+ p += hlen; | |
- } | |
- | |
-- p += hlen; | |
- /* Now write out lengths: p points to end of data written */ | |
- /* Total length */ | |
- len = p - ssl_handshake_start(ssl); | |
-@@ -2107,6 +2142,11 @@ err: | |
- OPENSSL_free(session); | |
- EVP_CIPHER_CTX_cleanup(&ctx); | |
- HMAC_CTX_cleanup(&hctx); | |
-+ | |
-+ if (is_aead) { | |
-+ EVP_AEAD_CTX_cleanup(&aead_ctx); | |
-+ } | |
-+ | |
- return ret; | |
- } | |
- | |
-diff -rupN a/ssl/t1_lib.c b/ssl/t1_lib.c | |
---- a/ssl/t1_lib.c 2016-03-29 21:14:01.000000000 +1030 | |
-+++ b/ssl/t1_lib.c 2016-04-03 13:34:11.115239449 +0930 | |
-@@ -2443,6 +2443,7 @@ int tls_process_ticket(SSL *ssl, SSL_SES | |
- size_t ticket_len, const uint8_t *session_id, | |
- size_t session_id_len) { | |
- int ret = 1; /* Most errors are non-fatal. */ | |
-+ int is_aead = 0; | |
- SSL_CTX *ssl_ctx = ssl->initial_ctx; | |
- uint8_t *plaintext = NULL; | |
- | |
-@@ -2450,6 +2451,7 @@ int tls_process_ticket(SSL *ssl, SSL_SES | |
- HMAC_CTX_init(&hmac_ctx); | |
- EVP_CIPHER_CTX cipher_ctx; | |
- EVP_CIPHER_CTX_init(&cipher_ctx); | |
-+ EVP_AEAD_CTX aead_ctx; | |
- | |
- *out_renew_ticket = 0; | |
- *out_session = NULL; | |
-@@ -2471,6 +2473,16 @@ int tls_process_ticket(SSL *ssl, SSL_SES | |
- int cb_ret = ssl_ctx->tlsext_ticket_key_cb( | |
- ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, &cipher_ctx, | |
- &hmac_ctx, 0 /* decrypt */); | |
-+ if (cb_ret == TLSEXT_TICKET_CB_WANT_AEAD) { | |
-+ is_aead = 1; | |
-+ | |
-+ EVP_AEAD_CTX_zero(&aead_ctx); | |
-+ | |
-+ cb_ret = ssl_ctx->tlsext_ticket_key_cb( | |
-+ ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, | |
-+ (EVP_CIPHER_CTX *)&aead_ctx, SSL_magic_tlsext_ticket_key_cb_aead_ptr(), | |
-+ 0 /* decrypt */); | |
-+ } | |
- if (cb_ret < 0) { | |
- ret = 0; | |
- goto done; | |
-@@ -2496,6 +2508,43 @@ int tls_process_ticket(SSL *ssl, SSL_SES | |
- goto done; | |
- } | |
- } | |
-+ | |
-+ if (is_aead) { | |
-+ const size_t nonce_len = EVP_AEAD_nonce_length(aead_ctx.aead); | |
-+ | |
-+ /* Decrypt the session data. */ | |
-+ const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + nonce_len; | |
-+ size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - nonce_len; | |
-+ plaintext = OPENSSL_malloc(ciphertext_len); | |
-+ if (plaintext == NULL) { | |
-+ ret = 0; | |
-+ goto done; | |
-+ } | |
-+ | |
-+ size_t plaintext_len; | |
-+ | |
-+ if (!EVP_AEAD_CTX_open(&aead_ctx, plaintext, &plaintext_len, ciphertext_len, | |
-+ iv, nonce_len, ciphertext, ciphertext_len, NULL, 0)) { | |
-+ goto done; | |
-+ } | |
-+ | |
-+ /* Decode the session. */ | |
-+ SSL_SESSION *session = SSL_SESSION_from_bytes(plaintext, plaintext_len); | |
-+ if (session == NULL) { | |
-+ ERR_clear_error(); /* Don't leave an error on the queue. */ | |
-+ goto done; | |
-+ } | |
-+ | |
-+ /* Copy the client's session ID into the new session, to denote the ticket has | |
-+ * been accepted. */ | |
-+ memcpy(session->session_id, session_id, session_id_len); | |
-+ session->session_id_length = session_id_len; | |
-+ | |
-+ *out_session = session; | |
-+ | |
-+ goto done; | |
-+ } | |
-+ | |
- size_t iv_len = EVP_CIPHER_CTX_iv_length(&cipher_ctx); | |
- | |
- /* Check the MAC at the end of the ticket. */ | |
-@@ -2549,6 +2598,11 @@ done: | |
- OPENSSL_free(plaintext); | |
- HMAC_CTX_cleanup(&hmac_ctx); | |
- EVP_CIPHER_CTX_cleanup(&cipher_ctx); | |
-+ | |
-+ if (is_aead) { | |
-+ EVP_AEAD_CTX_cleanup(&aead_ctx); | |
-+ } | |
-+ | |
- return ret; | |
- } | |
- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment