static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)
{
    size_t packlen = pkt->written - sub->pwritten;
    if (packlen == 0
            && (sub->flags & WPACKET_FLAGS_NON_ZERO_LENGTH) != 0)
        return 0;
    if (packlen == 0
            && sub->flags & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) {
        if (!doclose)
            return 0;
        if ((pkt->curr - sub->lenbytes) == sub->packet_len) {
            pkt->written -= sub->lenbytes;
            pkt->curr -= sub->lenbytes;
        }
        sub->packet_len = 0;
        sub->lenbytes = 0;
    }
    if (sub->lenbytes > 0
                && !put_value(&GETBUF(pkt)[sub->packet_len], packlen,
                              sub->lenbytes))
            return 0;
    if (doclose) {
        pkt->subs = sub->parent;
        OPENSSL_free(sub);
    }
    return 1;
}
['int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,\n                             const unsigned char *label, size_t labellen,\n                             const unsigned char *data, size_t datalen,\n                             unsigned char *out, size_t outlen)\n{\n    const unsigned char label_prefix[] = "tls13 ";\n    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);\n    int ret;\n    size_t hkdflabellen;\n    size_t hashlen;\n    unsigned char hkdflabel[sizeof(uint16_t) + sizeof(uint8_t) +\n                            + sizeof(label_prefix) + TLS13_MAX_LABEL_LEN\n                            + EVP_MAX_MD_SIZE];\n    WPACKET pkt;\n    if (pctx == NULL)\n        return 0;\n    hashlen = EVP_MD_size(md);\n    if (!WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0)\n            || !WPACKET_put_bytes_u16(&pkt, outlen)\n            || !WPACKET_start_sub_packet_u8(&pkt)\n            || !WPACKET_memcpy(&pkt, label_prefix, sizeof(label_prefix) - 1)\n            || !WPACKET_memcpy(&pkt, label, labellen)\n            || !WPACKET_close(&pkt)\n            || !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen)\n            || !WPACKET_get_total_written(&pkt, &hkdflabellen)\n            || !WPACKET_finish(&pkt)) {\n        EVP_PKEY_CTX_free(pctx);\n        WPACKET_cleanup(&pkt);\n        return 0;\n    }\n    ret = EVP_PKEY_derive_init(pctx) <= 0\n            || EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY)\n               <= 0\n            || EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0\n            || EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, hashlen) <= 0\n            || EVP_PKEY_CTX_add1_hkdf_info(pctx, hkdflabel, hkdflabellen) <= 0\n            || EVP_PKEY_derive(pctx, out, &outlen) <= 0;\n    EVP_PKEY_CTX_free(pctx);\n    return ret == 0;\n}', 'int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)\n{\n    WPACKET_SUB *sub;\n    unsigned char *lenchars;\n    if (!ossl_assert(pkt->subs != NULL))\n        return 0;\n    sub = OPENSSL_zalloc(sizeof(*sub));\n    if (sub == NULL)\n        return 0;\n    sub->parent = pkt->subs;\n    pkt->subs = sub;\n    sub->pwritten = pkt->written + lenbytes;\n    sub->lenbytes = lenbytes;\n    if (lenbytes == 0) {\n        sub->packet_len = 0;\n        return 1;\n    }\n    if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars))\n        return 0;\n    sub->packet_len = lenchars - GETBUF(pkt);\n    return 1;\n}', 'int WPACKET_close(WPACKET *pkt)\n{\n    if (pkt->subs == NULL || pkt->subs->parent == NULL)\n        return 0;\n    return wpacket_intern_close(pkt, pkt->subs, 1);\n}', 'static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)\n{\n    size_t packlen = pkt->written - sub->pwritten;\n    if (packlen == 0\n            && (sub->flags & WPACKET_FLAGS_NON_ZERO_LENGTH) != 0)\n        return 0;\n    if (packlen == 0\n            && sub->flags & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) {\n        if (!doclose)\n            return 0;\n        if ((pkt->curr - sub->lenbytes) == sub->packet_len) {\n            pkt->written -= sub->lenbytes;\n            pkt->curr -= sub->lenbytes;\n        }\n        sub->packet_len = 0;\n        sub->lenbytes = 0;\n    }\n    if (sub->lenbytes > 0\n                && !put_value(&GETBUF(pkt)[sub->packet_len], packlen,\n                              sub->lenbytes))\n            return 0;\n    if (doclose) {\n        pkt->subs = sub->parent;\n        OPENSSL_free(sub);\n    }\n    return 1;\n}']