dd7ad04e5fa81f4ee584578593d4bb0f28778e7b
[libgcrypt.git] / random / rndjent.c
1 /* rndjent.c  - Driver for the jitterentropy module.
2  * Copyright (C) 2017 g10 Code GmbH
3  * Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
4  * Copyright (C) 2013 Stephan Mueller <smueller@chronox.de>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, and the entire permission notice in its entirety,
11  *    including the disclaimer of warranties.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote
16  *    products derived from this software without specific prior
17  *    written permission.
18  *
19  * ALTERNATIVELY, this product may be distributed under the terms of
20  * the GNU General Public License, in which case the provisions of the GPL are
21  * required INSTEAD OF the above restrictions.  (This clause is
22  * necessary due to a potential bad interaction between the GPL and
23  * the restrictions contained in a BSD-style copyright.)
24  *
25  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
28  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
31  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
36  * DAMAGE.
37  */
38
39 #include <config.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <time.h>
43 #ifdef HAVE_STDINT_H
44 # include <stdint.h>
45 #endif
46
47 #include "types.h"
48 #include "g10lib.h"
49 #include "../cipher/bithelp.h"
50 #include "rand-internal.h"
51
52 /*
53  * Decide whether we can support jent at compile time.
54  */
55 #undef USE_JENT
56 #define JENT_USES_RDTSC 1
57 #define JENT_USES_GETTIME 2
58 #define JENT_USES_READ_REAL_TIME 3
59 #ifdef ENABLE_JENT_SUPPORT
60 # if defined (__i386__) || defined(__x86_64__)
61 #   define USE_JENT JENT_USES_RDTSC
62 # elif defined (HAVE_CLOCK_GETTIME)
63 #  if _AIX
64 #   define USE_JENT JENT_USES_READ_REAL_TIME
65 #  else
66 #   define USE_JENT JENT_USES_GETTIME
67 #  endif
68 # endif
69 #endif /*ENABLE_JENT_SUPPORT*/
70
71
72 #ifdef USE_JENT
73
74 /* When using the libgcrypt secure memory mechanism, all precautions
75  * are taken to protect our state. If the user disables secmem during
76  * runtime, it is his decision and we thus try not to overrule his
77  * decision for less memory protection. */
78 #define JENT_CPU_JITTERENTROPY_SECURE_MEMORY 1
79 #define jent_zalloc(n) _gcry_calloc_secure (1, (n))
80
81
82 \f
83 /*
84  * Libgcrypt specific platform dependent functions.
85  */
86
87
88 static void
89 jent_get_nstime(u64 *out)
90 {
91 #if USE_JENT == JENT_USES_RDTSC
92
93   u32 t_eax, t_edx;
94
95   asm volatile (".byte 0x0f,0x31\n\t"
96                 : "=a" (t_eax), "=d" (t_edx)
97                 );
98   *out = (((u64)t_edx << 32) | t_eax);
99
100 #elif USE_JENT == JENT_USES_GETTIME
101
102   struct timespec tv;
103   u64 tmp;
104
105   /* On Linux we could use CLOCK_MONOTONIC(_RAW), but with
106    * CLOCK_REALTIME we get some nice extra entropy once in a while
107    * from the NTP actions that we want to use as well... though, we do
108    * not rely on that extra little entropy.  */
109   if (!clock_gettime (CLOCK_REALTIME, &tv))
110     {
111       tmp = time.tv_sec;
112       tmp = tmp << 32;
113       tmp = tmp | time.tv_nsec;
114     }
115   else
116     tmp = 0;
117   *out = tmp;
118
119 #elif USE_JENT == JENT_USES_READ_REAL_TIME
120
121   /* clock_gettime() on AIX returns a timer value that increments in
122    * steps of 1000.  */
123   u64 tmp = 0;
124
125   timebasestruct_t aixtime;
126   read_real_time (&aixtime, TIMEBASE_SZ);
127   tmp = aixtime.tb_high;
128   tmp = tmp << 32;
129   tmp = tmp | aixtime.tb_low;
130   *out = tmp;
131
132 #else
133 # error No clock available in jent_get_nstime
134 #endif
135 }
136
137
138 static GPGRT_INLINE void
139 jent_zfree (void *ptr, unsigned int len)
140 {
141   if (ptr)
142     {
143       wipememory (ptr, len);
144       _gcry_free (ptr);
145     }
146 }
147
148 static GPGRT_INLINE int
149 jent_fips_enabled(void)
150 {
151   return fips_mode();
152 }
153
154
155 /*
156  * We source include the actual jitter entropy code.  Note that the
157  * included code has been slightly changed from the Linux kernel
158  * version for namespace reasons.  We define MODULE so that the
159  * EXPORT_SYMBOL macro will not be used.
160  */
161 #undef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
162 /* Uncomment the next line to build with statistics.  */
163 /* #define CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT 1 */
164
165 #undef MODULE
166 #define MODULE 1
167
168 #ifndef HAVE_STDINT_H
169 # error This module needs stdint.h - try ./configure --disable-jent-support
170 #endif
171 #include "jitterentropy-base.c"
172
173
174 /* This is the lock we use to serialize access to this RNG.  The extra
175  * integer variable is only used to check the locking state; that is,
176  * it is not meant to be thread-safe but merely as a failsafe feature
177  * to assert proper locking.  */
178 GPGRT_LOCK_DEFINE (jent_rng_lock);
179 static int jent_rng_is_locked;
180
181 /* This flag tracks whether the RNG has been initialized - either
182  * with error or with success.  Protected by JENT_RNG_LOCK. */
183 static int jent_rng_is_initialized;
184
185 /* Our collector.  The RNG is in a working state if its value is not
186  * NULL.  Protected by JENT_RNG_LOCK.  */
187 struct rand_data *jent_rng_collector;
188
189 /* The number of times the core entropy function has been called and
190  * the number of random bytes retrieved.  */
191 static unsigned long jent_rng_totalcalls;
192 static unsigned long jent_rng_totalbytes;
193
194
195 \f
196 /* JENT statistic helper code.  */
197 #ifdef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
198
199 static void
200 jent_init_statistic (struct rand_data *rand_data)
201 {
202   int i;
203   struct entropy_stat *stat = &rand_data->entropy_stat;
204
205   for (i = 0; i < 64; i++)
206     {
207       stat->bitslot[i] = 0;
208       stat->bitvar[i] = 0;
209     }
210
211   jent_get_nstime (&stat->collection_begin);
212 }
213
214 static void
215 jent_bit_count (struct rand_data *rand_data, u64 prev_data)
216 {
217   int i;
218
219   if (!rand_data->entropy_stat.enable_bit_test)
220     return;
221
222   for (i = 0; i < 64; i++)
223     {
224       /* collect the count of set bits per bit position in the
225        * current ->data field */
226       rand_data->entropy_stat.bitslot[i] += (rand_data->data & 1<<i) ? 1:0;
227
228       /* collect the count of bit changes between the current
229        * and the previous random data value per bit position */
230       if ((rand_data->data & 1<<i) != (prev_data & 1<<i))
231         rand_data->entropy_stat.bitvar[i] += 1;
232     }
233 }
234
235
236 static void
237 jent_statistic_copy_stat (struct entropy_stat *src, struct entropy_stat *dst)
238 {
239   /* not copying bitslot and bitvar as they are not needed for
240    * statistic printout */
241   dst->collection_begin = src->collection_begin;
242   dst->collection_end   = src->collection_end;
243   dst->old_delta        = src->old_delta;
244   dst->setbits          = src->setbits;
245   dst->varbits          = src->varbits;
246   dst->obsbits          = src->obsbits;
247   dst->collection_loop_cnt= src->collection_loop_cnt;
248 }
249
250
251 /*
252  * Assessment of statistical behavior of the generated output and returning
253  * the information to the caller by filling the target value.
254  *
255  * Details about the bit statistics are given in chapter 4 of the doc.
256  * Chapter 5 documents the timer analysis and the resulting entropy.
257  */
258 static void
259 jent_calc_statistic (struct rand_data *rand_data,
260                      struct entropy_stat *target, unsigned int loop_cnt)
261 {
262   int i;
263   struct entropy_stat *stat = &rand_data->entropy_stat;
264
265   jent_get_nstime(&stat->collection_end);
266
267   stat->collection_loop_cnt = loop_cnt;
268
269   stat->setbits = 0;
270   stat->varbits = 0;
271   stat->obsbits = 0;
272
273   for (i = 0; i < DATA_SIZE_BITS; i++)
274     {
275       stat->setbits += stat->bitslot[i];
276       stat->varbits += stat->bitvar[i];
277
278       /* This is the sum of set bits in the current observation
279        * of the random data. */
280       stat->obsbits += (rand_data->data & 1<<i) ? 1:0;
281     }
282
283   jent_statistic_copy_stat(stat, target);
284
285   stat->old_delta = (stat->collection_end - stat->collection_begin);
286 }
287
288 #endif /*CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT*/
289
290
291 /* Acquire the jent_rng_lock.  */
292 static void
293 lock_rng (void)
294 {
295   gpg_err_code_t rc;
296
297   rc = gpgrt_lock_lock (&jent_rng_lock);
298   if (rc)
299     log_fatal ("failed to acquire the Jent RNG lock: %s\n",
300                gpg_strerror (rc));
301   jent_rng_is_locked = 1;
302 }
303
304
305 /* Release the jent_rng_lock.  */
306 static void
307 unlock_rng (void)
308 {
309   gpg_err_code_t rc;
310
311   jent_rng_is_locked = 0;
312   rc = gpgrt_lock_unlock (&jent_rng_lock);
313   if (rc)
314     log_fatal ("failed to release the Jent RNG lock: %s\n",
315                gpg_strerror (rc));
316 }
317
318
319 /* Return true if the JENT RNG code can be run.  It may not yet been
320  * initialized, though.  */
321 static int
322 is_rng_available (void)
323 {
324 #if USE_JENT == JENT_USES_RDTSC
325   return !!(_gcry_get_hw_features () & HWF_INTEL_RDTSC);
326 #elif USE_JENT == JENT_USES_GETTIME
327   return 2;
328 #elif USE_JENT == JENT_USES_READ_REAL_TIME
329   return 3;
330 #else  /* Ooops  */
331   return 0;
332 #endif
333 }
334
335 #endif /* USE_JENT */
336
337 \f
338 /*
339  * The API used by the high level code.
340  */
341
342 /* Read up to LENGTH bytes from a jitter RNG and return the number of
343  * bytes actually read.  */
344 size_t
345 _gcry_rndjent_poll (void (*add)(const void*, size_t, enum random_origins),
346                     enum random_origins origin, size_t length)
347 {
348   size_t nbytes = 0;
349
350 #ifdef USE_JENT
351   if ( is_rng_available () )
352     {
353       lock_rng ();
354
355       if (!jent_rng_is_initialized)
356         {
357           /* Auto-initialize.  */
358           jent_rng_is_initialized = 1;
359           jent_entropy_collector_free (jent_rng_collector);
360           jent_rng_collector = NULL;
361           if ( !(_gcry_random_read_conf () & RANDOM_CONF_DISABLE_JENT))
362             {
363               if (!jent_entropy_init ())
364                 jent_rng_collector = jent_entropy_collector_alloc (1, 0);
365             }
366         }
367
368       if (jent_rng_collector && add)
369         {
370           /* We have a working JENT and it has not been disabled.  */
371           char buffer[32];
372
373           while (length)
374             {
375               int rc;
376               size_t n = length < sizeof(buffer)? length : sizeof (buffer);
377
378               jent_rng_totalcalls++;
379               rc = jent_read_entropy (jent_rng_collector, buffer, n);
380               if (rc < 0)
381                 break;
382               /* We need to hash the output to conform to the BSI
383                * NTG.1 specs.  */
384               _gcry_md_hash_buffer (GCRY_MD_SHA256, buffer, buffer, rc);
385               n = rc < 32? rc : 32;
386               (*add) (buffer, n, origin);
387               length -= n;
388               nbytes += n;
389               jent_rng_totalbytes += n;
390             }
391           wipememory (buffer, sizeof buffer);
392         }
393
394       unlock_rng ();
395     }
396
397 #else
398
399   (void)add;
400   (void)origin;
401
402 #endif
403
404   return nbytes;
405 }
406
407
408 /* Return the version number of the JENT RNG.  If the RNG is not
409  * initialized or usable 0 is returned.  If R_ACTIVE is not NULL the
410  * jitter RNG will be initialized and true is stored at R_ACTIVE if
411  * the initialization succeeded.  */
412 unsigned int
413 _gcry_rndjent_get_version (int *r_active)
414 {
415 #ifdef USE_JENT
416   if ( is_rng_available () )
417     {
418       if (r_active)
419         {
420           /* Make sure the RNG is initialized.  */
421           _gcry_rndjent_poll (NULL, 0, 0);
422           /* To ease debugging we store 2 for a clock_gettime based
423            * implementation and 1 for a rdtsc based code.  */
424           *r_active = jent_rng_collector? is_rng_available () : 0;
425         }
426       return jent_version ();
427     }
428   else
429     return 0;
430 #else
431   return 0;
432 #endif
433 }
434
435
436 /* Log statistical informantion about the use of this module.  */
437 void
438 _gcry_rndjent_dump_stats (void)
439 {
440   /* In theory we would need to lock the stats here.  However this
441      function is usually called during cleanup and then we _might_ run
442      into problems.  */
443
444 #ifdef USE_JENT
445   if ( is_rng_available () )
446     {
447       log_info ("rndjent stat: collector=%p calls=%lu bytes=%lu\n",
448                 jent_rng_collector, jent_rng_totalcalls, jent_rng_totalbytes);
449
450     }
451 #endif /*USE_JENT*/
452 }