int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                          size_t chainidx)
{
    unsigned int format, version, key_share, group_id;
    EVP_MD_CTX *hctx;
    EVP_PKEY *pkey;
    PACKET cookie, raw, chhash, appcookie;
    WPACKET hrrpkt;
    const unsigned char *data, *mdin, *ciphdata;
    unsigned char hmac[SHA256_DIGEST_LENGTH];
    unsigned char hrr[MAX_HRR_SIZE];
    size_t rawlen, hmaclen, hrrlen, ciphlen;
    unsigned long tm, now;
    if (s->ctx->verify_stateless_cookie_cb == NULL
            || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0)
        return 1;
    if (!PACKET_as_length_prefixed_2(pkt, &cookie)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    raw = cookie;
    data = PACKET_data(&raw);
    rawlen = PACKET_remaining(&raw);
    if (rawlen < SHA256_DIGEST_LENGTH
            || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    mdin = PACKET_data(&raw);
    hctx = EVP_MD_CTX_create();
    pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
                                        s->session_ctx->ext.cookie_hmac_key,
                                        sizeof(s->session_ctx->ext
                                               .cookie_hmac_key));
    if (hctx == NULL || pkey == NULL) {
        EVP_MD_CTX_free(hctx);
        EVP_PKEY_free(pkey);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_MALLOC_FAILURE);
        return 0;
    }
    hmaclen = SHA256_DIGEST_LENGTH;
    if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0
            || EVP_DigestSign(hctx, hmac, &hmaclen, data,
                              rawlen - SHA256_DIGEST_LENGTH) <= 0
            || hmaclen != SHA256_DIGEST_LENGTH) {
        EVP_MD_CTX_free(hctx);
        EVP_PKEY_free(pkey);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    EVP_MD_CTX_free(hctx);
    EVP_PKEY_free(pkey);
    if (CRYPTO_memcmp(hmac, mdin, SHA256_DIGEST_LENGTH) != 0) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_COOKIE_MISMATCH);
        return 0;
    }
    if (!PACKET_get_net_2(&cookie, &format)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    if (format != COOKIE_STATE_FORMAT_VERSION)
        return 1;
    if (!PACKET_get_net_2(&cookie, &version)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    if (version != TLS1_3_VERSION) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
        return 0;
    }
    if (!PACKET_get_net_2(&cookie, &group_id)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    ciphdata = PACKET_data(&cookie);
    if (!PACKET_forward(&cookie, 2)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    if (group_id != s->s3->group_id
            || s->s3->tmp.new_cipher
               != ssl_get_cipher_by_char(s, ciphdata, 0)) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_BAD_CIPHER);
        return 0;
    }
    if (!PACKET_get_1(&cookie, &key_share)
            || !PACKET_get_net_4(&cookie, &tm)
            || !PACKET_get_length_prefixed_2(&cookie, &chhash)
            || !PACKET_get_length_prefixed_1(&cookie, &appcookie)
            || PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    now = (unsigned long)time(NULL);
    if (tm > now || (now - tm) > 600) {
        return 1;
    }
    if (s->ctx->verify_stateless_cookie_cb(s, PACKET_data(&appcookie),
                                     PACKET_remaining(&appcookie)) == 0) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_COOKIE_MISMATCH);
        return 0;
    }
    if (!WPACKET_init_static_len(&hrrpkt, hrr, sizeof(hrr), 0)) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO)
            || !WPACKET_start_sub_packet_u24(&hrrpkt)
            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_2_VERSION)
            || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE)
            || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id,
                                      s->tmp_session_id_len)
            || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, &hrrpkt,
                                              &ciphlen)
            || !WPACKET_put_bytes_u8(&hrrpkt, 0)
            || !WPACKET_start_sub_packet_u16(&hrrpkt)) {
        WPACKET_cleanup(&hrrpkt);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions)
            || !WPACKET_start_sub_packet_u16(&hrrpkt)
            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_3_VERSION_DRAFT)
            || !WPACKET_close(&hrrpkt)) {
        WPACKET_cleanup(&hrrpkt);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (key_share) {
        if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_key_share)
                || !WPACKET_start_sub_packet_u16(&hrrpkt)
                || !WPACKET_put_bytes_u16(&hrrpkt, s->s3->group_id)
                || !WPACKET_close(&hrrpkt)) {
            WPACKET_cleanup(&hrrpkt);
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                     ERR_R_INTERNAL_ERROR);
            return 0;
        }
    }
    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_cookie)
            || !WPACKET_start_sub_packet_u16(&hrrpkt)
            || !WPACKET_sub_memcpy_u16(&hrrpkt, data, rawlen)
            || !WPACKET_close(&hrrpkt)
            || !WPACKET_close(&hrrpkt)
            || !WPACKET_close(&hrrpkt)
            || !WPACKET_get_total_written(&hrrpkt, &hrrlen)
            || !WPACKET_finish(&hrrpkt)) {
        WPACKET_cleanup(&hrrpkt);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (!create_synthetic_message_hash(s, PACKET_data(&chhash),
                                       PACKET_remaining(&chhash), hrr,
                                       hrrlen)) {
        return 0;
    }
    s->hello_retry_request = 1;
    s->ext.cookieok = 1;
    return 1;
}
['int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,\n                          size_t chainidx)\n{\n    unsigned int format, version, key_share, group_id;\n    EVP_MD_CTX *hctx;\n    EVP_PKEY *pkey;\n    PACKET cookie, raw, chhash, appcookie;\n    WPACKET hrrpkt;\n    const unsigned char *data, *mdin, *ciphdata;\n    unsigned char hmac[SHA256_DIGEST_LENGTH];\n    unsigned char hrr[MAX_HRR_SIZE];\n    size_t rawlen, hmaclen, hrrlen, ciphlen;\n    unsigned long tm, now;\n    if (s->ctx->verify_stateless_cookie_cb == NULL\n            || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0)\n        return 1;\n    if (!PACKET_as_length_prefixed_2(pkt, &cookie)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    raw = cookie;\n    data = PACKET_data(&raw);\n    rawlen = PACKET_remaining(&raw);\n    if (rawlen < SHA256_DIGEST_LENGTH\n            || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    mdin = PACKET_data(&raw);\n    hctx = EVP_MD_CTX_create();\n    pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,\n                                        s->session_ctx->ext.cookie_hmac_key,\n                                        sizeof(s->session_ctx->ext\n                                               .cookie_hmac_key));\n    if (hctx == NULL || pkey == NULL) {\n        EVP_MD_CTX_free(hctx);\n        EVP_PKEY_free(pkey);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_MALLOC_FAILURE);\n        return 0;\n    }\n    hmaclen = SHA256_DIGEST_LENGTH;\n    if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0\n            || EVP_DigestSign(hctx, hmac, &hmaclen, data,\n                              rawlen - SHA256_DIGEST_LENGTH) <= 0\n            || hmaclen != SHA256_DIGEST_LENGTH) {\n        EVP_MD_CTX_free(hctx);\n        EVP_PKEY_free(pkey);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    EVP_MD_CTX_free(hctx);\n    EVP_PKEY_free(pkey);\n    if (CRYPTO_memcmp(hmac, mdin, SHA256_DIGEST_LENGTH) != 0) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_COOKIE_MISMATCH);\n        return 0;\n    }\n    if (!PACKET_get_net_2(&cookie, &format)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    if (format != COOKIE_STATE_FORMAT_VERSION)\n        return 1;\n    if (!PACKET_get_net_2(&cookie, &version)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    if (version != TLS1_3_VERSION) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_BAD_PROTOCOL_VERSION_NUMBER);\n        return 0;\n    }\n    if (!PACKET_get_net_2(&cookie, &group_id)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    ciphdata = PACKET_data(&cookie);\n    if (!PACKET_forward(&cookie, 2)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    if (group_id != s->s3->group_id\n            || s->s3->tmp.new_cipher\n               != ssl_get_cipher_by_char(s, ciphdata, 0)) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_BAD_CIPHER);\n        return 0;\n    }\n    if (!PACKET_get_1(&cookie, &key_share)\n            || !PACKET_get_net_4(&cookie, &tm)\n            || !PACKET_get_length_prefixed_2(&cookie, &chhash)\n            || !PACKET_get_length_prefixed_1(&cookie, &appcookie)\n            || PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    now = (unsigned long)time(NULL);\n    if (tm > now || (now - tm) > 600) {\n        return 1;\n    }\n    if (s->ctx->verify_stateless_cookie_cb(s, PACKET_data(&appcookie),\n                                     PACKET_remaining(&appcookie)) == 0) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_COOKIE_MISMATCH);\n        return 0;\n    }\n    if (!WPACKET_init_static_len(&hrrpkt, hrr, sizeof(hrr), 0)) {\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO)\n            || !WPACKET_start_sub_packet_u24(&hrrpkt)\n            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_2_VERSION)\n            || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE)\n            || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id,\n                                      s->tmp_session_id_len)\n            || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, &hrrpkt,\n                                              &ciphlen)\n            || !WPACKET_put_bytes_u8(&hrrpkt, 0)\n            || !WPACKET_start_sub_packet_u16(&hrrpkt)) {\n        WPACKET_cleanup(&hrrpkt);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions)\n            || !WPACKET_start_sub_packet_u16(&hrrpkt)\n            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_3_VERSION_DRAFT)\n            || !WPACKET_close(&hrrpkt)) {\n        WPACKET_cleanup(&hrrpkt);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (key_share) {\n        if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_key_share)\n                || !WPACKET_start_sub_packet_u16(&hrrpkt)\n                || !WPACKET_put_bytes_u16(&hrrpkt, s->s3->group_id)\n                || !WPACKET_close(&hrrpkt)) {\n            WPACKET_cleanup(&hrrpkt);\n            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                     ERR_R_INTERNAL_ERROR);\n            return 0;\n        }\n    }\n    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_cookie)\n            || !WPACKET_start_sub_packet_u16(&hrrpkt)\n            || !WPACKET_sub_memcpy_u16(&hrrpkt, data, rawlen)\n            || !WPACKET_close(&hrrpkt)\n            || !WPACKET_close(&hrrpkt)\n            || !WPACKET_close(&hrrpkt)\n            || !WPACKET_get_total_written(&hrrpkt, &hrrlen)\n            || !WPACKET_finish(&hrrpkt)) {\n        WPACKET_cleanup(&hrrpkt);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (!create_synthetic_message_hash(s, PACKET_data(&chhash),\n                                       PACKET_remaining(&chhash), hrr,\n                                       hrrlen)) {\n        return 0;\n    }\n    s->hello_retry_request = 1;\n    s->ext.cookieok = 1;\n    return 1;\n}', 'static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)\n{\n    return pkt->curr;\n}', 'static ossl_inline size_t PACKET_remaining(const PACKET *pkt)\n{\n    return pkt->remaining;\n}', 'static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)\n{\n    if (PACKET_remaining(pkt) < len)\n        return 0;\n    packet_forward(pkt, len);\n    return 1;\n}', 'static ossl_inline void packet_forward(PACKET *pkt, size_t len)\n{\n    pkt->curr += len;\n    pkt->remaining -= len;\n}', 'EVP_MD_CTX *EVP_MD_CTX_new(void)\n{\n    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));\n}', 'void *CRYPTO_zalloc(size_t num, const char *file, int line)\n{\n    void *ret = CRYPTO_malloc(num, file, line);\n    FAILTEST();\n    if (ret != NULL)\n        memset(ret, 0, num);\n    return ret;\n}', 'void *CRYPTO_malloc(size_t num, const char *file, int line)\n{\n    void *ret = NULL;\n    INCREMENT(malloc_count);\n    if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)\n        return malloc_impl(num, file, line);\n    if (num == 0)\n        return NULL;\n    FAILTEST();\n    if (allow_customize) {\n        allow_customize = 0;\n    }\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);\n        ret = malloc(num);\n        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);\n    } else {\n        ret = malloc(num);\n    }\n#else\n    (void)(file); (void)(line);\n    ret = malloc(num);\n#endif\n    return ret;\n}', 'EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,\n                                       const unsigned char *priv,\n                                       size_t len)\n{\n    EVP_PKEY *ret = EVP_PKEY_new();\n    if (ret == NULL\n            || !pkey_set_type(ret, e, type, NULL, -1)) {\n        goto err;\n    }\n    if (ret->ameth->set_priv_key == NULL) {\n        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY,\n               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);\n        goto err;\n    }\n    if (!ret->ameth->set_priv_key(ret, priv, len)) {\n        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, EVP_R_KEY_SETUP_FAILED);\n        goto err;\n    }\n    return ret;\n err:\n    EVP_PKEY_free(ret);\n    return NULL;\n}', 'void EVP_PKEY_free(EVP_PKEY *x)\n{\n    int i;\n    if (x == NULL)\n        return;\n    CRYPTO_DOWN_REF(&x->references, &i, x->lock);\n    REF_PRINT_COUNT("EVP_PKEY", x);\n    if (i > 0)\n        return;\n    REF_ASSERT_ISNT(i < 0);\n    EVP_PKEY_free_it(x);\n    CRYPTO_THREAD_lock_free(x->lock);\n    sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);\n    OPENSSL_free(x);\n}', 'void EVP_MD_CTX_free(EVP_MD_CTX *ctx)\n{\n    EVP_MD_CTX_reset(ctx);\n    OPENSSL_free(ctx);\n}', 'void CRYPTO_free(void *str, const char *file, int line)\n{\n    INCREMENT(free_count);\n    if (free_impl != NULL && free_impl != &CRYPTO_free) {\n        free_impl(str, file, line);\n        return;\n    }\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_free(str, 0, file, line);\n        free(str);\n        CRYPTO_mem_debug_free(str, 1, file, line);\n    } else {\n        free(str);\n    }\n#else\n    free(str);\n#endif\n}']