Пример #1
0
RAND_POOL *RAND_POOL_new(int entropy, size_t min_len, size_t max_len)
{
    RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));

    if (pool == NULL) {
        RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    pool->min_len = min_len;
    pool->max_len = max_len;

    pool->buffer = OPENSSL_secure_zalloc(pool->max_len);
    if (pool->buffer == NULL) {
        RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    pool->requested_entropy = entropy;

    return pool;

err:
    OPENSSL_free(pool);
    return NULL;
}
Пример #2
0
/*
 * Allocate memory and initialize a new DRBG. The DRBG is allocated on
 * the secure heap if |secure| is nonzero and the secure heap is enabled.
 * The |parent|, if not NULL, will be used as random source for reseeding.
 *
 * Returns a pointer to the new DRBG instance on success, NULL on failure.
 */
static RAND_DRBG *rand_drbg_new(int secure,
                                int type,
                                unsigned int flags,
                                RAND_DRBG *parent)
{
    RAND_DRBG *drbg = secure ?
        OPENSSL_secure_zalloc(sizeof(*drbg)) : OPENSSL_zalloc(sizeof(*drbg));

    if (drbg == NULL) {
        RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    drbg->secure = secure && CRYPTO_secure_allocated(drbg);
    drbg->fork_count = rand_fork_count;
    drbg->parent = parent;

    if (parent == NULL) {
        drbg->reseed_interval = master_reseed_interval;
        drbg->reseed_time_interval = master_reseed_time_interval;
    } else {
        drbg->reseed_interval = slave_reseed_interval;
        drbg->reseed_time_interval = slave_reseed_time_interval;
    }

    if (RAND_DRBG_set(drbg, type, flags) == 0)
        goto err;

    if (parent != NULL) {
        rand_drbg_lock(parent);
        if (drbg->strength > parent->strength) {
            /*
             * We currently don't support the algorithm from NIST SP 800-90C
             * 10.1.2 to use a weaker DRBG as source
             */
            rand_drbg_unlock(parent);
            RANDerr(RAND_F_RAND_DRBG_NEW, RAND_R_PARENT_STRENGTH_TOO_WEAK);
            goto err;
        }
        rand_drbg_unlock(parent);
    }

    if (!RAND_DRBG_set_callbacks(drbg, rand_drbg_get_entropy,
                                 rand_drbg_cleanup_entropy,
                                 NULL, NULL))
        goto err;

    return drbg;

err:
    if (drbg->secure)
        OPENSSL_secure_free(drbg);
    else
        OPENSSL_free(drbg);

    return NULL;
}
Пример #3
0
/*
 * Allocates a new global DRBG on the secure heap (if enabled) and
 * initializes it with default settings.
 * A global lock for the DRBG is created with the given name.
 *
 * Returns a pointer to the new DRBG instance on success, NULL on failure.
 */
static RAND_DRBG *drbg_setup(const char *name, RAND_DRBG *parent)
{
    RAND_DRBG *drbg;

    if (name == NULL) {
        RANDerr(RAND_F_DRBG_SETUP, ERR_R_INTERNAL_ERROR);
        return NULL;
    }

    drbg = OPENSSL_secure_zalloc(sizeof(RAND_DRBG));
    if (drbg == NULL)
        return NULL;

    drbg->lock = CRYPTO_THREAD_glock_new(name);
    if (drbg->lock == NULL) {
        RANDerr(RAND_F_DRBG_SETUP, RAND_R_FAILED_TO_CREATE_LOCK);
        goto err;
    }

    if (RAND_DRBG_set(drbg,
                      RAND_DRBG_NID, RAND_DRBG_FLAG_CTR_USE_DF) != 1)
        goto err;
    if (RAND_DRBG_set_callbacks(drbg, rand_drbg_get_entropy,
                                rand_drbg_cleanup_entropy, NULL, NULL) != 1)
        goto err;

    if (parent == NULL) {
        drbg->reseed_interval = MASTER_RESEED_INTERVAL;
        drbg->reseed_time_interval = MASTER_RESEED_TIME_INTERVAL;
    } else {
        drbg->parent = parent;
        drbg->reseed_interval = SLAVE_RESEED_INTERVAL;
        drbg->reseed_time_interval = SLAVE_RESEED_TIME_INTERVAL;
    }

    /* enable seed propagation */
    drbg->reseed_counter = 1;

    /*
     * Ignore instantiation error so support just-in-time instantiation.
     *
     * The state of the drbg will be checked in RAND_DRBG_generate() and
     * an automatic recovery is attempted.
     */
    RAND_DRBG_instantiate(drbg,
                          (const unsigned char *) ossl_pers_string,
                          sizeof(ossl_pers_string) - 1);
    return drbg;

err:
    drbg_cleanup(drbg);
    return NULL;
}
Пример #4
0
/*
 * Allocate memory and initialize a new DRBG. The DRBG is allocated on
 * the secure heap if |secure| is nonzero and the secure heap is enabled.
 * The |parent|, if not NULL, will be used as random source for reseeding.
 *
 * Returns a pointer to the new DRBG instance on success, NULL on failure.
 */
static RAND_DRBG *rand_drbg_new(int secure,
                                int type,
                                unsigned int flags,
                                RAND_DRBG *parent)
{
    RAND_DRBG *drbg = secure ?
        OPENSSL_secure_zalloc(sizeof(*drbg)) : OPENSSL_zalloc(sizeof(*drbg));

    if (drbg == NULL) {
        RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    drbg->secure = secure && CRYPTO_secure_allocated(drbg);
    drbg->fork_count = rand_fork_count;
    drbg->parent = parent;

    if (parent == NULL) {
        drbg->get_entropy = rand_drbg_get_entropy;
        drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
#ifndef RAND_DRBG_GET_RANDOM_NONCE
        drbg->get_nonce = rand_drbg_get_nonce;
        drbg->cleanup_nonce = rand_drbg_cleanup_nonce;
#endif

        drbg->reseed_interval = master_reseed_interval;
        drbg->reseed_time_interval = master_reseed_time_interval;
    } else {
        drbg->get_entropy = rand_drbg_get_entropy;
        drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
        /*
         * Do not provide nonce callbacks, the child DRBGs will
         * obtain their nonce using random bits from the parent.
         */

        drbg->reseed_interval = slave_reseed_interval;
        drbg->reseed_time_interval = slave_reseed_time_interval;
    }

    if (RAND_DRBG_set(drbg, type, flags) == 0)
        goto err;

    if (parent != NULL) {
        rand_drbg_lock(parent);
        if (drbg->strength > parent->strength) {
            /*
             * We currently don't support the algorithm from NIST SP 800-90C
             * 10.1.2 to use a weaker DRBG as source
             */
            rand_drbg_unlock(parent);
            RANDerr(RAND_F_RAND_DRBG_NEW, RAND_R_PARENT_STRENGTH_TOO_WEAK);
            goto err;
        }
        rand_drbg_unlock(parent);
    }

    return drbg;

err:
    if (drbg->secure)
        OPENSSL_secure_free(drbg);
    else
        OPENSSL_free(drbg);

    return NULL;
}