int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
{
    const tls_curve_info *cinfo;
    if (curve[0])
        return 1;
    if ((curve[1] < 1) || ((size_t)curve[1] > OSSL_NELEM(nid_list)))
        return 0;
    cinfo = &nid_list[curve[1] - 1];
# ifdef OPENSSL_NO_EC2M
    if (cinfo->flags & TLS_CURVE_CHAR2)
        return 0;
# endif
    return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);
}
['static int final_key_share(SSL *s, unsigned int context, int sent, int *al)\n{\n    if (!SSL_IS_TLS13(s))\n        return 1;\n    if (!s->server\n            && !sent\n            && (!s->hit\n                || (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0)) {\n        *al = SSL_AD_HANDSHAKE_FAILURE;\n        SSLerr(SSL_F_FINAL_KEY_SHARE, SSL_R_NO_SUITABLE_KEY_SHARE);\n        return 0;\n    }\n    if (s->server && s->s3->peer_tmp == NULL) {\n        if (s->hello_retry_request == 0 && sent\n                && (!s->hit\n                    || (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE)\n                       != 0)) {\n            const unsigned char *pcurves, *pcurvestmp, *clntcurves;\n            size_t num_curves, clnt_num_curves, i;\n            unsigned int group_id = 0;\n            if (!tls1_get_curvelist(s, 1, &clntcurves, &clnt_num_curves)) {\n                *al = SSL_AD_INTERNAL_ERROR;\n                SSLerr(SSL_F_FINAL_KEY_SHARE, ERR_R_INTERNAL_ERROR);\n                return 0;\n            }\n            if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {\n                *al = SSL_AD_INTERNAL_ERROR;\n                SSLerr(SSL_F_FINAL_KEY_SHARE, ERR_R_INTERNAL_ERROR);\n                return 0;\n            }\n            for (i = 0, pcurvestmp = pcurves; i < num_curves;\n                 i++, pcurvestmp += 2) {\n                group_id = bytestogroup(pcurvestmp);\n                if (check_in_list(s, group_id, clntcurves, clnt_num_curves, 1))\n                    break;\n            }\n            if (i < num_curves) {\n                s->s3->group_id = group_id;\n                s->hello_retry_request = 1;\n                return 1;\n            }\n        }\n        if (!s->hit\n                || (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0) {\n            *al = SSL_AD_HANDSHAKE_FAILURE;\n            SSLerr(SSL_F_FINAL_KEY_SHARE, SSL_R_NO_SUITABLE_KEY_SHARE);\n            return 0;\n        }\n    }\n    if (s->server)\n        s->hello_retry_request = 0;\n    if (!sent && !s->server && !tls13_generate_handshake_secret(s, NULL, 0)) {\n        *al = SSL_AD_INTERNAL_ERROR;\n        SSLerr(SSL_F_FINAL_KEY_SHARE, ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    return 1;\n}', 'int check_in_list(SSL *s, unsigned int group_id, const unsigned char *groups,\n                  size_t num_groups, int checkallow)\n{\n    size_t i;\n    if (groups == NULL || num_groups == 0)\n        return 0;\n    for (i = 0; i < num_groups; i++, groups += 2) {\n        unsigned int share_id = (groups[0] << 8) | (groups[1]);\n        if (group_id == share_id\n                && (!checkallow\n                    || tls_curve_allowed(s, groups, SSL_SECOP_CURVE_CHECK))) {\n            return 1;\n        }\n    }\n    return 0;\n}', 'int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)\n{\n    const tls_curve_info *cinfo;\n    if (curve[0])\n        return 1;\n    if ((curve[1] < 1) || ((size_t)curve[1] > OSSL_NELEM(nid_list)))\n        return 0;\n    cinfo = &nid_list[curve[1] - 1];\n# ifdef OPENSSL_NO_EC2M\n    if (cinfo->flags & TLS_CURVE_CHAR2)\n        return 0;\n# endif\n    return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);\n}']