static OSSL_PARAM *param_template_to_param(PARAMS_TEMPLATE *tmpl, size_t *sz)
{
    size_t i;
    void *buf;
    OSSL_PARAM *param = NULL;
    unsigned char *currbuf = NULL;

    if (tmpl->totsz == 0)
        return NULL;

    /* Add some space for the end of OSSL_PARAM marker */
    tmpl->totsz += sizeof(*param);

    if (tmpl->ispublic)
        buf = OPENSSL_zalloc(tmpl->totsz);
    else
        buf = OPENSSL_secure_zalloc(tmpl->totsz);
    if (buf == NULL)
        return NULL;
    param = buf;

    currbuf = (unsigned char *)buf + (sizeof(*param) * (tmpl->curr + 1));

    for (i = 0; i < tmpl->curr; i++) {
        if (!ossl_assert((currbuf - (unsigned char *)buf )
                         + tmpl->params[i].bufsz <= tmpl->totsz))
            goto err;
        if (BN_bn2nativepad(tmpl->params[i].bnparam, currbuf,
                            tmpl->params[i].bufsz) < 0)
            goto err;
        param[i] = OSSL_PARAM_construct_BN(tmpl->params[i].key, currbuf,
                                           tmpl->params[i].bufsz);
        currbuf += tmpl->params[i].bufsz;
    }
    param[i] = OSSL_PARAM_construct_end();

    if (sz != NULL)
        *sz = tmpl->totsz;
    return param;

 err:
    if (tmpl->ispublic)
        OPENSSL_free(param);
    else
        OPENSSL_clear_free(param, tmpl->totsz);
    return NULL;
}