cleanup API of ADC
[gnuk/neug.git] / src / neug.c
1 /*
2  * neug.c - true random number generation
3  *
4  * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
5  * Author: NIIBE Yutaka <gniibe@fsij.org>
6  *
7  * This file is a part of NeuG, a True Random Number Generator
8  * implementation based on quantization error of ADC (for STM32F103).
9  *
10  * NeuG is free software: you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * NeuG is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include <stdint.h>
26 #include <string.h>
27 #include <chopstx.h>
28
29 #include "sys.h"
30 #include "neug.h"
31 #include "stm32f103.h"
32 #include "adc.h"
33 #include "sha256.h"
34
35 static chopstx_mutex_t mode_mtx;
36 static chopstx_cond_t  mode_cond;
37
38 /*
39  * ADC finish interrupt
40  */
41 #define INTR_REQ_DMA1_Channel1 11
42
43
44 static sha256_context sha256_ctx_data;
45 static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
46
47 /*
48  * To be a full entropy source, the requirement is to have N samples
49  * for output of 256-bit, where:
50  *
51  *      N = (256 * 2) / <min-entropy of a sample>
52  *
53  * For example, N should be more than 103 for min-entropy = 5.0.
54  *
55  * On the other hand, in the section 6.2 "Full Entropy Source
56  * Requirements", it says:
57  *
58  *     At least twice the block size of the underlying cryptographic
59  *     primitive shall be provided as input to the conditioning
60  *     function to produce full entropy output.
61  *
62  * For us, cryptographic primitive is SHA-256 and its blocksize is
63  * 512-bit (64-byte), thus, N >= 128.
64  *
65  * We chose N=140.  Note that we have "additional bits" of 16-byte for
66  * last block (feedback from previous output of SHA-256) to feed
67  * hash_df function of SHA-256, together with sample data of 140-byte.
68  *
69  * N=140 corresponds to min-entropy >= 3.68.
70  *
71  */
72 #define NUM_NOISE_INPUTS 140
73
74 #define EP_ROUND_0 0 /* initial-five-byte and 3-byte, then 56-byte-input */
75 #define EP_ROUND_1 1 /* 64-byte-input */
76 #define EP_ROUND_2 2 /* 17-byte-input */
77 #define EP_ROUND_RAW      3 /* 32-byte-input */
78 #define EP_ROUND_RAW_DATA 4 /* 32-byte-input */
79
80 #define EP_ROUND_0_INPUTS 56
81 #define EP_ROUND_1_INPUTS 64
82 #define EP_ROUND_2_INPUTS 17
83 #define EP_ROUND_RAW_INPUTS 32
84 #define EP_ROUND_RAW_DATA_INPUTS 32
85
86 static uint8_t ep_round;
87
88 static void noise_source_continuous_test (uint8_t noise);
89
90 /*
91  * Hash_df initial string:
92  *
93  *  Initial five bytes are:
94  *    1,          : counter = 1
95  *    0, 0, 1, 0  : no_of_bits_returned (in big endian)
96  *
97  *  Then, three-byte from noise source follows.
98  *
99  *  One-byte was used in the previous turn, and we have three bytes in
100  *  CRC->DR.
101  */
102 static void ep_fill_initial_string (void)
103 {
104   uint32_t v = CRC->DR;
105   uint8_t b1, b2, b3;
106
107   b3 = v >> 24;
108   b2 = v >> 16;
109   b1 = v >> 8;
110
111   noise_source_continuous_test (b1);
112   noise_source_continuous_test (b2);
113   noise_source_continuous_test (b3);
114
115   adc_buf[0] = 0x01000001;
116   adc_buf[1] = (v & 0xffffff00);
117 }
118
119 static void ep_init (int mode)
120 {
121   if (mode == NEUG_MODE_RAW)
122     {
123       ep_round = EP_ROUND_RAW;
124       adc_start_conversion (0, EP_ROUND_RAW_INPUTS);
125     }
126   else if (mode == NEUG_MODE_RAW_DATA)
127     {
128       ep_round = EP_ROUND_RAW_DATA;
129       adc_start_conversion (0, EP_ROUND_RAW_DATA_INPUTS / 4);
130     }
131   else
132     {
133       ep_round = EP_ROUND_0;
134       ep_fill_initial_string ();
135       adc_start_conversion (2, EP_ROUND_0_INPUTS);
136     }
137 }
138
139
140 static void ep_fill_wbuf_v (int i, int test, uint32_t v)
141 {
142   if (test)
143     {
144       uint8_t b0, b1, b2, b3;
145
146       b3 = v >> 24;
147       b2 = v >> 16;
148       b1 = v >> 8;
149       b0 = v;
150
151       noise_source_continuous_test (b0);
152       noise_source_continuous_test (b1);
153       noise_source_continuous_test (b2);
154       noise_source_continuous_test (b3);
155     }
156
157   sha256_ctx_data.wbuf[i] = v;
158 }
159
160 /* Here assumes little endian architecture.  */
161 static int ep_process (int mode)
162 {
163   int i, n;
164   uint32_t v;
165
166   if (ep_round == EP_ROUND_RAW)
167     {
168       for (i = 0; i < EP_ROUND_RAW_INPUTS / 4; i++)
169         {
170           CRC->DR = adc_buf[i*4];
171           CRC->DR = adc_buf[i*4 + 1];
172           CRC->DR = adc_buf[i*4 + 2];
173           CRC->DR = adc_buf[i*4 + 3];
174           v = CRC->DR;
175           ep_fill_wbuf_v (i, 1, v);
176         }
177
178       ep_init (mode);
179       return EP_ROUND_RAW_INPUTS / 4;
180     }
181   else if (ep_round == EP_ROUND_RAW_DATA)
182     {
183       for (i = 0; i < EP_ROUND_RAW_DATA_INPUTS / 4; i++)
184         {
185           v = adc_buf[i];
186           ep_fill_wbuf_v (i, 0, v);
187         }
188
189       ep_init (mode);
190       return EP_ROUND_RAW_DATA_INPUTS / 4;
191     }
192
193   if (ep_round == EP_ROUND_0)
194     {
195       sha256_start (&sha256_ctx_data);
196       sha256_ctx_data.wbuf[0] = adc_buf[0];
197       sha256_ctx_data.wbuf[1] = adc_buf[1];
198       for (i = 0; i < EP_ROUND_0_INPUTS / 4; i++)
199         {
200           CRC->DR = adc_buf[i*4 + 2];
201           CRC->DR = adc_buf[i*4 + 3];
202           CRC->DR = adc_buf[i*4 + 4];
203           CRC->DR = adc_buf[i*4 + 5];
204           v = CRC->DR;
205           ep_fill_wbuf_v (i+2, 1, v);
206         }
207
208       adc_start_conversion (0, EP_ROUND_1_INPUTS);
209       sha256_process (&sha256_ctx_data);
210       ep_round++;
211       return 0;
212     }
213   else if (ep_round == EP_ROUND_1)
214     {
215       for (i = 0; i < EP_ROUND_1_INPUTS / 4; i++)
216         {
217           CRC->DR = adc_buf[i*4];
218           CRC->DR = adc_buf[i*4 + 1];
219           CRC->DR = adc_buf[i*4 + 2];
220           CRC->DR = adc_buf[i*4 + 3];
221           v = CRC->DR;
222           ep_fill_wbuf_v (i, 1, v);
223         }
224
225       adc_start_conversion (0, EP_ROUND_2_INPUTS + 3);
226       sha256_process (&sha256_ctx_data);
227       ep_round++;
228       return 0;
229     }
230   else
231     {
232       for (i = 0; i < EP_ROUND_2_INPUTS / 4; i++)
233         {
234           CRC->DR = adc_buf[i*4];
235           CRC->DR = adc_buf[i*4 + 1];
236           CRC->DR = adc_buf[i*4 + 2];
237           CRC->DR = adc_buf[i*4 + 3];
238           v = CRC->DR;
239           ep_fill_wbuf_v (i, 1, v);
240         }
241
242       CRC->DR = adc_buf[i*4];
243       CRC->DR = adc_buf[i*4 + 1];
244       CRC->DR = adc_buf[i*4 + 2];
245       CRC->DR = adc_buf[i*4 + 3];
246       v = CRC->DR & 0xff;
247       noise_source_continuous_test (v);
248       sha256_ctx_data.wbuf[i] = v;
249       ep_init (NEUG_MODE_CONDITIONED); /* The rest three-byte of
250                                           CRC->DR is used here.  */
251       n = SHA256_DIGEST_SIZE / 2;
252       memcpy (((uint8_t *)sha256_ctx_data.wbuf) + EP_ROUND_2_INPUTS,
253               sha256_output, n);
254       sha256_ctx_data.total[0] = 5 + NUM_NOISE_INPUTS + n;
255       sha256_finish (&sha256_ctx_data, (uint8_t *)sha256_output);
256       return SHA256_DIGEST_SIZE / sizeof (uint32_t);
257     }
258 }
259
260
261 static const uint32_t *ep_output (int mode)
262 {
263   if (mode)
264     return sha256_ctx_data.wbuf;
265   else
266     return sha256_output;
267 }
268 \f
269 #define REPETITION_COUNT           1
270 #define ADAPTIVE_PROPORTION_64     2
271 #define ADAPTIVE_PROPORTION_4096   4
272
273 uint8_t neug_err_state;
274 uint16_t neug_err_cnt;
275 uint16_t neug_err_cnt_rc;
276 uint16_t neug_err_cnt_p64;
277 uint16_t neug_err_cnt_p4k;
278
279 uint16_t neug_rc_max;
280 uint16_t neug_p64_max;
281 uint16_t neug_p4k_max;
282
283 #include "board.h"
284
285 static void noise_source_cnt_max_reset (void)
286 {
287   neug_err_cnt = neug_err_cnt_rc = neug_err_cnt_p64 = neug_err_cnt_p4k = 0;
288   neug_rc_max = neug_p64_max = neug_p4k_max = 0;
289 }
290
291 static void noise_source_error_reset (void)
292 {
293   neug_err_state = 0;
294 }
295
296 static void noise_source_error (uint32_t err)
297 {
298   neug_err_state |= err;
299   neug_err_cnt++;
300
301   if ((err & REPETITION_COUNT))
302     neug_err_cnt_rc++;
303   if ((err & ADAPTIVE_PROPORTION_64))
304     neug_err_cnt_p64++;
305   if ((err & ADAPTIVE_PROPORTION_4096))
306     neug_err_cnt_p4k++;
307 }
308
309 /*
310  * For health tests, we assume that the device noise source has
311  * min-entropy >= 4.2.  Observing raw data stream (before CRC-32) has
312  * more than 4.2 bit/byte entropy.  When the data stream after CRC-32
313  * filter will be less than 4.2 bit/byte entropy, that must be
314  * something wrong.  Note that even we observe < 4.2, we still have
315  * some margin, since we use NUM_NOISE_INPUTS=140.
316  *
317  */
318
319 /* Cuttoff = 9, when min-entropy = 4.2, W= 2^-30 */
320 /* ceiling of (1+30/4.2) */
321 #define REPITITION_COUNT_TEST_CUTOFF 9
322
323 static uint8_t rct_a;
324 static uint8_t rct_b;
325
326 static void repetition_count_test (uint8_t sample)
327 {
328   if (rct_a == sample)
329     {
330       rct_b++;
331       if (rct_b >= REPITITION_COUNT_TEST_CUTOFF)
332         noise_source_error (REPETITION_COUNT);
333       if (rct_b > neug_rc_max)
334         neug_rc_max = rct_b;
335    }
336   else
337     {
338       rct_a = sample;
339       rct_b = 1;
340     }
341 }
342
343 /* Cuttoff = 18, when min-entropy = 4.2, W= 2^-30 */
344 /* With R, qbinom(1-2^-30,64,2^-4.2) */
345 #define ADAPTIVE_PROPORTION_64_TEST_CUTOFF 18
346
347 static uint8_t ap64t_a;
348 static uint8_t ap64t_b;
349 static uint8_t ap64t_s;
350
351 static void adaptive_proportion_64_test (uint8_t sample)
352 {
353   if (ap64t_s >= 64)
354     {
355       ap64t_a = sample;
356       ap64t_s = 0;
357       ap64t_b = 0;
358     }
359   else
360     {
361       ap64t_s++;
362       if (ap64t_a == sample)
363         {
364           ap64t_b++;
365           if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
366             noise_source_error (ADAPTIVE_PROPORTION_64);
367           if (ap64t_b > neug_p64_max)
368             neug_p64_max = ap64t_b;
369         }
370     }
371 }
372
373 /* Cuttoff = 315, when min-entropy = 4.2, W= 2^-30 */
374 /* With R, qbinom(1-2^-30,4096,2^-4.2) */
375 #define ADAPTIVE_PROPORTION_4096_TEST_CUTOFF 315
376
377 static uint8_t ap4096t_a;
378 static uint16_t ap4096t_b;
379 static uint16_t ap4096t_s;
380
381 static void adaptive_proportion_4096_test (uint8_t sample)
382 {
383   if (ap4096t_s >= 4096)
384     {
385       ap4096t_a = sample;
386       ap4096t_s = 0;
387       ap4096t_b = 0;
388     }
389   else
390     {
391       ap4096t_s++;
392       if (ap4096t_a == sample)
393         {
394           ap4096t_b++;
395           if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
396             noise_source_error (ADAPTIVE_PROPORTION_4096);
397           if (ap4096t_b > neug_p4k_max)
398             neug_p4k_max = ap4096t_b;
399         }
400     }
401 }
402
403 static void noise_source_continuous_test (uint8_t noise)
404 {
405   repetition_count_test (noise);
406   adaptive_proportion_64_test (noise);
407   adaptive_proportion_4096_test (noise);
408 }
409 \f
410 /*
411  * Ring buffer, filled by generator, consumed by neug_get routine.
412  */
413 struct rng_rb {
414   uint32_t *buf;
415   chopstx_mutex_t m;
416   chopstx_cond_t data_available;
417   chopstx_cond_t space_available;
418   uint8_t head, tail;
419   uint8_t size;
420   unsigned int full :1;
421   unsigned int empty :1;
422 };
423
424 static void rb_init (struct rng_rb *rb, uint32_t *p, uint8_t size)
425 {
426   rb->buf = p;
427   rb->size = size;
428   chopstx_mutex_init (&rb->m);
429   chopstx_cond_init (&rb->data_available);
430   chopstx_cond_init (&rb->space_available);
431   rb->head = rb->tail = 0;
432   rb->full = 0;
433   rb->empty = 1;
434 }
435
436 static void rb_add (struct rng_rb *rb, uint32_t v)
437 {
438   rb->buf[rb->tail++] = v;
439   if (rb->tail == rb->size)
440     rb->tail = 0;
441   if (rb->tail == rb->head)
442     rb->full = 1;
443   rb->empty = 0;
444 }
445
446 static uint32_t rb_del (struct rng_rb *rb)
447 {
448   uint32_t v = rb->buf[rb->head++];
449
450   if (rb->head == rb->size)
451     rb->head = 0;
452   if (rb->head == rb->tail)
453     rb->empty = 1;
454   rb->full = 0;
455
456   return v;
457 }
458
459 uint8_t neug_mode;
460 static int rng_should_terminate;
461 static chopstx_t rng_thread;
462
463
464 /**
465  * @brief Random number generation thread.
466  */
467 static void *
468 rng (void *arg)
469 {
470   struct rng_rb *rb = (struct rng_rb *)arg;
471   chopstx_intr_t adc_intr;
472   int mode = neug_mode;
473
474   rng_should_terminate = 0;
475   chopstx_mutex_init (&mode_mtx);
476   chopstx_cond_init (&mode_cond);
477
478   /* Enable ADCs */
479   adc_start ();
480   chopstx_claim_irq (&adc_intr, INTR_REQ_DMA1_Channel1);
481
482   ep_init (mode);
483   while (!rng_should_terminate)
484     {
485       int err;
486       int n;
487
488       err = adc_wait_completion (&adc_intr);
489
490       chopstx_mutex_lock (&mode_mtx);
491       if (err || mode != neug_mode)
492         {
493           mode = neug_mode;
494
495           noise_source_cnt_max_reset ();
496
497           /* Discarding data available, re-initiate from the start.  */
498           ep_init (mode);
499           chopstx_cond_signal (&mode_cond);
500           chopstx_mutex_unlock (&mode_mtx);
501           continue;
502         }
503       else
504         chopstx_mutex_unlock (&mode_mtx);
505
506       if ((n = ep_process (mode)))
507         {
508           int i;
509           const uint32_t *vp;
510
511           if (neug_err_state != 0
512               && (mode == NEUG_MODE_CONDITIONED || mode == NEUG_MODE_RAW))
513             {
514               /* Don't use the result and do it again.  */
515               noise_source_error_reset ();
516               continue;
517             }
518
519           vp = ep_output (mode);
520
521           chopstx_mutex_lock (&rb->m);
522           while (rb->full)
523             chopstx_cond_wait (&rb->space_available, &rb->m);
524
525           for (i = 0; i < n; i++)
526             {
527               rb_add (rb, *vp++);
528               if (rb->full)
529                 break;
530             }
531
532           chopstx_cond_signal (&rb->data_available);
533           chopstx_mutex_unlock (&rb->m);
534         }
535     }
536
537   adc_stop ();
538   chopstx_release_irq (&adc_intr);
539
540   return NULL;
541 }
542
543 static struct rng_rb the_ring_buffer;
544
545 extern uint8_t __process2_stack_base__, __process2_stack_size__;
546 const uint32_t __stackaddr_rng = (uint32_t)&__process2_stack_base__;
547 const size_t __stacksize_rng = (size_t)&__process2_stack_size__;
548 #define PRIO_RNG 2
549
550 /**
551  * @brief Initialize NeuG.
552  */
553 void
554 neug_init (uint32_t *buf, uint8_t size)
555 {
556   const uint32_t *u = (const uint32_t *)unique_device_id ();
557   struct rng_rb *rb = &the_ring_buffer;
558   int i;
559
560   RCC->AHBENR |= RCC_AHBENR_CRCEN;
561   CRC->CR = CRC_CR_RESET;
562
563   /*
564    * This initialization ensures that it generates different sequence
565    * even if all physical conditions are same.
566    */
567   for (i = 0; i < 3; i++)
568     CRC->DR = *u++;
569
570   neug_mode = NEUG_MODE_CONDITIONED;
571   rb_init (rb, buf, size);
572
573   rng_thread = chopstx_create (PRIO_RNG, __stackaddr_rng, __stacksize_rng,
574                                rng, rb);
575 }
576
577 /**
578  * @breif Flush random bytes.
579  */
580 void
581 neug_flush (void)
582 {
583   struct rng_rb *rb = &the_ring_buffer;
584
585   chopstx_mutex_lock (&rb->m);
586   while (!rb->empty)
587     (void)rb_del (rb);
588   chopstx_cond_signal (&rb->space_available);
589   chopstx_mutex_unlock (&rb->m);
590 }
591
592
593 /**
594  * @brief  Wakes up RNG thread to generate random numbers.
595  */
596 void
597 neug_kick_filling (void)
598 {
599   struct rng_rb *rb = &the_ring_buffer;
600
601   chopstx_mutex_lock (&rb->m);
602   if (!rb->full)
603     chopstx_cond_signal (&rb->space_available);
604   chopstx_mutex_unlock (&rb->m);
605 }
606
607 /**
608  * @brief  Get random word (32-bit) from NeuG.
609  * @detail With NEUG_KICK_FILLING, it wakes up RNG thread.
610  *         With NEUG_NO_KICK, it doesn't wake up RNG thread automatically,
611  *         it is needed to call neug_kick_filling later.
612  */
613 uint32_t
614 neug_get (int kick)
615 {
616   struct rng_rb *rb = &the_ring_buffer;
617   uint32_t v;
618
619   chopstx_mutex_lock (&rb->m);
620   while (rb->empty)
621     chopstx_cond_wait (&rb->data_available, &rb->m);
622   v = rb_del (rb);
623   if (kick)
624     chopstx_cond_signal (&rb->space_available);
625   chopstx_mutex_unlock (&rb->m);
626
627   return v;
628 }
629
630 int
631 neug_get_nonblock (uint32_t *p)
632 {
633   struct rng_rb *rb = &the_ring_buffer;
634   int r = 0;
635
636   chopstx_mutex_lock (&rb->m);
637   if (rb->empty)
638     {
639       r = -1;
640       chopstx_cond_signal (&rb->space_available);
641     }
642   else
643     *p = rb_del (rb);
644   chopstx_mutex_unlock (&rb->m);
645
646   return r;
647 }
648
649 int neug_consume_random (void (*proc) (uint32_t, int))
650 {
651   int i = 0;
652   struct rng_rb *rb = &the_ring_buffer;
653
654   chopstx_mutex_lock (&rb->m);
655   while (!rb->empty)
656     {
657       uint32_t v;
658
659       v = rb_del (rb);
660       proc (v, i);
661       i++;
662     }
663   chopstx_cond_signal (&rb->space_available);
664   chopstx_mutex_unlock (&rb->m);
665
666   return i;
667 }
668
669 void
670 neug_wait_full (void)
671 {
672   struct rng_rb *rb = &the_ring_buffer;
673
674   chopstx_mutex_lock (&rb->m);
675   while (!rb->full)
676     chopstx_cond_wait (&rb->data_available, &rb->m);
677   chopstx_mutex_unlock (&rb->m);
678 }
679
680 void
681 neug_fini (void)
682 {
683   rng_should_terminate = 1;
684   neug_get (1);
685   chopstx_join (rng_thread, NULL);
686 }
687
688 void
689 neug_mode_select (uint8_t mode)
690 {
691   if (neug_mode == mode)
692     return;
693
694   neug_wait_full ();
695
696   chopstx_mutex_lock (&mode_mtx);
697   neug_mode = mode;
698   neug_flush ();
699   chopstx_cond_wait (&mode_cond, &mode_mtx);
700   chopstx_mutex_unlock (&mode_mtx);
701
702   neug_wait_full ();
703   neug_flush ();
704 }