int tls_construct_new_session_ticket(SSL *s)
{
    unsigned char *senc = NULL;
    EVP_CIPHER_CTX *ctx;
    HMAC_CTX *hctx = NULL;
    unsigned char *p, *macstart;
    const unsigned char *const_p;
    int len, slen_full, slen;
    SSL_SESSION *sess;
    unsigned int hlen;
    SSL_CTX *tctx = s->initial_ctx;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    unsigned char key_name[TLSEXT_KEYNAME_LENGTH];
    int iv_len;
    slen_full = i2d_SSL_SESSION(s->session, NULL);
    if (slen_full == 0 || slen_full > 0xFF00) {
        ossl_statem_set_error(s);
        return 0;
    }
    senc = OPENSSL_malloc(slen_full);
    if (senc == NULL) {
        ossl_statem_set_error(s);
        return 0;
    }
    ctx = EVP_CIPHER_CTX_new();
    hctx = HMAC_CTX_new();
    p = senc;
    if (!i2d_SSL_SESSION(s->session, &p))
        goto err;
    const_p = senc;
    sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
    if (sess == NULL)
        goto err;
    sess->session_id_length = 0;
    slen = i2d_SSL_SESSION(sess, NULL);
    if (slen == 0 || slen > slen_full) {
        SSL_SESSION_free(sess);
        goto err;
    }
    p = senc;
    if (!i2d_SSL_SESSION(sess, &p)) {
        SSL_SESSION_free(sess);
        goto err;
    }
    SSL_SESSION_free(sess);
    if (!BUF_MEM_grow(s->init_buf,
                      SSL_HM_HEADER_LENGTH(s) + 6 + sizeof(key_name) +
                      EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
                      EVP_MAX_MD_SIZE + slen))
        goto err;
    p = ssl_handshake_start(s);
    if (tctx->tlsext_ticket_key_cb) {
        int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, ctx,
                                             hctx, 1);
        if (ret == 0) {
            l2n(0, p);
            s2n(0, p);
            if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, p - ssl_handshake_start(s)))
                goto err;
            OPENSSL_free(senc);
            EVP_CIPHER_CTX_free(ctx);
            HMAC_CTX_free(hctx);
            return 1;
        }
        if (ret < 0)
            goto err;
        iv_len = EVP_CIPHER_CTX_iv_length(ctx);
    } else {
        const EVP_CIPHER *cipher = EVP_aes_256_cbc();
        iv_len = EVP_CIPHER_iv_length(cipher);
        if (RAND_bytes(iv, iv_len) <= 0)
            goto err;
        if (!EVP_EncryptInit_ex(ctx, cipher, NULL,
                                tctx->tlsext_tick_aes_key, iv))
            goto err;
        if (!HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key,
                          sizeof(tctx->tlsext_tick_hmac_key),
                          EVP_sha256(), NULL))
            goto err;
        memcpy(key_name, tctx->tlsext_tick_key_name,
               sizeof(tctx->tlsext_tick_key_name));
    }
    l2n(s->hit ? 0 : s->session->timeout, p);
    p += 2;
    macstart = p;
    memcpy(p, key_name, sizeof(key_name));
    p += sizeof(key_name);
    memcpy(p, iv, iv_len);
    p += iv_len;
    if (!EVP_EncryptUpdate(ctx, p, &len, senc, slen))
        goto err;
    p += len;
    if (!EVP_EncryptFinal(ctx, p, &len))
        goto err;
    p += len;
    if (!HMAC_Update(hctx, macstart, p - macstart))
        goto err;
    if (!HMAC_Final(hctx, p, &hlen))
        goto err;
    EVP_CIPHER_CTX_free(ctx);
    HMAC_CTX_free(hctx);
    ctx = NULL;
    hctx = NULL;
    p += hlen;
    len = p - ssl_handshake_start(s);
    p = ssl_handshake_start(s) + 4;
    s2n(len - 6, p);
    if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len))
        goto err;
    OPENSSL_free(senc);
    return 1;
 err:
    OPENSSL_free(senc);
    EVP_CIPHER_CTX_free(ctx);
    HMAC_CTX_free(hctx);
    ossl_statem_set_error(s);
    return 0;
}
['int tls_construct_new_session_ticket(SSL *s)\n{\n    unsigned char *senc = NULL;\n    EVP_CIPHER_CTX *ctx;\n    HMAC_CTX *hctx = NULL;\n    unsigned char *p, *macstart;\n    const unsigned char *const_p;\n    int len, slen_full, slen;\n    SSL_SESSION *sess;\n    unsigned int hlen;\n    SSL_CTX *tctx = s->initial_ctx;\n    unsigned char iv[EVP_MAX_IV_LENGTH];\n    unsigned char key_name[TLSEXT_KEYNAME_LENGTH];\n    int iv_len;\n    slen_full = i2d_SSL_SESSION(s->session, NULL);\n    if (slen_full == 0 || slen_full > 0xFF00) {\n        ossl_statem_set_error(s);\n        return 0;\n    }\n    senc = OPENSSL_malloc(slen_full);\n    if (senc == NULL) {\n        ossl_statem_set_error(s);\n        return 0;\n    }\n    ctx = EVP_CIPHER_CTX_new();\n    hctx = HMAC_CTX_new();\n    p = senc;\n    if (!i2d_SSL_SESSION(s->session, &p))\n        goto err;\n    const_p = senc;\n    sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);\n    if (sess == NULL)\n        goto err;\n    sess->session_id_length = 0;\n    slen = i2d_SSL_SESSION(sess, NULL);\n    if (slen == 0 || slen > slen_full) {\n        SSL_SESSION_free(sess);\n        goto err;\n    }\n    p = senc;\n    if (!i2d_SSL_SESSION(sess, &p)) {\n        SSL_SESSION_free(sess);\n        goto err;\n    }\n    SSL_SESSION_free(sess);\n    if (!BUF_MEM_grow(s->init_buf,\n                      SSL_HM_HEADER_LENGTH(s) + 6 + sizeof(key_name) +\n                      EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +\n                      EVP_MAX_MD_SIZE + slen))\n        goto err;\n    p = ssl_handshake_start(s);\n    if (tctx->tlsext_ticket_key_cb) {\n        int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, ctx,\n                                             hctx, 1);\n        if (ret == 0) {\n            l2n(0, p);\n            s2n(0, p);\n            if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, p - ssl_handshake_start(s)))\n                goto err;\n            OPENSSL_free(senc);\n            EVP_CIPHER_CTX_free(ctx);\n            HMAC_CTX_free(hctx);\n            return 1;\n        }\n        if (ret < 0)\n            goto err;\n        iv_len = EVP_CIPHER_CTX_iv_length(ctx);\n    } else {\n        const EVP_CIPHER *cipher = EVP_aes_256_cbc();\n        iv_len = EVP_CIPHER_iv_length(cipher);\n        if (RAND_bytes(iv, iv_len) <= 0)\n            goto err;\n        if (!EVP_EncryptInit_ex(ctx, cipher, NULL,\n                                tctx->tlsext_tick_aes_key, iv))\n            goto err;\n        if (!HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key,\n                          sizeof(tctx->tlsext_tick_hmac_key),\n                          EVP_sha256(), NULL))\n            goto err;\n        memcpy(key_name, tctx->tlsext_tick_key_name,\n               sizeof(tctx->tlsext_tick_key_name));\n    }\n    l2n(s->hit ? 0 : s->session->timeout, p);\n    p += 2;\n    macstart = p;\n    memcpy(p, key_name, sizeof(key_name));\n    p += sizeof(key_name);\n    memcpy(p, iv, iv_len);\n    p += iv_len;\n    if (!EVP_EncryptUpdate(ctx, p, &len, senc, slen))\n        goto err;\n    p += len;\n    if (!EVP_EncryptFinal(ctx, p, &len))\n        goto err;\n    p += len;\n    if (!HMAC_Update(hctx, macstart, p - macstart))\n        goto err;\n    if (!HMAC_Final(hctx, p, &hlen))\n        goto err;\n    EVP_CIPHER_CTX_free(ctx);\n    HMAC_CTX_free(hctx);\n    ctx = NULL;\n    hctx = NULL;\n    p += hlen;\n    len = p - ssl_handshake_start(s);\n    p = ssl_handshake_start(s) + 4;\n    s2n(len - 6, p);\n    if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len))\n        goto err;\n    OPENSSL_free(senc);\n    return 1;\n err:\n    OPENSSL_free(senc);\n    EVP_CIPHER_CTX_free(ctx);\n    HMAC_CTX_free(hctx);\n    ossl_statem_set_error(s);\n    return 0;\n}']