void BN_CTX_end(BN_CTX *ctx)
	{
	if (ctx == NULL) return;
	assert(ctx->depth > 0);
	if (ctx->depth == 0)
		BN_CTX_start(ctx);
	ctx->too_many = 0;
	ctx->depth--;
	if (ctx->depth < BN_CTX_NUM_POS)
		ctx->tos = ctx->pos[ctx->depth];
	}
['EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)\n{\n\tEVP_PKEY *pkey = NULL;\n#ifndef NO_RSA\n\tRSA *rsa = NULL;\n#endif\n#ifndef NO_DSA\n\tDSA *dsa = NULL;\n\tASN1_INTEGER *privkey;\n\tASN1_TYPE *t1, *t2, *param = NULL;\n\tSTACK *ndsa = NULL;\n\tBN_CTX *ctx = NULL;\n\tint plen;\n#endif\n\tX509_ALGOR *a;\n\tunsigned char *p;\n\tint pkeylen;\n\tchar obj_tmp[80];\n\tif(p8->pkey->type == V_ASN1_OCTET_STRING) {\n\t\tp8->broken = PKCS8_OK;\n\t\tp = p8->pkey->value.octet_string->data;\n\t\tpkeylen = p8->pkey->value.octet_string->length;\n\t} else {\n\t\tp8->broken = PKCS8_NO_OCTET;\n\t\tp = p8->pkey->value.sequence->data;\n\t\tpkeylen = p8->pkey->value.sequence->length;\n\t}\n\tif (!(pkey = EVP_PKEY_new())) {\n\t\tEVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);\n\t\treturn NULL;\n\t}\n\ta = p8->pkeyalg;\n\tswitch (OBJ_obj2nid(a->algorithm))\n\t{\n#ifndef NO_RSA\n\t\tcase NID_rsaEncryption:\n\t\tif (!(rsa = d2i_RSAPrivateKey (NULL, &p, pkeylen))) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);\n\t\t\treturn NULL;\n\t\t}\n\t\tEVP_PKEY_assign_RSA (pkey, rsa);\n\t\tbreak;\n#endif\n#ifndef NO_DSA\n\t\tcase NID_dsa:\n\t\tif(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {\n\t\t    if(!(ndsa = ASN1_seq_unpack(p, pkeylen,\n\t\t\t\t\t(char *(*)())d2i_ASN1_TYPE,\n\t\t\t\t\t\t\t ASN1_TYPE_free))) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);\n\t\t\tgoto dsaerr;\n\t\t    }\n\t\t    if(sk_num(ndsa) != 2 ) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);\n\t\t\tgoto dsaerr;\n\t\t    }\n\t\t    t1 = (ASN1_TYPE *)sk_value(ndsa, 0);\n\t\t    t2 = (ASN1_TYPE *)sk_value(ndsa, 1);\n\t\t    if(t1->type == V_ASN1_SEQUENCE) {\n\t\t\tp8->broken = PKCS8_EMBEDDED_PARAM;\n\t\t\tparam = t1;\n\t\t    } else if(a->parameter->type == V_ASN1_SEQUENCE) {\n\t\t\tp8->broken = PKCS8_NS_DB;\n\t\t\tparam = a->parameter;\n\t\t    } else {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);\n\t\t\tgoto dsaerr;\n\t\t    }\n\t\t    if(t2->type != V_ASN1_INTEGER) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);\n\t\t\tgoto dsaerr;\n\t\t    }\n\t\t    privkey = t2->value.integer;\n\t\t} else if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);\n\t\t\tgoto dsaerr;\n\t\t}\n\t\tp = param->value.sequence->data;\n\t\tplen = param->value.sequence->length;\n\t\tif (!(dsa = d2i_DSAparams (NULL, &p, plen))) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);\n\t\t\tgoto dsaerr;\n\t\t}\n\t\tif (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);\n\t\t\tgoto dsaerr;\n\t\t}\n\t\tif (!(dsa->pub_key = BN_new())) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);\n\t\t\tgoto dsaerr;\n\t\t}\n\t\tif (!(ctx = BN_CTX_new())) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);\n\t\t\tgoto dsaerr;\n\t\t}\n\t\tif (!BN_mod_exp(dsa->pub_key, dsa->g,\n\t\t\t\t\t\t dsa->priv_key, dsa->p, ctx)) {\n\t\t\tEVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);\n\t\t\tgoto dsaerr;\n\t\t}\n\t\tEVP_PKEY_assign_DSA(pkey, dsa);\n\t\tBN_CTX_free (ctx);\n\t\tsk_pop_free(ndsa, ASN1_TYPE_free);\n\t\tbreak;\n\t\tdsaerr:\n\t\tBN_CTX_free (ctx);\n\t\tsk_pop_free(ndsa, ASN1_TYPE_free);\n\t\tDSA_free(dsa);\n\t\tEVP_PKEY_free(pkey);\n\t\treturn NULL;\n\t\tbreak;\n#endif\n\t\tdefault:\n\t\tEVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);\n\t\tif (!a->algorithm) strcpy (obj_tmp, "NULL");\n\t\telse i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);\n\t\tERR_add_error_data(2, "TYPE=", obj_tmp);\n\t\tEVP_PKEY_free (pkey);\n\t\treturn NULL;\n\t}\n\treturn pkey;\n}', 'BN_CTX *BN_CTX_new(void)\n\t{\n\tBN_CTX *ret;\n\tret=(BN_CTX *)Malloc(sizeof(BN_CTX));\n\tif (ret == NULL)\n\t\t{\n\t\tBNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);\n\t\treturn(NULL);\n\t\t}\n\tBN_CTX_init(ret);\n\tret->flags=BN_FLG_MALLOCED;\n\treturn(ret);\n\t}', 'void BN_CTX_init(BN_CTX *ctx)\n\t{\n\tint i;\n\tctx->tos = 0;\n\tctx->flags = 0;\n\tctx->depth = 0;\n\tctx->too_many = 0;\n\tfor (i = 0; i < BN_CTX_NUM; i++)\n\t\tBN_init(&(ctx->bn[i]));\n\t}', 'int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,\n\t       BN_CTX *ctx)\n\t{\n\tint ret;\n\tbn_check_top(a);\n\tbn_check_top(p);\n\tbn_check_top(m);\n#ifdef ATALLA\n\tif(BN_mod_exp_atalla(r,a,p,m))\n\t    return 1;\n\ttried_atalla=1;\n#endif\n#ifdef MONT_MUL_MOD\n\tif (BN_is_odd(m))\n\t\t{ ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); }\n\telse\n#endif\n#ifdef RECP_MUL_MOD\n\t\t{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }\n#else\n\t\t{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }\n#endif\n#ifdef ATALLA\n\ttried_atalla=0;\n#endif\n\treturn(ret);\n\t}', 'int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,\n\t\t    const BIGNUM *m, BN_CTX *ctx)\n\t{\n\tint i,j,bits,ret=0,wstart,wend,window,wvalue;\n\tint start=1,ts=0;\n\tBIGNUM *aa;\n\tBIGNUM val[TABLE_SIZE];\n\tBN_RECP_CTX recp;\n\tbits=BN_num_bits(p);\n\tif (bits == 0)\n\t\t{\n\t\tBN_one(r);\n\t\treturn(1);\n\t\t}\n\tBN_CTX_start(ctx);\n\tif ((aa = BN_CTX_get(ctx)) == NULL) goto err;\n\tBN_RECP_CTX_init(&recp);\n\tif (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;\n\tBN_init(&(val[0]));\n\tts=1;\n\tif (!BN_mod(&(val[0]),a,m,ctx)) goto err;\n\tif (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))\n\t\tgoto err;\n\tif (bits <= 17)\n\t\twindow=1;\n\telse if (bits >= 256)\n\t\twindow=5;\n\telse if (bits >= 128)\n\t\twindow=4;\n\telse\n\t\twindow=3;\n\tj=1<<(window-1);\n\tfor (i=1; i<j; i++)\n\t\t{\n\t\tBN_init(&val[i]);\n\t\tif (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))\n\t\t\tgoto err;\n\t\t}\n\tts=i;\n\tstart=1;\n\twvalue=0;\n\twstart=bits-1;\n\twend=0;\n\tif (!BN_one(r)) goto err;\n\tfor (;;)\n\t\t{\n\t\tif (BN_is_bit_set(p,wstart) == 0)\n\t\t\t{\n\t\t\tif (!start)\n\t\t\t\tif (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))\n\t\t\t\tgoto err;\n\t\t\tif (wstart == 0) break;\n\t\t\twstart--;\n\t\t\tcontinue;\n\t\t\t}\n\t\tj=wstart;\n\t\twvalue=1;\n\t\twend=0;\n\t\tfor (i=1; i<window; i++)\n\t\t\t{\n\t\t\tif (wstart-i < 0) break;\n\t\t\tif (BN_is_bit_set(p,wstart-i))\n\t\t\t\t{\n\t\t\t\twvalue<<=(i-wend);\n\t\t\t\twvalue|=1;\n\t\t\t\twend=i;\n\t\t\t\t}\n\t\t\t}\n\t\tj=wend+1;\n\t\tif (!start)\n\t\t\tfor (i=0; i<j; i++)\n\t\t\t\t{\n\t\t\t\tif (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\tif (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))\n\t\t\tgoto err;\n\t\twstart-=wend+1;\n\t\twvalue=0;\n\t\tstart=0;\n\t\tif (wstart < 0) break;\n\t\t}\n\tret=1;\nerr:\n\tBN_CTX_end(ctx);\n\tfor (i=0; i<ts; i++)\n\t\tBN_clear_free(&(val[i]));\n\tBN_RECP_CTX_free(&recp);\n\treturn(ret);\n\t}', 'void BN_CTX_start(BN_CTX *ctx)\n\t{\n\tif (ctx->depth < BN_CTX_NUM_POS)\n\t\tctx->pos[ctx->depth] = ctx->tos;\n\tctx->depth++;\n\t}', 'BIGNUM *BN_CTX_get(BN_CTX *ctx)\n\t{\n\tif (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)\n\t\t{\n\t\tif (!ctx->too_many)\n\t\t\t{\n\t\t\tBNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);\n\t\t\tctx->too_many = 1;\n\t\t\t}\n\t\treturn NULL;\n\t\t}\n\treturn (&(ctx->bn[ctx->tos++]));\n\t}', 'void BN_CTX_end(BN_CTX *ctx)\n\t{\n\tif (ctx == NULL) return;\n\tassert(ctx->depth > 0);\n\tif (ctx->depth == 0)\n\t\tBN_CTX_start(ctx);\n\tctx->too_many = 0;\n\tctx->depth--;\n\tif (ctx->depth < BN_CTX_NUM_POS)\n\t\tctx->tos = ctx->pos[ctx->depth];\n\t}']