docker: source checking container
[gnuk/gnuk.git] / src / random.c
1 /*
2  * random.c -- get random bytes
3  *
4  * Copyright (C) 2010, 2011, 2012, 2013, 2015
5  *               Free Software Initiative of Japan
6  * Author: NIIBE Yutaka <gniibe@fsij.org>
7  *
8  * This file is a part of Gnuk, a GnuPG USB Token implementation.
9  *
10  * Gnuk 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  * Gnuk 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
28 #include "gnuk.h"
29 #include "neug.h"
30
31 #define RANDOM_BYTES_LENGTH 32
32 static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)];
33
34 void
35 random_init (void)
36 {
37   int i;
38
39   neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
40
41   for (i = 0; i < NEUG_PRE_LOOP; i++)
42     (void)neug_get (NEUG_KICK_FILLING);
43 }
44
45 void
46 random_fini (void)
47 {
48   neug_fini ();
49 }
50
51 /*
52  * Return pointer to random 32-byte
53  */
54 const uint8_t *
55 random_bytes_get (void)
56 {
57   neug_wait_full ();
58   return (const uint8_t *)random_word;
59 }
60
61 /*
62  * Free pointer to random 32-byte
63  */
64 void
65 random_bytes_free (const uint8_t *p)
66 {
67   (void)p;
68   memset (random_word, 0, RANDOM_BYTES_LENGTH);
69   neug_flush ();
70 }
71
72 /*
73  * Return 4-byte salt
74  */
75 void
76 random_get_salt (uint8_t *p)
77 {
78   uint32_t rnd;
79
80   rnd = neug_get (NEUG_KICK_FILLING);
81   memcpy (p, &rnd, sizeof (uint32_t));
82   rnd = neug_get (NEUG_KICK_FILLING);
83   memcpy (p + sizeof (uint32_t), &rnd, sizeof (uint32_t));
84 }
85
86
87 /*
88  * Random byte iterator
89  */
90 int
91 random_gen (void *arg, unsigned char *out, size_t out_len)
92 {
93   uint8_t *index_p = (uint8_t *)arg;
94   uint8_t index = *index_p;
95   size_t n;
96
97   while (out_len)
98     {
99       neug_wait_full ();
100
101       n = RANDOM_BYTES_LENGTH - index;
102       if (n > out_len)
103         n = out_len;
104
105       memcpy (out, ((unsigned char *)random_word) + index, n);
106       out += n;
107       out_len -= n;
108       index += n;
109
110       if (index >= RANDOM_BYTES_LENGTH)
111         {
112           index = 0;
113           neug_flush ();
114         }
115     }
116
117   *index_p = index;
118
119   return 0;
120 }