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