1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <openssl/opensslconf.h> 11e1051a39Sopenharmony_ci 12e1051a39Sopenharmony_ci#include <openssl/rand.h> 13e1051a39Sopenharmony_ci#include "crypto/rand_pool.h" 14e1051a39Sopenharmony_ci#include "crypto/rand.h" 15e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 16e1051a39Sopenharmony_ci#include "prov/seeding.h" 17e1051a39Sopenharmony_ci#include <version.h> 18e1051a39Sopenharmony_ci#include <taskLib.h> 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ci#if defined(OPENSSL_RAND_SEED_NONE) 21e1051a39Sopenharmony_ci/* none means none */ 22e1051a39Sopenharmony_ci# undef OPENSSL_RAND_SEED_OS 23e1051a39Sopenharmony_ci#endif 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_ci#if defined(OPENSSL_RAND_SEED_OS) 26e1051a39Sopenharmony_ci# if _WRS_VXWORKS_MAJOR >= 7 27e1051a39Sopenharmony_ci# define RAND_SEED_VXRANDLIB 28e1051a39Sopenharmony_ci# else 29e1051a39Sopenharmony_ci# error "VxWorks <7 only support RAND_SEED_NONE" 30e1051a39Sopenharmony_ci# endif 31e1051a39Sopenharmony_ci#endif 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci#if defined(RAND_SEED_VXRANDLIB) 34e1051a39Sopenharmony_ci# include <randomNumGen.h> 35e1051a39Sopenharmony_ci#endif 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ci/* Macro to convert two thirty two bit values into a sixty four bit one */ 38e1051a39Sopenharmony_ci#define TWO32TO64(a, b) ((((uint64_t)(a)) << 32) + (b)) 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_cistatic uint64_t get_time_stamp(void) 41e1051a39Sopenharmony_ci{ 42e1051a39Sopenharmony_ci struct timespec ts; 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci if (clock_gettime(CLOCK_REALTIME, &ts) == 0) 45e1051a39Sopenharmony_ci return TWO32TO64(ts.tv_sec, ts.tv_nsec); 46e1051a39Sopenharmony_ci return time(NULL); 47e1051a39Sopenharmony_ci} 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_cistatic uint64_t get_timer_bits(void) 50e1051a39Sopenharmony_ci{ 51e1051a39Sopenharmony_ci uint64_t res = OPENSSL_rdtsc(); 52e1051a39Sopenharmony_ci struct timespec ts; 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci if (res != 0) 55e1051a39Sopenharmony_ci return res; 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_ci if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) 58e1051a39Sopenharmony_ci return TWO32TO64(ts.tv_sec, ts.tv_nsec); 59e1051a39Sopenharmony_ci return time(NULL); 60e1051a39Sopenharmony_ci} 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci/* 63e1051a39Sopenharmony_ci * empty implementation 64e1051a39Sopenharmony_ci * vxworks does not need to init/cleanup or keep open the random lib 65e1051a39Sopenharmony_ci */ 66e1051a39Sopenharmony_ciint ossl_rand_pool_init(void) 67e1051a39Sopenharmony_ci{ 68e1051a39Sopenharmony_ci return 1; 69e1051a39Sopenharmony_ci} 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_civoid ossl_rand_pool_cleanup(void) 72e1051a39Sopenharmony_ci{ 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_civoid ossl_rand_pool_keep_random_devices_open(int keep) 76e1051a39Sopenharmony_ci{ 77e1051a39Sopenharmony_ci} 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ciint ossl_rand_pool_add_additional_data(RAND_POOL *pool) 80e1051a39Sopenharmony_ci{ 81e1051a39Sopenharmony_ci struct { 82e1051a39Sopenharmony_ci CRYPTO_THREAD_ID tid; 83e1051a39Sopenharmony_ci uint64_t time; 84e1051a39Sopenharmony_ci } data; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci memset(&data, 0, sizeof(data)); 87e1051a39Sopenharmony_ci 88e1051a39Sopenharmony_ci /* 89e1051a39Sopenharmony_ci * Add some noise from the thread id and a high resolution timer. 90e1051a39Sopenharmony_ci * The thread id adds a little randomness if the drbg is accessed 91e1051a39Sopenharmony_ci * concurrently (which is the case for the <master> drbg). 92e1051a39Sopenharmony_ci */ 93e1051a39Sopenharmony_ci data.tid = CRYPTO_THREAD_get_current_id(); 94e1051a39Sopenharmony_ci data.time = get_timer_bits(); 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); 97e1051a39Sopenharmony_ci} 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ciint ossl_pool_add_nonce_data(RAND_POOL *pool) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci struct { 102e1051a39Sopenharmony_ci pid_t pid; 103e1051a39Sopenharmony_ci CRYPTO_THREAD_ID tid; 104e1051a39Sopenharmony_ci uint64_t time; 105e1051a39Sopenharmony_ci } data; 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci memset(&data, 0, sizeof(data)); 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci /* 110e1051a39Sopenharmony_ci * Add process id, thread id, and a high resolution timestamp to 111e1051a39Sopenharmony_ci * ensure that the nonce is unique with high probability for 112e1051a39Sopenharmony_ci * different process instances. 113e1051a39Sopenharmony_ci */ 114e1051a39Sopenharmony_ci data.pid = getpid(); 115e1051a39Sopenharmony_ci data.tid = CRYPTO_THREAD_get_current_id(); 116e1051a39Sopenharmony_ci data.time = get_time_stamp(); 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ci return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); 119e1051a39Sopenharmony_ci} 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_cisize_t ossl_pool_acquire_entropy(RAND_POOL *pool) 122e1051a39Sopenharmony_ci{ 123e1051a39Sopenharmony_ci#if defined(RAND_SEED_VXRANDLIB) 124e1051a39Sopenharmony_ci /* vxRandLib based entropy method */ 125e1051a39Sopenharmony_ci size_t bytes_needed; 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); 128e1051a39Sopenharmony_ci if (bytes_needed > 0) 129e1051a39Sopenharmony_ci { 130e1051a39Sopenharmony_ci int retryCount = 0; 131e1051a39Sopenharmony_ci STATUS result = ERROR; 132e1051a39Sopenharmony_ci unsigned char *buffer; 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci buffer = ossl_rand_pool_add_begin(pool, bytes_needed); 135e1051a39Sopenharmony_ci while ((result != OK) && (retryCount < 10)) { 136e1051a39Sopenharmony_ci RANDOM_NUM_GEN_STATUS status = randStatus(); 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci if ((status == RANDOM_NUM_GEN_ENOUGH_ENTROPY) 139e1051a39Sopenharmony_ci || (status == RANDOM_NUM_GEN_MAX_ENTROPY) ) { 140e1051a39Sopenharmony_ci result = randBytes(buffer, bytes_needed); 141e1051a39Sopenharmony_ci if (result == OK) 142e1051a39Sopenharmony_ci ossl_rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); 143e1051a39Sopenharmony_ci /* 144e1051a39Sopenharmony_ci * no else here: randStatus said ok, if randBytes failed 145e1051a39Sopenharmony_ci * it will result in another loop or no entropy 146e1051a39Sopenharmony_ci */ 147e1051a39Sopenharmony_ci } else { 148e1051a39Sopenharmony_ci /* 149e1051a39Sopenharmony_ci * give a minimum delay here to allow OS to collect more 150e1051a39Sopenharmony_ci * entropy. taskDelay duration will depend on the system tick, 151e1051a39Sopenharmony_ci * this is by design as the sw-random lib uses interrupts 152e1051a39Sopenharmony_ci * which will at least happen during ticks 153e1051a39Sopenharmony_ci */ 154e1051a39Sopenharmony_ci taskDelay(5); 155e1051a39Sopenharmony_ci } 156e1051a39Sopenharmony_ci retryCount++; 157e1051a39Sopenharmony_ci } 158e1051a39Sopenharmony_ci } 159e1051a39Sopenharmony_ci return ossl_rand_pool_entropy_available(pool); 160e1051a39Sopenharmony_ci#else 161e1051a39Sopenharmony_ci /* 162e1051a39Sopenharmony_ci * SEED_NONE means none, without randlib we dont have entropy and 163e1051a39Sopenharmony_ci * rely on it being added externally 164e1051a39Sopenharmony_ci */ 165e1051a39Sopenharmony_ci return ossl_rand_pool_entropy_available(pool); 166e1051a39Sopenharmony_ci#endif /* defined(RAND_SEED_VXRANDLIB) */ 167e1051a39Sopenharmony_ci} 168