static int ubsec_dh_generate_key(DH *dh)
        {
        int      ret               = 0,
                 random_bits       = 0,
                 pub_key_len       = 0,
                 priv_key_len      = 0,
                 fd;
        BIGNUM   *pub_key          = NULL;
        BIGNUM   *priv_key         = NULL;

        /* 
         *  How many bits should Random x be? dh_key.c
         *  sets the range from 0 to num_bits(modulus) ???
         */

        if (dh->priv_key == NULL)
                {
                priv_key = BN_new();
                if (priv_key == NULL) goto err;
                priv_key_len = BN_num_bits(dh->p);
                bn_wexpand(priv_key, dh->p->top);
                do
                        if (!BN_rand_range(priv_key, dh->p)) goto err;
                while (BN_is_zero(priv_key));
                random_bits = BN_num_bits(priv_key);
                }
        else
                {
                priv_key = dh->priv_key;
                }

        if (dh->pub_key == NULL)
                {
                pub_key = BN_new();
                pub_key_len = BN_num_bits(dh->p);
                bn_wexpand(pub_key, dh->p->top);
                if(pub_key == NULL) goto err;
                }
        else
                {
                pub_key = dh->pub_key;
                }

        if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
                {
                const DH_METHOD *meth;
                UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE);
                meth = DH_OpenSSL();
                ret = meth->generate_key(dh);
                goto err;
                }

        if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
                                                  (unsigned char *)priv_key->d, &priv_key_len,
                                                  (unsigned char *)pub_key->d,  &pub_key_len,
                                                  (unsigned char *)dh->g->d, BN_num_bits(dh->g),
                                                  (unsigned char *)dh->p->d, BN_num_bits(dh->p),
                                                  0, 0, random_bits) != 0)
                {
                /* Hardware's a no go, failover to software */
                const DH_METHOD *meth;

                UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED);
                p_UBSEC_ubsec_close(fd);

                meth = DH_OpenSSL();
                ret = meth->generate_key(dh);

                goto err;
                }

        p_UBSEC_ubsec_close(fd);

        dh->pub_key = pub_key;
        dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
        dh->priv_key = priv_key;
        dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;

        ret = 1;
err:
        return ret;
        }