Skip to content

Instantly share code, notes, and snippets.

@tmthrgd
Created March 8, 2017 10:25
Show Gist options
  • Save tmthrgd/b6f9bd53e75f01738255c2be0497ac1c to your computer and use it in GitHub Desktop.
Save tmthrgd/b6f9bd53e75f01738255c2be0497ac1c to your computer and use it in GitHub Desktop.
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