RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
{
    RAND_DRBG *drbg = OPENSSL_zalloc(sizeof(*drbg));
    unsigned char *ucp = OPENSSL_zalloc(RANDOMNESS_NEEDED);

    if (drbg == NULL || ucp == NULL) {
        RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    drbg->size = RANDOMNESS_NEEDED;
    drbg->randomness = ucp;

    drbg->parent = parent;
    if (RAND_DRBG_set(drbg, type, flags) < 0)
        goto err;

    if (parent != NULL) {
        if (!RAND_DRBG_set_callbacks(drbg, drbg_entropy_from_parent,
                                     drbg_release_entropy,
                                     NULL, NULL)
                /*
                 * Add in our address.  Note we are adding the pointer
                 * itself, not its contents!
                 */
                || !RAND_DRBG_instantiate(drbg,
                                          (unsigned char*)&drbg, sizeof(drbg)))
            goto err;
    }

    return drbg;

err:
    OPENSSL_free(ucp);
    OPENSSL_free(drbg);
    return NULL;
}