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 run_rfc5114_tests(void) { int i; for (i = 0; i < (int)(sizeof(rfctd) / sizeof(rfc5114_td)); i++) { DH *dhA, *dhB; unsigned char *Z1 = NULL, *Z2 = NULL; const rfc5114_td *td = rfctd + i; /* Set up DH structures setting key components */ dhA = td->get_param(); dhB = td->get_param(); if (!dhA || !dhB) goto bad_err; dhA->priv_key = BN_bin2bn(td->xA, td->xA_len, NULL); dhA->pub_key = BN_bin2bn(td->yA, td->yA_len, NULL); dhB->priv_key = BN_bin2bn(td->xB, td->xB_len, NULL); dhB->pub_key = BN_bin2bn(td->yB, td->yB_len, NULL); if (!dhA->priv_key || !dhA->pub_key || !dhB->priv_key || !dhB->pub_key) goto bad_err; if ((td->Z_len != (size_t)DH_size(dhA)) || (td->Z_len != (size_t)DH_size(dhB))) goto err; Z1 = OPENSSL_malloc(DH_size(dhA)); Z2 = OPENSSL_malloc(DH_size(dhB)); /* * Work out shared secrets using both sides and compare with expected * values. */ if (!DH_compute_key(Z1, dhB->pub_key, dhA)) goto bad_err; if (!DH_compute_key(Z2, dhA->pub_key, dhB)) goto bad_err; if (memcmp(Z1, td->Z, td->Z_len)) goto err; if (memcmp(Z2, td->Z, td->Z_len)) goto err; printf("RFC5114 parameter test %d OK\n", i + 1); DH_free(dhA); DH_free(dhB); OPENSSL_free(Z1); OPENSSL_free(Z2); } return 1; bad_err: fprintf(stderr, "Initalisation error RFC5114 set %d\n", i + 1); ERR_print_errors_fp(stderr); return 0; err: fprintf(stderr, "Test failed RFC5114 set %d\n", i + 1); return 0; }
int SrsDH::copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size) { int ret = ERROR_SUCCESS; BIGNUM* ppk = NULL; if ((ppk = BN_bin2bn((const unsigned char*)ppkey, ppkey_size, 0)) == NULL) { ret = ERROR_OpenSslGetPeerPublicKey; return ret; } // if failed, donot return, do cleanup, @see ./test/dhtest.c:168 // maybe the key_size is 127, but dh will write all 128bytes skey, // so, donot need to set/initialize the skey. // @see https://github.com/winlinvip/simple-rtmp-server/issues/165 int32_t key_size = DH_compute_key((unsigned char*)skey, ppk, pdh); if (key_size < ppkey_size) { srs_warn("shared key size=%d, ppk_size=%d", key_size, ppkey_size); } if (key_size < 0 || key_size > skey_size) { ret = ERROR_OpenSslComputeSharedKey; } else { skey_size = key_size; } if (ppk) { BN_free(ppk); } return ret; }
const uint8_t* tr_cryptoComputeSecret( tr_crypto * crypto, const uint8_t * peerPublicKey ) { int len; uint8_t secret[KEY_LEN]; BIGNUM * bn = BN_bin2bn( peerPublicKey, KEY_LEN, NULL ); DH * dh; ensureKeyExists( crypto ); dh = crypto->dh; assert( DH_size( dh ) == KEY_LEN ); len = DH_compute_key( secret, bn, dh ); if( len == -1 ) logErrorFromSSL( ); else { int offset; assert( len <= KEY_LEN ); offset = KEY_LEN - len; memset( crypto->mySecret, 0, offset ); memcpy( crypto->mySecret + offset, secret, len ); crypto->mySecretIsSet = 1; } BN_free( bn ); return crypto->mySecret; }
tr_dh_secret_t tr_dh_agree (tr_dh_ctx_t handle, const uint8_t * other_public_key, size_t other_public_key_length) { struct tr_dh_secret * ret; int dh_size, secret_key_length; BIGNUM * other_key; assert (handle != NULL); assert (other_public_key != NULL); if (!check_pointer (other_key = BN_bin2bn (other_public_key, other_public_key_length, NULL))) return NULL; dh_size = DH_size (handle); ret = tr_dh_secret_new (dh_size); secret_key_length = DH_compute_key (ret->key, other_key, handle); if (check_result_neq (secret_key_length, -1)) { tr_dh_secret_align (ret, secret_key_length); } else { tr_dh_secret_free (ret); ret = NULL; } BN_free (other_key); return ret; }
bool diffie_hellman::compute_shared_key( const char* buf, uint32_t s ) { ssl_dh dh = DH_new(); #if OPENSSL_VERSION_NUMBER >= 0x10100000L auto bn_p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL ); auto bn_pub_key = BN_bin2bn( (unsigned char*)&pub_key.front(), pub_key.size(), NULL ); auto bn_priv_key = BN_bin2bn( (unsigned char*)&priv_key.front(), priv_key.size(), NULL ); auto bn_g = BN_bin2bn( (unsigned char*)&g, 1, NULL ); DH_set0_pqg(dh.obj, bn_p, NULL, bn_g); DH_set0_key(dh.obj, bn_pub_key, bn_priv_key); #else dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL ); dh->pub_key = BN_bin2bn( (unsigned char*)&pub_key.front(), pub_key.size(), NULL ); dh->priv_key = BN_bin2bn( (unsigned char*)&priv_key.front(), priv_key.size(), NULL ); dh->g = BN_bin2bn( (unsigned char*)&g, 1, NULL ); #endif int check; DH_check(dh,&check); if( !fc::validate( dh, valid ) ) { return false; } ssl_bignum pk; BN_bin2bn( (unsigned char*)buf, s, pk ); shared_key.resize( DH_size(dh) ); DH_compute_key( (unsigned char*)&shared_key.front(), pk, dh ); return true; }
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { int ret; DH *dh; DH_PKEY_CTX *dctx = ctx->data; BIGNUM *dhpub; if (!ctx->pkey || !ctx->peerkey) { DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); return 0; } dh = ctx->pkey->pkey.dh; dhpub = ctx->peerkey->pkey.dh->pub_key; if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) { if (key == NULL) { *keylen = DH_size(dh); return 1; } ret = DH_compute_key(key, dhpub, dh); if (ret < 0) return ret; *keylen = ret; return 1; } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; size_t Zlen = 0; if (!dctx->kdf_outlen || !dctx->kdf_oid) return 0; if (key == NULL) { *keylen = dctx->kdf_outlen; return 1; } if (*keylen != dctx->kdf_outlen) return 0; ret = 0; Zlen = DH_size(dh); Z = OPENSSL_malloc(Zlen); if (DH_compute_key_padded(Z, dhpub, dh) <= 0) goto err; if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid, dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) goto err; *keylen = dctx->kdf_outlen; ret = 1; err: if (Z) { OPENSSL_cleanse(Z, Zlen); OPENSSL_free(Z); } return ret; } return 1; }
int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key) { uint16_t Yc_length; struct s2n_blob Yc; int shared_key_size; BIGNUM *pub_key; GUARD(s2n_check_all_dh_params(server_dh_params)); GUARD(s2n_stuffer_read_uint16(Yc_in, &Yc_length)); Yc.size = Yc_length; Yc.data = s2n_stuffer_raw_read(Yc_in, Yc.size); notnull_check(Yc.data); pub_key = BN_bin2bn((const unsigned char *)Yc.data, Yc.size, NULL); notnull_check(pub_key); GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh))); shared_key_size = DH_compute_key(shared_key->data, pub_key, server_dh_params->dh); if (shared_key_size <= 0) { BN_free(pub_key); S2N_ERROR(S2N_ERR_DH_SHARED_SECRET); } shared_key->size = shared_key_size; BN_free(pub_key); return 0; }
ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */ BIGNUM *other_pub_key = NULL, *dh_p = NULL, *dh_g = NULL; DH *dh_priv = DH_new(); /* Check the arguments and get my private key (dh_priv), the peer's public key (other_pub_key), the parameters p & q */ { BIGNUM *dummy_pub_key = NULL, *priv_key = NULL; ERL_NIF_TERM head, tail; if (!get_bn_from_bin(env, argv[0], &other_pub_key) || !get_bn_from_bin(env, argv[1], &priv_key) || !enif_get_list_cell(env, argv[2], &head, &tail) || !get_bn_from_bin(env, head, &dh_p) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &dh_g) || !enif_is_empty_list(env, tail) /* Note: DH_set0_key() does not allow setting only the * private key, although DH_compute_key() does not use the * public key. Work around this limitation by setting * the public key to a copy of the private key. */ || !(dummy_pub_key = BN_dup(priv_key)) || !DH_set0_key(dh_priv, dummy_pub_key, priv_key) || !DH_set0_pqg(dh_priv, dh_p, NULL, dh_g) ) { if (dh_p) BN_free(dh_p); if (dh_g) BN_free(dh_g); if (other_pub_key) BN_free(other_pub_key); if (dummy_pub_key) BN_free(dummy_pub_key); if (priv_key) BN_free(priv_key); return enif_make_badarg(env); } } { ErlNifBinary ret_bin; int size; enif_alloc_binary(DH_size(dh_priv), &ret_bin); size = DH_compute_key(ret_bin.data, other_pub_key, dh_priv); BN_free(other_pub_key); DH_free(dh_priv); if (size<=0) { enif_release_binary(&ret_bin); return atom_error; } if (size != ret_bin.size) enif_realloc_binary(&ret_bin, size); return enif_make_binary(env, &ret_bin); } }
static isc_result_t openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { DH *dhpub, *dhpriv; int ret; isc_region_t r; unsigned int len; REQUIRE(pub->keydata.dh != NULL); REQUIRE(priv->keydata.dh != NULL); dhpub = pub->keydata.dh; dhpriv = priv->keydata.dh; len = DH_size(dhpriv); isc_buffer_availableregion(secret, &r); if (r.length < len) return (ISC_R_NOSPACE); ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv); if (ret <= 0) return (dst__openssl_toresult2("DH_compute_key", DST_R_COMPUTESECRETFAILURE)); isc_buffer_add(secret, len); return (ISC_R_SUCCESS); }
bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length) { if (_pDH == NULL) { FATAL("DHWrapper not initialized"); return false; } if (_sharedKeyLength != 0 || _pSharedKey != NULL) { FATAL("Shared key already computed"); return false; } _sharedKeyLength = DH_size(_pDH); if (_sharedKeyLength <= 0 || _sharedKeyLength > 1024) { FATAL("Unable to get shared key size in bytes"); return false; } _pSharedKey = new uint8_t[_sharedKeyLength]; memset(_pSharedKey, 0, _sharedKeyLength); _peerPublickey = BN_bin2bn(pPeerPublicKey, length, 0); if (_peerPublickey == NULL) { FATAL("Unable to get the peer public key"); return false; } if (DH_compute_key(_pSharedKey, _peerPublickey, _pDH) == -1) { FATAL("Unable to compute the shared key"); return false; } return true; }
x4s_buf x4_dh_shared(const uint8 * g, size_t glen, const uint8 * p, size_t plen, const uint8 * x, size_t xlen, const uint8 * gx, size_t gxlen, const uint8 * gy, size_t gylen) { DH * dh; BIGNUM * bn; x4s_buf gxy = { 0 }; /* */ x4_assert(gx && gxlen && gy && gylen); /* */ dh = _dh_init(g,glen, p,plen, x,xlen); x4_assert(dh); dh->pub_key = BN_bin2bn(gx, gxlen, 0); x4_assert(dh->pub_key); bn = BN_bin2bn(gy, gylen, 0); x4_assert(bn); x4_buf_resize(&gxy, DH_size(dh)); DH_compute_key(gxy.data, bn, dh); DH_free(dh); return gxy; }
struct sec performDH(char *pubkeyRec,DH *privkey){ struct sec s; int secret_size; /* Send the public key to the peer. * How this occurs will be specific to your situation (see main text below) */ /* Receive the public key from the peer. In this example we're just hard coding a value */ BIGNUM *pubkey = NULL; if(0 == (BN_dec2bn(&pubkey, pubkeyRec))) handleErrors(); /* Compute the shared secret */ unsigned char *secret; if(NULL == (secret = OPENSSL_malloc(sizeof(unsigned char) * (DH_size(privkey))))) handleErrors(); if(0 > (secret_size = DH_compute_key(secret, pubkey, privkey))) handleErrors(); /* Do something with the shared secret */ /* Note secret_size may be less than DH_size(privkey) */ printf("The shared secret is:\n"); strcpy(s.value,secret); s.length=secret_size; /* Clean up */ OPENSSL_free(secret); BN_free(pubkey); DH_free(privkey); return s; }
int tr_compute_dh_key(unsigned char **pbuf, BIGNUM *pub_key, DH *priv_dh) { size_t buflen; unsigned char *buf = NULL;; int rc = 0; if ((!pbuf) || (!pub_key) || (!priv_dh)) { tr_debug("tr_compute_dh_key: Invalid parameters."); return(-1); } *pbuf = NULL; buflen = DH_size(priv_dh); buf = malloc(buflen); if (buf == NULL) { tr_crit("tr_compute_dh_key: out of memory"); return -1; } rc = DH_compute_key(buf, pub_key, priv_dh); if (0 <= rc) { *pbuf = buf; }else { free(buf); } return rc; }
int usmDHSetKey(struct usmUser *user, int for_auth_key, u_char *val, size_t val_len) { DH *dh; BIGNUM *other_pub; u_char *key; size_t key_len; DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHSetKey", "called\n")); /* * XXX: mem leaks on errors abound */ dh = usmDHGetUserDHptr(user, for_auth_key); if (!dh) return MFD_ERROR; other_pub = BN_bin2bn(val + val_len / 2, val_len / 2, NULL); if (!other_pub) return MFD_ERROR; /* * Set the new key for a user */ key_len = DH_size(dh); key = malloc(DH_size(dh)); if (!key) return MFD_ERROR; if (DH_compute_key(key, other_pub, dh)) { u_char **replkey; size_t replkey_size; if (for_auth_key) { replkey_size = user->authKeyLen; replkey = &user->authKey; } else { replkey_size = user->privKeyLen; replkey = &user->privKey; } /* * is it large enough? */ if (key_len < replkey_size) return MFD_ERROR; /* * copy right most bits, per the object requirements */ SNMP_FREE(*replkey); memdup(replkey, key + key_len - replkey_size, replkey_size); return MFD_SUCCESS; } return MFD_ERROR; }
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; }
// compute shared secret given remote public key void DH_key_exchange::compute_secret (char const* remote_pubkey) { assert (remote_pubkey); BIGNUM* bn_remote_pubkey = BN_bin2bn ((unsigned char*)remote_pubkey, 96, NULL); int ret = DH_compute_key ( (unsigned char*)m_dh_secret, bn_remote_pubkey, m_DH); // TODO Check for errors BN_free (bn_remote_pubkey); }
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; }
/* Computes Diffie-Hellman key and stores it into buffer in * little-endian byte order as expected by both versions of GOST 94 * algorithm */ static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh) { unsigned char be_key[128]; int i,key_size; key_size=DH_compute_key(be_key,pub_key,dh); if (!key_size) return 0; TINYCLR_SSL_MEMSET(pair_key,0,128); for (i=0;i<key_size;i++) { pair_key[i]=be_key[key_size-1-i]; } return key_size; }
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { int ret; if (!ctx->pkey || !ctx->peerkey) { DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); return 0; } ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, ctx->pkey->pkey.dh); if (ret < 0) return ret; *keylen = ret; return 1; }
size_t dh_key::compute_key(void* out, size_t out_len, bn::bignum pub_key) const { assert(out_len >= size()); if (out_len < size()) { throw std::invalid_argument("out_len"); } int result = DH_compute_key(static_cast<unsigned char*>(out), pub_key.raw(), ptr().get()); throw_error_if_not(result >= 0); return result; }
std::string avjackif::async_client_hello(boost::asio::yield_context yield_context) { proto::client_hello client_hello; client_hello.set_client("avim"); client_hello.set_version(0001); unsigned char to[512]; auto dh = DH_new(); DH_generate_parameters_ex(dh,64,DH_GENERATOR_5,NULL); DH_generate_key(dh); // 把 g,p, pubkey 传过去 client_hello.set_random_g((const void*)to, BN_bn2bin(dh->g, to)); client_hello.set_random_p((const void*)to, BN_bn2bin(dh->p, to)); client_hello.set_random_pub_key((const void*)to, BN_bn2bin(dh->pub_key, to)); auto tobesend = av_router::encode(client_hello); boost::asio::async_write(*m_sock, boost::asio::buffer(tobesend), yield_context); // 解码 std::unique_ptr<proto::server_hello> server_hello( (proto::server_hello*)async_read_protobuf_message(*m_sock, yield_context)); m_remote_addr.reset(new proto::av_address( av_address_from_string(server_hello->server_av_address()))); auto server_pubkey = BN_bin2bn((const unsigned char *) server_hello->random_pub_key().data(), server_hello->random_pub_key().length(), NULL); m_shared_key.resize(DH_size(dh)); // 密钥就算出来啦! DH_compute_key(&m_shared_key[0], server_pubkey, dh); BN_free(server_pubkey); std::printf("key = 0x"); for (int i=0; i<DH_size(dh); ++i) { std::printf("%x%x", (m_shared_key[i] >> 4) & 0xf, m_shared_key[i] & 0xf); } std::printf("\n"); DH_free(dh); return server_hello->random_pub_key(); }
/** Computes exchanged common key. Given peer's public key, this function computes the exchanged common key, based on its own context including value of prime modulus and random secret exponent. If DhContext is NULL, then return FALSE. If PeerPublicKey is NULL, then return FALSE. If KeySize is NULL, then return FALSE. If Key is NULL, then return FALSE. If KeySize is not large enough, then return FALSE. @param[in, out] DhContext Pointer to the DH context. @param[in] PeerPublicKey Pointer to the peer's public key. @param[in] PeerPublicKeySize Size of peer's public key in bytes. @param[out] Key Pointer to the buffer to receive generated key. @param[in, out] KeySize On input, the size of Key buffer in bytes. On output, the size of data returned in Key buffer in bytes. @retval TRUE DH exchanged key generation succeeded. @retval FALSE DH exchanged key generation failed. @retval FALSE KeySize is not large enough. **/ BOOLEAN EFIAPI DhComputeKey ( IN OUT VOID *DhContext, IN CONST UINT8 *PeerPublicKey, IN UINTN PeerPublicKeySize, OUT UINT8 *Key, IN OUT UINTN *KeySize ) { BIGNUM *Bn; INTN Size; // // Check input parameters. // if (DhContext == NULL || PeerPublicKey == NULL || KeySize == NULL || Key == NULL) { return FALSE; } if (PeerPublicKeySize > INT_MAX) { return FALSE; } Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL); if (Bn == NULL) { return FALSE; } Size = DH_compute_key (Key, Bn, DhContext); if (Size < 0) { BN_free (Bn); return FALSE; } if (*KeySize < (UINTN) Size) { *KeySize = Size; BN_free (Bn); return FALSE; } *KeySize = Size; BN_free (Bn); return TRUE; }
int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key) { struct s2n_dh_params client_params; uint8_t *client_pub_key; uint16_t client_pub_key_size; int shared_key_size; GUARD(s2n_dh_params_check(server_dh_params)); GUARD(s2n_dh_params_copy(server_dh_params, &client_params)); GUARD(s2n_dh_generate_ephemeral_key(&client_params)); GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh))); const BIGNUM *client_pub_key_bn = s2n_get_Ys_dh_param(&client_params); client_pub_key_size = BN_num_bytes(client_pub_key_bn); GUARD(s2n_stuffer_write_uint16(Yc_out, client_pub_key_size)); client_pub_key = s2n_stuffer_raw_write(Yc_out, client_pub_key_size); if (client_pub_key == NULL) { GUARD(s2n_free(shared_key)); GUARD(s2n_dh_params_free(&client_params)); S2N_ERROR(S2N_ERR_DH_WRITING_PUBLIC_KEY); } if (BN_bn2bin(client_pub_key_bn, client_pub_key) != client_pub_key_size) { GUARD(s2n_free(shared_key)); GUARD(s2n_dh_params_free(&client_params)); S2N_ERROR(S2N_ERR_DH_COPYING_PUBLIC_KEY); } /* server_dh_params already validated */ const BIGNUM *server_pub_key_bn = s2n_get_Ys_dh_param(server_dh_params); shared_key_size = DH_compute_key(shared_key->data, server_pub_key_bn, client_params.dh); if (shared_key_size < 0) { GUARD(s2n_free(shared_key)); GUARD(s2n_dh_params_free(&client_params)); S2N_ERROR(S2N_ERR_DH_SHARED_SECRET); } shared_key->size = shared_key_size; GUARD(s2n_dh_params_free(&client_params)); return 0; }
bool OSSLDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey) { // Check parameters if ((ppSymmetricKey == NULL) || (publicKey == NULL) || (privateKey == NULL)) { return false; } // Get keys DH *pub = ((OSSLDHPublicKey *)publicKey)->getOSSLKey(); DH *priv = ((OSSLDHPrivateKey *)privateKey)->getOSSLKey(); if (pub == NULL || pub->pub_key == NULL || priv == NULL) { ERROR_MSG("Failed to get OpenSSL DH keys"); return false; } // Derive the secret ByteString secret; secret.resize(DH_size(priv));; if (DH_compute_key(&secret[0], pub->pub_key, priv) <= 0) { ERROR_MSG("DH key derivation failed (0x%08X)", ERR_get_error()); return false; } *ppSymmetricKey = new SymmetricKey; if (*ppSymmetricKey == NULL) return false; if (!(*ppSymmetricKey)->setKeyBits(secret)) { delete *ppSymmetricKey; *ppSymmetricKey = NULL; return false; } return true; }
int Condor_Diffie_Hellman :: compute_shared_secret(const char * pk) { // the input pk is assumed to be an encoded string representing // the binary data for the remote party's public key -- y (or x) // the local DH knows about g and x, now, it will compute // (g^x)^y, or (g^y)^x BIGNUM * remote_pubKey = NULL; if (BN_hex2bn(&remote_pubKey, pk) == 0) { dprintf(D_ALWAYS, "Unable to obtain remote public key\n"); goto error; } if ((dh_ != NULL) && (remote_pubKey != NULL)) { secret_ = (unsigned char *) malloc(DH_size(dh_)); // Now compute keySize_ = DH_compute_key(secret_, remote_pubKey, dh_); BN_clear_free(remote_pubKey); if (keySize_ == -1) { dprintf(D_ALWAYS, "Unable to compute shared secret\n"); goto error; } } else { goto error; } return 1; error: if (remote_pubKey) { BN_clear_free(remote_pubKey); } if (secret_) { free(secret_); secret_ = NULL; } return 0; }
BUF_MEM * dh_compute_key(EVP_PKEY *key, const BUF_MEM * in, BN_CTX *bn_ctx) { BUF_MEM * out = NULL; BIGNUM * bn = NULL; DH *dh = NULL; check(key && in, "Invalid arguments"); dh = EVP_PKEY_get1_DH(key); if (!dh) return NULL; /* decode public key */ bn = BN_bin2bn((unsigned char *) in->data, in->length, bn); if (!bn) goto err; out = BUF_MEM_create(DH_size(dh)); if (!out) goto err; out->length = DH_compute_key((unsigned char *) out->data, bn, dh); if ((int) out->length < 0) goto err; BN_clear_free(bn); DH_free(dh); return out; err: if (out) BUF_MEM_free(out); if (bn) BN_clear_free(bn); if (dh) DH_free(dh); return NULL; }
/* * call-seq: * dh.compute_key(pub_bn) -> aString * * Returns a String containing a shared secret computed from the other party's public value. * See DH_compute_key() for further information. * * === Parameters * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by * DH#public_key as that contains the DH parameters only. */ static VALUE ossl_dh_compute_key(VALUE self, VALUE pub) { DH *dh; EVP_PKEY *pkey; BIGNUM *pub_key; VALUE str; int len; GetPKeyDH(self, pkey); dh = pkey->pkey.dh; pub_key = GetBNPtr(pub); len = DH_size(dh); str = rb_str_new(0, len); if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) { ossl_raise(eDHError, NULL); } rb_str_set_len(str, len); return str; }
//terminar DiffieHellman int finishDiffieHellman(DH *dh, char* messageReceived,int messageSize,unsigned char* masterKey) { char pubKeyString[MASTER_KEY_SIZE]; int result; BIGNUM *pubKey; result = messageGetSingleValue(messageReceived, messageSize, "/diffie-hellman/B/text()",pubKeyString, MASTER_KEY_SIZE,1); if (result < 0) return -1; pubKey = BN_new(); result = BN_hex2bn(&pubKey, pubKeyString); if (result < 0) return -1; result = DH_compute_key(masterKey, pubKey, dh); if (result < 0) return -1; BN_free(pubKey); return result; }
// shared_secret should be allocated to hold at least 128-bytes (256-bytes for 2048 bit dh). // given the priv_key from the client, the agreed upon modulus p, and the server's dh_pub_key, // this will generate the shared secret int telex_get_shared_secret(BIGNUM *client_dh_priv_key, BIGNUM *p, BIGNUM *server_dh_pub_key, char *shared_secret) { //server_dh_pub_key ^ client_dh_priv_key % p int n; DH *dh_clnt; dh_clnt = DH_new(); // Sets dh_clnt->meth. if (!dh_clnt) { printf("Error: can't DH_new() in telex_get_shared_secret\n"); return -1; } dh_clnt->p = p; dh_clnt->priv_key = client_dh_priv_key; n = DH_compute_key((unsigned char*)shared_secret, server_dh_pub_key, dh_clnt); DH_free(dh_clnt); return n; }