void openssl_dh_crypt() { BIO *b; DH *d1, *d2; int i, len1, len2; unsigned char skey1[COMM_LEN], skey2[COMM_LEN]; d1 = DH_new(); d2 = DH_new(); DH_generate_parameters_ex(d1, 64, DH_GENERATOR_2, NULL); DH_check(d1, &i); printf("\nDH key size: %d\n", DH_size(d1)); DH_generate_key(d1); d2->p = BN_dup(d1->p); d2->g = BN_dup(d1->g); DH_generate_key(d2); DH_check_pub_key(d1, d1->pub_key, &i); len1 = DH_compute_key(skey1, d2->pub_key, d1); len2 = DH_compute_key(skey2, d1->pub_key, d2); if ((len1 != len2) || (memcmp(skey1, skey2, len1) != 0)) { printf("DH_compute_key err!\n"); DH_free(d1); DH_free(d2); return; } b = BIO_new(BIO_s_file()); BIO_set_fp(b, stdout, BIO_NOCLOSE); DHparams_print(b, d1); BIO_free(b); DH_free(d1); DH_free(d2); }
static int mech_start(sasl_session_t *p, char **out, int *out_len) { char *ptr; if (!DH_generate_key(dh)) return ASASL_FAIL; /* Serialize p, g, and pub_key */ *out = malloc(BN_num_bytes(dh->p) + BN_num_bytes(dh->g) + BN_num_bytes(dh->pub_key) + 6); *out_len = BN_num_bytes(dh->p) + BN_num_bytes(dh->g) + BN_num_bytes(dh->pub_key) + 6; ptr = *out; /* p */ *((unsigned int *)ptr) = htons(BN_num_bytes(dh->p)); BN_bn2bin(dh->p, (unsigned char *)ptr + 2); ptr += 2 + BN_num_bytes(dh->p); /* g */ *((unsigned int *)ptr) = htons(BN_num_bytes(dh->g)); BN_bn2bin(dh->g, (unsigned char *)ptr + 2); ptr += 2 + BN_num_bytes(dh->g); /* pub_key */ *((unsigned int *)ptr) = htons(BN_num_bytes(dh->pub_key)); BN_bn2bin(dh->pub_key, (unsigned char *)ptr + 2); ptr += 2 + BN_num_bytes(dh->pub_key); p->mechdata = dh; return ASASL_MORE; }
bool tr_dh_make_key (tr_dh_ctx_t raw_handle, size_t private_key_length, uint8_t * public_key, size_t * public_key_length) { DH * handle = raw_handle; int dh_size, my_public_key_length; assert (handle != NULL); assert (public_key != NULL); handle->length = private_key_length * 8; if (!check_result (DH_generate_key (handle))) return false; my_public_key_length = BN_bn2bin (handle->pub_key, public_key); dh_size = DH_size (handle); tr_dh_align_key (public_key, my_public_key_length, dh_size); if (public_key_length != NULL) *public_key_length = dh_size; return true; }
DH * dif_hel_setup() { DH * new_dh = DH_new(); if ( !new_dh ) { printf("%s \n","Error:Creating new dh"); error(); } if ( !DH_generate_parameters_ex(new_dh,2,DH_GENERATOR_2,0)) { printf("%s \n","Error:Generating paramters"); error(); } int dh_code = 0; if( !DH_check(new_dh,&dh_code)) { printf("%s \n", "Error:Dh_check failed"); error(); } if(!DH_generate_key(new_dh)) { printf("%s \n", "Error:Generating key failed"); error(); } return new_dh; }
bool tr_dh_make_key (tr_dh_ctx_t raw_handle, size_t private_key_length, uint8_t * public_key, size_t * public_key_length) { DH * handle = raw_handle; int dh_size, my_public_key_length; const BIGNUM * my_public_key; assert (handle != NULL); assert (public_key != NULL); DH_set_length(handle, private_key_length * 8); if (!check_result (DH_generate_key (handle))) return false; DH_get0_key (handle, &my_public_key, NULL); my_public_key_length = BN_bn2bin (my_public_key, public_key); dh_size = DH_size (handle); tr_dh_align_key (public_key, my_public_key_length, dh_size); if (public_key_length != NULL) *public_key_length = dh_size; return true; }
void avjackif::async_handshake(std::string login_username, std::string login_password, boost::asio::yield_context yield_context) { auto dh = DH_new(); DH_generate_parameters(); DH_generate_key(dh); }
int __openssl_initialize_dh(DH* pdh, int32_t bits_count){ int ret = ERROR_SUCCESS; //2. Create his internal p and g if ((pdh->p = BN_new()) == NULL) { ret = ERROR_OpenSslCreateP; return ret; } if ((pdh->g = BN_new()) == NULL) { ret = ERROR_OpenSslCreateG; return ret; } //3. initialize p and g if (BN_hex2bn(&pdh->p, RFC2409_PRIME_1024) == 0) { ret = ERROR_OpenSslParseP1024; return ret; } if (BN_set_word(pdh->g, 2) != 1) { ret = ERROR_OpenSslSetG; return ret; } //4. Set the key length pdh->length = bits_count; //5. Generate private and public key if (DH_generate_key(pdh) != 1) { ret = ERROR_OpenSslGenerateDHKeys; return ret; } return ret; }
int dh_gen_key(DH *dh, int need) { int pbits; const BIGNUM *p, *pub_key, *priv_key; DH_get0_pqg(dh, &p, NULL, NULL); if (need < 0 || p == NULL || (pbits = BN_num_bits(p)) <= 0 || need > INT_MAX / 2 || 2 * need > pbits) return SSH_ERR_INVALID_ARGUMENT; if (need < 256) need = 256; /* * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), * so double requested need here. */ DH_set_length(dh, MIN(need * 2, pbits - 1)); if (DH_generate_key(dh) == 0) { return SSH_ERR_LIBCRYPTO_ERROR; } DH_get0_key(dh, &pub_key, &priv_key); if (!dh_pub_is_valid(dh, pub_key)) { #if 0 BN_clear(priv_key); #endif return SSH_ERR_LIBCRYPTO_ERROR; } return 0; }
BUF_MEM * dh_generate_key(EVP_PKEY *key, BN_CTX *bn_ctx) { int suc; DH *dh = NULL; BUF_MEM *ret = NULL; const BIGNUM *pub_key; check(key, "Invalid arguments"); dh = EVP_PKEY_get1_DH(key); if (!dh) goto err; if (!DH_generate_key(dh) || !DH_check_pub_key_rfc(dh, bn_ctx, &suc)) goto err; if (suc) goto err; DH_get0_key(dh, &pub_key, NULL); ret = BN_bn2buf(pub_key); err: if (dh) DH_free(dh); return ret; }
// Set the prime P and the generator, generate local public key DH_key_exchange::DH_key_exchange () { m_DH = DH_new (); m_DH->p = BN_bin2bn (m_dh_prime, sizeof(m_dh_prime), NULL); m_DH->g = BN_bin2bn (m_dh_generator, sizeof(m_dh_generator), NULL); assert (sizeof(m_dh_prime) == DH_size(m_DH)); DH_generate_key (m_DH); // TODO Check != 0 assert (m_DH->pub_key); // DH can generate key sizes that are smaller than the size of // P with exponentially decreasing probability, in which case // the msb's of m_dh_local_key need to be zeroed // appropriately. int key_size = get_local_key_size(); int len_dh = sizeof(m_dh_prime); // must equal DH_size(m_DH) if (key_size != len_dh) { assert(key_size > 0 && key_size < len_dh); int pad_zero_size = len_dh - key_size; std::fill(m_dh_local_key, m_dh_local_key + pad_zero_size, 0); BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key + pad_zero_size); } else BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key); // TODO Check return value }
void dh_gen_key(DH *dh, int need) { int i, bits_set, tries = 0; if (dh->p == NULL) fatal("dh_gen_key: dh->p == NULL"); if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p)) fatal("dh_gen_key: group too small: %d (2*need %d)", BN_num_bits(dh->p), 2*need); do { if (dh->priv_key != NULL) BN_clear_free(dh->priv_key); if ((dh->priv_key = BN_new()) == NULL) fatal("dh_gen_key: BN_new failed"); /* generate a 2*need bits random private exponent */ if (!BN_rand(dh->priv_key, 2*need, 0, 0)) fatal("dh_gen_key: BN_rand failed"); if (DH_generate_key(dh) == 0) fatal("DH_generate_key"); for (i = 0, bits_set = 0; i <= BN_num_bits(dh->priv_key); i++) if (BN_is_bit_set(dh->priv_key, i)) bits_set++; debug2("dh_gen_key: priv key bits set: %d/%d", bits_set, BN_num_bits(dh->priv_key)); if (tries++ > 10) fatal("dh_gen_key: too many bad keys: giving up"); } while (!dh_pub_is_valid(dh, dh->pub_key)); }
// DH鍵を生成する void dh_gen_key(PTInstVar pvar, DH *dh, int we_need /* bytes */ ) { int i; dh->priv_key = NULL; // 秘密にすべき乱数(X)を生成 for (i = 0 ; i < 10 ; i++) { // retry counter if (dh->priv_key != NULL) { BN_clear_free(dh->priv_key); } dh->priv_key = BN_new(); if (dh->priv_key == NULL) goto error; if (BN_rand(dh->priv_key, 2*(we_need*8), 0, 0) == 0) goto error; if (DH_generate_key(dh) == 0) goto error; if (dh_pub_is_valid(dh, dh->pub_key)) break; } if (i >= 10) { goto error; } return; error:; notify_fatal_error(pvar, "error occurred @ dh_gen_key()", TRUE); }
DH * usmDHGetUserDHptr(struct usmUser *user, int for_auth_key) { DH *dh, *dh_params; void **theptr; if (user == NULL) return NULL; if (for_auth_key == 1) theptr = &user->usmDHUserAuthKeyChange; else theptr = &user->usmDHUserPrivKeyChange; if (!*theptr) { /* * copy the system parameters to the local ones */ dh = DH_new(); if (!dh) return NULL; dh_params = get_dh_params(); if (!dh_params) return NULL; dh->g = BN_dup(dh_params->g); dh->p = BN_dup(dh_params->p); if (!dh->g || !dh->p) return NULL; DH_generate_key(dh); *theptr = dh; } else { dh = (DH *) * theptr; } return dh; }
bool diffie_hellman::generate_pub_key() { if( !p.size() ) return valid = false; DH* dh = DH_new(); dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL ); dh->g = BN_bin2bn( (unsigned char*)&g, 1, NULL ); int check; DH_check(dh,&check); if( check & DH_CHECK_P_NOT_SAFE_PRIME ) { DH_free(dh); return valid = false; } DH_generate_key(dh); pub_key.resize( BN_num_bytes( dh->pub_key ) ); priv_key.resize( BN_num_bytes( dh->priv_key ) ); if( pub_key.size() ) BN_bn2bin( dh->pub_key, (unsigned char*)&pub_key.front() ); if( priv_key.size() ) BN_bn2bin( dh->priv_key, (unsigned char*)&priv_key.front() ); DH_free(dh); return valid = true; }
int main(int arc, char *argv[]) { DH *dh = DH_new(); BN_GENCB *(*cb)(BN_GENCB *, int, int); cb = &callback; char buf[400]; char *bufPtr = &buf[0]; /* Load the human readable error strings for libcrypto */ ERR_load_crypto_strings(); /* Load all digest and cipher algorithms */ OpenSSL_add_all_algorithms(); /* Load config file, and other important initialisation */ OPENSSL_config(NULL); /* use special PRNG if possible: * /dev/random * /dev/hwrng * ... */ /* ---------------------------- PARAMATER GEN ------------------------ */ printf("start generation\n"); DH_generate_parameters_ex(dh, 256, 2, NULL); printf("paramters DONE\n"); if(dh->pub_key == NULL) printf("pubkey init to NULL\n"); DH_generate_key(dh); printf("key DONE\n"); bufPtr = BN_bn2hex(dh->p); printf ("prime : %s\n", bufPtr); bufPtr = BN_bn2hex(dh->g); printf ("generator: %s\n", bufPtr); bufPtr = BN_bn2hex(dh->pub_key); printf ("pubkey : %s\n", bufPtr); bufPtr = BN_bn2hex(dh->priv_key); printf ("privkey : %s\n", bufPtr); /* Clean up */ /* Removes all digests and ciphers */ EVP_cleanup(); /* if you omit the next, a small leak may be left when you make use of the BIO (low level API) for e.g. base64 transformations */ CRYPTO_cleanup_all_ex_data(); /* Remove error strings */ ERR_free_strings(); return 0; }
/* * This function generates my Diffie Hellmann parameter */ DH* dh_genkey(){ DH *dh = get_dh1024(); if(DH_generate_key(dh)!=1){ DH_free(dh); return NULL; } return dh; }
static krb5_error_code generate_dh_keyblock(krb5_context context, pk_client_params *client_params, krb5_enctype enctype, krb5_keyblock *reply_key) { unsigned char *dh_gen_key = NULL; krb5_keyblock key; krb5_error_code ret; size_t dh_gen_keylen, size; memset(&key, 0, sizeof(key)); if (!DH_generate_key(client_params->dh)) { ret = KRB5KRB_ERR_GENERIC; krb5_set_error_message(context, ret, "Can't generate Diffie-Hellman keys"); goto out; } if (client_params->dh_public_key == NULL) { ret = KRB5KRB_ERR_GENERIC; krb5_set_error_message(context, ret, "dh_public_key"); goto out; } dh_gen_keylen = DH_size(client_params->dh); size = BN_num_bytes(client_params->dh->p); if (size < dh_gen_keylen) size = dh_gen_keylen; dh_gen_key = malloc(size); if (dh_gen_key == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } memset(dh_gen_key, 0, size - dh_gen_keylen); dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen), client_params->dh_public_key, client_params->dh); if (dh_gen_keylen == -1) { ret = KRB5KRB_ERR_GENERIC; krb5_set_error_message(context, ret, "Can't compute Diffie-Hellman key"); goto out; } ret = _krb5_pk_octetstring2key(context, enctype, dh_gen_key, dh_gen_keylen, NULL, NULL, reply_key); out: if (dh_gen_key) free(dh_gen_key); if (key.keyvalue.data) krb5_free_keyblock_contents(context, &key); return ret; }
// Key factory bool OSSLDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng /* = NULL */) { // Check parameters if ((ppKeyPair == NULL) || (parameters == NULL)) { return false; } if (!parameters->areOfType(DHParameters::type)) { ERROR_MSG("Invalid parameters supplied for DH key generation"); return false; } DHParameters* params = (DHParameters*) parameters; // Generate the key-pair DH* dh = DH_new(); if (dh == NULL) { ERROR_MSG("Failed to instantiate OpenSSL DH object"); return false; } if (dh->p != NULL) BN_clear_free(dh->p); dh->p = OSSL::byteString2bn(params->getP()); if (dh->g != NULL) BN_clear_free(dh->g); dh->g = OSSL::byteString2bn(params->getG()); if (DH_generate_key(dh) != 1) { ERROR_MSG("DH key generation failed (0x%08X)", ERR_get_error()); DH_free(dh); return false; } // Create an asymmetric key-pair object to return OSSLDHKeyPair* kp = new OSSLDHKeyPair(); ((OSSLDHPublicKey*) kp->getPublicKey())->setFromOSSL(dh); ((OSSLDHPrivateKey*) kp->getPrivateKey())->setFromOSSL(dh); *ppKeyPair = kp; // Release the key DH_free(dh); return true; }
static EP_STAT generate_dh_key(EP_CRYPTO_KEY *key, ...) { DH *dhkey = DH_generate_key(keylen, XXX); if (dhkey == NULL) return _ep_crypto_error("cannot generate DH key"); if (EVP_PKEY_assign_DH(key, dhkey) != 1) return _ep_crypto_error("cannot save DH key"); }
static int dh_priv_decode (EVP_PKEY * pkey, PKCS8_PRIV_KEY_INFO * p8) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *privkey = NULL; DH *dh = NULL; if (!PKCS8_pkey_get0 (NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0 (NULL, &ptype, &pval, palg); if (ptype != V_ASN1_SEQUENCE) goto decerr; if (!(privkey = d2i_ASN1_INTEGER (NULL, &p, pklen))) goto decerr; pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dh = d2i_DHparams (NULL, &pm, pmlen))) goto decerr; /* We have parameters now set private key */ if (!(dh->priv_key = ASN1_INTEGER_to_BN (privkey, NULL))) { DHerr (DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); goto dherr; } /* Calculate public key */ if (!DH_generate_key (dh)) goto dherr; EVP_PKEY_assign_DH (pkey, dh); ASN1_INTEGER_free (privkey); return 1; decerr: DHerr (DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); dherr: DH_free (dh); return 0; }
/* * call-seq: * dh.generate_key! -> self * * Generates a private and public key unless a private key already exists. * If this DH instance was generated from public DH parameters (e.g. by * encoding the result of DH#public_key), then this method needs to be * called first in order to generate the per-session keys before performing * the actual key exchange. * * === Example * dh = OpenSSL::PKey::DH.new(2048) * public_key = dh.public_key #contains no private/public key yet * public_key.generate_key! * puts public_key.private? # => true */ static VALUE ossl_dh_generate_key(VALUE self) { DH *dh; GetDH(self, dh); if (!DH_generate_key(dh)) ossl_raise(eDHError, "Failed to generate key"); return self; }
int s2n_dh_generate_ephemeral_key(struct s2n_dh_params *dh_params) { GUARD(s2n_check_p_g_dh_params(dh_params)); if (DH_generate_key(dh_params->dh) == 0) { S2N_ERROR(S2N_ERR_DH_GENERATING_PARAMETERS); } return 0; }
int CDiffeHellman::GenPubKeyAndDHKey(const char* pszKey, char* pszPubKey, int &iPubLen, uint8_t* pucDHKey, int &iKeyLen) { if(m_isInit) { return RT_DH_DH_NOT_INIT; } if(!DH_generate_key(m_pDH)) { DHKeyFree(); return RT_DH_GEN_PUB_KEY; } /* 生成公共的key */ char *pKey = BN_bn2hex(m_pDH->pub_key); int iPubKeyLen = strlen(pKey); if(iPubKeyLen > iPubLen) { OPENSSL_free(pKey); DHKeyFree(); return RT_DH_PUB_KEY_BUFF_LEN; } iPubLen = iPubKeyLen; memcpy(pszPubKey, pKey, iPubLen); OPENSSL_free(pKey); /* 生成DH key */ if(BN_hex2bn(&m_pPBig, pszKey) <= 0) { DHKeyFree(); return RT_DH_INVALID_PUB_KEY; } uint8_t aucDHKey[1024] = { 0 }; int iDHKeyLen = DH_compute_key(aucDHKey, m_pPBig, m_pDH); if(iDHKeyLen <= 0) { DHKeyFree(); return RT_DH_GEN_DH_KEY; } if(iKeyLen < iDHKeyLen) { DHKeyFree(); return RT_DH_DH_KEY_BUFF_LEN; } iKeyLen = iDHKeyLen; memcpy(pucDHKey, aucDHKey, iDHKeyLen); DHKeyFree(); return RT_DH_SUCCESS; }
static int ssl_dhe_offer(SSL_ECDH_CTX *ctx, CBB *out) { DH *dh = (DH *)ctx->data; /* The group must have been initialized already, but not the key. */ assert(dh != NULL); assert(dh->priv_key == NULL); /* Due to a bug in yaSSL, the public key must be zero padded to the size of * the prime. */ return DH_generate_key(dh) && BN_bn2cbb_padded(out, BN_num_bytes(dh->p), dh->pub_key); }
/* * call-seq: * dh.generate_key! -> self * * Generates a private and public key unless a private key already exists. * If this DH instance was generated from public DH parameters (e.g. by * encoding the result of DH#public_key), then this method needs to be * called first in order to generate the per-session keys before performing * the actual key exchange. * * === Example * dh = OpenSSL::PKey::DH.new(2048) * public_key = dh.public_key #contains no private/public key yet * public_key.generate_key! * puts public_key.private? # => true */ static VALUE ossl_dh_generate_key(VALUE self) { DH *dh; EVP_PKEY *pkey; GetPKeyDH(self, pkey); dh = pkey->pkey.dh; if (!DH_generate_key(dh)) ossl_raise(eDHError, "Failed to generate key"); return self; }
bool DHWrapper::Initialize() { Cleanup(); //1. Create the DH _pDH = DH_new(); if (_pDH == NULL) { FATAL("Unable to create DH"); Cleanup(); return false; } //2. Create his internal p and g _pDH->p = BN_new(); if (_pDH->p == NULL) { FATAL("Unable to create p"); Cleanup(); return false; } _pDH->g = BN_new(); if (_pDH->g == NULL) { FATAL("Unable to create g"); Cleanup(); return false; } //3. initialize p, g and key length if (BN_hex2bn(&_pDH->p, P1024) == 0) { FATAL("Unable to parse P1024"); Cleanup(); return false; } if (BN_set_word(_pDH->g, 2) != 1) { FATAL("Unable to set g"); Cleanup(); return false; } //4. Set the key length _pDH->length = _bitsCount; //5. Generate private and public key if (DH_generate_key(_pDH) != 1) { FATAL("Unable to generate DH public/private keys"); Cleanup(); return false; } return true; }
static inline DH *DH_clone(DH *dh) { DH *out = DH_new(); out->p = BN_dup(dh->p); out->g = BN_dup(dh->g); if (!DH_generate_key(out)) { DH_free(out); return NULL; } return out; }
static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { DH *dh = NULL; if (ctx->pkey == NULL) { DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); return 0; } dh = DH_new(); if (!dh) return 0; EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh); /* Note: if error return, pkey is freed by parent routine */ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) return 0; return DH_generate_key(pkey->pkey.dh); }
static DH * dh_generate(int size, int gen) { struct ossl_generate_cb_arg cb_arg = { 0 }; struct dh_blocking_gen_arg gen_arg; DH *dh = DH_new(); BN_GENCB *cb = BN_GENCB_new(); if (!dh || !cb) { DH_free(dh); BN_GENCB_free(cb); return NULL; } if (rb_block_given_p()) cb_arg.yield = 1; BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); gen_arg.dh = dh; gen_arg.size = size; gen_arg.gen = gen; gen_arg.cb = cb; if (cb_arg.yield == 1) { /* we cannot release GVL when callback proc is supplied */ dh_blocking_gen(&gen_arg); } else { /* there's a chance to unblock */ rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); } BN_GENCB_free(cb); if (!gen_arg.result) { DH_free(dh); if (cb_arg.state) { /* Clear OpenSSL error queue before re-raising. */ ossl_clear_error(); rb_jump_tag(cb_arg.state); } return NULL; } if (!DH_generate_key(dh)) { DH_free(dh); return NULL; } return dh; }
static DH * dh_generate(int size, int gen) { #if defined(HAVE_DH_GENERATE_PARAMETERS_EX) && HAVE_BN_GENCB BN_GENCB cb; struct ossl_generate_cb_arg cb_arg; struct dh_blocking_gen_arg gen_arg; DH *dh = DH_new(); if (!dh) return 0; memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg)); if (rb_block_given_p()) cb_arg.yield = 1; BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg); gen_arg.dh = dh; gen_arg.size = size; gen_arg.gen = gen; gen_arg.cb = &cb; if (cb_arg.yield == 1) { /* we cannot release GVL when callback proc is supplied */ dh_blocking_gen(&gen_arg); } else { /* there's a chance to unblock */ rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); } if (!gen_arg.result) { DH_free(dh); if (cb_arg.state) rb_jump_tag(cb_arg.state); return 0; } #else DH *dh; dh = DH_generate_parameters(size, gen, rb_block_given_p() ? ossl_generate_cb : NULL, NULL); if (!dh) return 0; #endif if (!DH_generate_key(dh)) { DH_free(dh); return 0; } return dh; }