Пример #1
0
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);
}
Пример #2
0
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;
 }
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
   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;
   }
Пример #7
0
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;
	}
Пример #8
0
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;
}
Пример #9
0
Файл: dh.c Проект: KennethL/otp
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);
    }
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
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;
}
Пример #17
0
	// 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);
	}
Пример #18
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;
}
/* 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;	
	}	
Пример #20
0
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;
	}
Пример #21
0
		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;
		}
Пример #22
0
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();
}
Пример #23
0
/**
  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;
}
Пример #24
0
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;
}
Пример #25
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;
}
Пример #26
0
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;
}
Пример #27
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;
}
Пример #28
0
/*
 *  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;
}
Пример #30
0
// 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;
}