rand_lib.c 10.7 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9 10 11
 */

#include <stdio.h>
#include <time.h>
12
#include "internal/cryptlib.h"
13
#include <openssl/opensslconf.h>
R
Rich Salz 已提交
14
#include "internal/rand_int.h"
R
Rich Salz 已提交
15
#include <openssl/engine.h>
16
#include "internal/thread_once.h"
R
Rich Salz 已提交
17
#include "rand_lcl.h"
18

19
#ifndef OPENSSL_NO_ENGINE
20
/* non-NULL if default_RAND_meth is ENGINE-provided */
R
Rich Salz 已提交
21 22
static ENGINE *funct_ref;
static CRYPTO_RWLOCK *rand_engine_lock;
23
#endif
R
Rich Salz 已提交
24 25 26
static CRYPTO_RWLOCK *rand_meth_lock;
static const RAND_METHOD *default_RAND_meth;
static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;
R
Rich Salz 已提交
27
RAND_BYTES_BUFFER rand_bytes;
28

R
Rich Salz 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#ifdef OPENSSL_RAND_SEED_RDTSC
/*
 * IMPORTANT NOTE:  It is not currently possible to use this code
 * because we are not sure about the amount of randomness.  Some
 * SP900 tests have been run, but there is internal skepticism.
 * So for now this code is not used.
 */
# error "RDTSC enabled?  Should not be possible!"

/*
 * Since we get some randomness from the low-order bits of the
 * high-speec clock, it can help.  But don't return a status since
 * it's not sufficient to indicate whether or not the seeding was
 * done.
 */
R
Rich Salz 已提交
44
void rand_read_tsc(RAND_poll_fn cb, void *arg)
R
Rich Salz 已提交
45 46 47 48 49 50
{
    unsigned char c;
    int i;

    for (i = 0; i < 10; i++) {
        c = (unsigned char)(OPENSSL_rdtsc() & 0xFF);
R
Rich Salz 已提交
51
        cb(arg, &c, 1, 0.5);
R
Rich Salz 已提交
52 53 54 55 56 57 58 59 60 61
    }
}
#endif

#ifdef OPENSSL_RAND_SEED_RDCPU
size_t OPENSSL_ia32_rdseed(void);
size_t OPENSSL_ia32_rdrand(void);

extern unsigned int OPENSSL_ia32cap_P[];

R
Rich Salz 已提交
62
int rand_read_cpu(RAND_poll_fn cb, void *arg)
R
Rich Salz 已提交
63 64 65 66 67 68 69 70 71
{
    size_t i, s;

    /* If RDSEED is available, use that. */
    if ((OPENSSL_ia32cap_P[1] & (1 << 18)) != 0) {
        for (i = 0; i < RANDOMNESS_NEEDED; i += sizeof(s)) {
            s = OPENSSL_ia32_rdseed();
            if (s == 0)
                break;
R
Rich Salz 已提交
72
            cb(arg, &s, (int)sizeof(s), sizeof(s));
R
Rich Salz 已提交
73 74 75 76 77 78 79 80 81 82 83
        }
        if (i >= RANDOMNESS_NEEDED)
            return 1;
    }

    /* Second choice is RDRAND. */
    if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
        for (i = 0; i < RANDOMNESS_NEEDED; i += sizeof(s)) {
            s = OPENSSL_ia32_rdrand();
            if (s == 0)
                break;
R
Rich Salz 已提交
84
            cb(arg, &s, (int)sizeof(s), sizeof(s));
R
Rich Salz 已提交
85 86 87 88 89 90 91 92
        }
        if (i >= RANDOMNESS_NEEDED)
            return 1;
    }

    return 0;
}
#endif
R
Rich Salz 已提交
93

R
Rich Salz 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

/*
 * DRBG has two sets of callbacks; we only discuss the "entropy" one
 * here.  When the DRBG needs additional randomness bits (called entropy
 * in the NIST document), it calls the get_entropy callback which fills in
 * a pointer and returns the number of bytes. When the DRBG is finished with
 * the buffer, it calls the cleanup_entropy callback, with the value of
 * the buffer that the get_entropy callback filled in.
 *
 * Get entropy from the system, via RAND_poll if needed.  The |entropy|
 * is the bits of randomness required, and is expected to fit into a buffer
 * of |min_len|..|max__len| size.  We assume we're getting high-quality
 * randomness from the system, and that |min_len| bytes will do.
 */
size_t drbg_entropy_from_system(RAND_DRBG *drbg,
                                unsigned char **pout,
                                int entropy, size_t min_len, size_t max_len)
{
    int i;


    if (min_len > (size_t)drbg->size) {
        /* Should not happen.  See comment near RANDOMNESS_NEEDED. */
        min_len = drbg->size;
    }

    if (rand_drbg.filled) {
        /* Re-use what we have. */
        *pout = drbg->randomness;
        return drbg->size;
    }

    /* If we don't have enough, try to get more. */
    CRYPTO_THREAD_write_lock(rand_bytes.lock);
    for (i = RAND_POLL_RETRIES; rand_bytes.curr < min_len && --i >= 0; ) {
        CRYPTO_THREAD_unlock(rand_bytes.lock);
        RAND_poll();
        CRYPTO_THREAD_write_lock(rand_bytes.lock);
    }

    /* Get desired amount, but no more than we have. */
    if (min_len > rand_bytes.curr)
        min_len = rand_bytes.curr;
    if (min_len != 0) {
        memcpy(drbg->randomness, rand_bytes.buff, min_len);
        rand_drbg.filled = 1;
        /* Update amount left and shift it down. */
        rand_bytes.curr -= min_len;
        if (rand_bytes.curr != 0)
            memmove(rand_bytes.buff, &rand_bytes.buff[min_len], rand_bytes.curr);
    }
    CRYPTO_THREAD_unlock(rand_bytes.lock);
146
    *pout = drbg->randomness;
R
Rich Salz 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    return min_len;
}

size_t drbg_entropy_from_parent(RAND_DRBG *drbg,
                                unsigned char **pout,
                                int entropy, size_t min_len, size_t max_len)
{
    int st;

    if (min_len > (size_t)drbg->size) {
        /* Should not happen.  See comment near RANDOMNESS_NEEDED. */
        min_len = drbg->size;
    }

    /* Get random from parent, include our state as additional input. */
    st = RAND_DRBG_generate(drbg->parent, drbg->randomness, min_len, 0,
                            (unsigned char *)drbg, sizeof(*drbg));
    if (st == 0)
        return 0;
    drbg->filled = 1;
167
    *pout = drbg->randomness;
R
Rich Salz 已提交
168 169 170 171 172 173
    return min_len;
}

void drbg_release_entropy(RAND_DRBG *drbg, unsigned char *out)
{
    drbg->filled = 0;
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
    OPENSSL_cleanse(drbg->randomness, drbg->size);
}


/*
 * Set up a global DRBG.
 */
static int setup_drbg(RAND_DRBG *drbg)
{
    int ret = 1;

    drbg->lock = CRYPTO_THREAD_lock_new();
    ret &= drbg->lock != NULL;
    drbg->size = RANDOMNESS_NEEDED;
    drbg->randomness = OPENSSL_malloc(drbg->size);
    ret &= drbg->randomness != NULL;
    /* If you change these parameters, see RANDOMNESS_NEEDED */
    ret &= RAND_DRBG_set(drbg,
                         NID_aes_128_ctr, RAND_DRBG_FLAG_CTR_USE_DF) == 1;
    ret &= RAND_DRBG_set_callbacks(drbg, drbg_entropy_from_system,
                                   drbg_release_entropy, NULL, NULL) == 1;
    return ret;
}

static void free_drbg(RAND_DRBG *drbg)
{
    CRYPTO_THREAD_lock_free(drbg->lock);
    OPENSSL_clear_free(drbg->randomness, drbg->size);
    RAND_DRBG_uninstantiate(drbg);
R
Rich Salz 已提交
203 204
}

R
Rich Salz 已提交
205
DEFINE_RUN_ONCE_STATIC(do_rand_init)
206
{
207
    int ret = 1;
R
Rich Salz 已提交
208

209 210
#ifndef OPENSSL_NO_ENGINE
    rand_engine_lock = CRYPTO_THREAD_lock_new();
211
    ret &= rand_engine_lock != NULL;
212 213
#endif
    rand_meth_lock = CRYPTO_THREAD_lock_new();
214
    ret &= rand_meth_lock != NULL;
R
Rich Salz 已提交
215 216 217 218 219 220 221 222

    rand_bytes.lock = CRYPTO_THREAD_lock_new();
    ret &= rand_bytes.lock != NULL;
    rand_bytes.curr = 0;
    rand_bytes.size = MAX_RANDOMNESS_HELD;
    /* TODO: Should this be secure malloc? */
    rand_bytes.buff = malloc(rand_bytes.size);

223 224 225
    ret &= rand_bytes.buff != NULL;
    ret &= setup_drbg(&rand_drbg);
    ret &= setup_drbg(&priv_drbg);
226
    return ret;
227
}
228

229

R
Rich Salz 已提交
230 231 232 233 234 235 236 237 238 239 240
void rand_cleanup_int(void)
{
    const RAND_METHOD *meth = default_RAND_meth;

    if (meth != NULL && meth->cleanup != NULL)
        meth->cleanup();
    RAND_set_rand_method(NULL);
#ifndef OPENSSL_NO_ENGINE
    CRYPTO_THREAD_lock_free(rand_engine_lock);
#endif
    CRYPTO_THREAD_lock_free(rand_meth_lock);
R
Rich Salz 已提交
241
    CRYPTO_THREAD_lock_free(rand_bytes.lock);
242 243 244
    OPENSSL_clear_free(rand_bytes.buff, rand_bytes.size);
    free_drbg(&rand_drbg);
    free_drbg(&priv_drbg);
R
Rich Salz 已提交
245 246 247 248 249 250 251 252 253 254 255 256 257 258
}

/*
 * RAND_poll_ex() gets a function pointer to call when it has random bytes.
 * RAND_poll() sets the function pointer to be a wrapper that calls RAND_add().
 */
static void call_rand_add(void* arg, const void *buf, int num, double r)
{
    RAND_add(buf, num, r);
}

int RAND_poll(void)
{
    return RAND_poll_ex(call_rand_add, NULL);
R
Rich Salz 已提交
259 260
}

261
int RAND_set_rand_method(const RAND_METHOD *meth)
262
{
R
Rich Salz 已提交
263
    if (!RUN_ONCE(&rand_init, do_rand_init))
264 265 266
        return 0;

    CRYPTO_THREAD_write_lock(rand_meth_lock);
267
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
268 269
    ENGINE_finish(funct_ref);
    funct_ref = NULL;
270
#endif
271
    default_RAND_meth = meth;
272
    CRYPTO_THREAD_unlock(rand_meth_lock);
273 274
    return 1;
}
275

276
const RAND_METHOD *RAND_get_rand_method(void)
277
{
278 279
    const RAND_METHOD *tmp_meth = NULL;

R
Rich Salz 已提交
280
    if (!RUN_ONCE(&rand_init, do_rand_init))
281 282 283
        return NULL;

    CRYPTO_THREAD_write_lock(rand_meth_lock);
R
Rich Salz 已提交
284
    if (default_RAND_meth == NULL) {
285
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
286 287 288 289 290
        ENGINE *e;

        /* If we have an engine that can do RAND, use it. */
        if ((e = ENGINE_get_default_RAND()) != NULL
                && (tmp_meth = ENGINE_get_RAND(e)) != NULL) {
291
            funct_ref = e;
R
Rich Salz 已提交
292 293 294
            default_RAND_meth = tmp_meth;
        } else {
            ENGINE_finish(e);
R
Rich Salz 已提交
295
            default_RAND_meth = &rand_meth;
R
Rich Salz 已提交
296 297
        }
#else
R
Rich Salz 已提交
298
        default_RAND_meth = &rand_meth;
299
#endif
300
    }
301 302 303
    tmp_meth = default_RAND_meth;
    CRYPTO_THREAD_unlock(rand_meth_lock);
    return tmp_meth;
304
}
305

306
#ifndef OPENSSL_NO_ENGINE
307
int RAND_set_rand_engine(ENGINE *engine)
308 309
{
    const RAND_METHOD *tmp_meth = NULL;
310

R
Rich Salz 已提交
311
    if (!RUN_ONCE(&rand_init, do_rand_init))
312 313
        return 0;

R
Rich Salz 已提交
314
    if (engine != NULL) {
315 316 317
        if (!ENGINE_init(engine))
            return 0;
        tmp_meth = ENGINE_get_RAND(engine);
R
Rich Salz 已提交
318
        if (tmp_meth == NULL) {
319 320 321 322
            ENGINE_finish(engine);
            return 0;
        }
    }
323
    CRYPTO_THREAD_write_lock(rand_engine_lock);
324 325 326
    /* This function releases any prior ENGINE so call it first */
    RAND_set_rand_method(tmp_meth);
    funct_ref = engine;
327
    CRYPTO_THREAD_unlock(rand_engine_lock);
328 329
    return 1;
}
330
#endif
331

332
void RAND_seed(const void *buf, int num)
333 334
{
    const RAND_METHOD *meth = RAND_get_rand_method();
R
Rich Salz 已提交
335 336

    if (meth->seed != NULL)
337 338
        meth->seed(buf, num);
}
339

R
Rich Salz 已提交
340
void RAND_add(const void *buf, int num, double randomness)
341 342
{
    const RAND_METHOD *meth = RAND_get_rand_method();
R
Rich Salz 已提交
343 344 345

    if (meth->add != NULL)
        meth->add(buf, num, randomness);
346
}
347

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
/*
 * This function is not part of RAND_METHOD, so if we're not using
 * the default method, then just call RAND_bytes().  Otherwise make
 * sure we're instantiated and use the private DRBG.
 */
int RAND_priv_bytes(unsigned char *buf, int num)
{
    const RAND_METHOD *meth = RAND_get_rand_method();

    if (meth != RAND_OpenSSL())
        return RAND_bytes(buf, num);

    if (priv_drbg.state == DRBG_UNINITIALISED
            && RAND_DRBG_instantiate(&priv_drbg, NULL, 0) == 0)
        return 0;
    return RAND_DRBG_generate(&priv_drbg, buf, num, 0, NULL, 0);

}

367
int RAND_bytes(unsigned char *buf, int num)
368 369
{
    const RAND_METHOD *meth = RAND_get_rand_method();
R
Rich Salz 已提交
370 371

    if (meth->bytes != NULL)
372
        return meth->bytes(buf, num);
R
Rich Salz 已提交
373
    RANDerr(RAND_F_RAND_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED);
R
Rich Salz 已提交
374
    return -1;
375
}
376

377
#if OPENSSL_API_COMPAT < 0x10100000L
378
int RAND_pseudo_bytes(unsigned char *buf, int num)
379 380
{
    const RAND_METHOD *meth = RAND_get_rand_method();
R
Rich Salz 已提交
381 382

    if (meth->pseudorand != NULL)
383
        return meth->pseudorand(buf, num);
R
Rich Salz 已提交
384
    return -1;
385
}
M
Matt Caswell 已提交
386
#endif
387 388

int RAND_status(void)
389 390
{
    const RAND_METHOD *meth = RAND_get_rand_method();
R
Rich Salz 已提交
391 392

    if (meth->status != NULL)
393 394 395
        return meth->status();
    return 0;
}