Version 0.10
[gnuk/gnuk.git] / src / random.c
1 /*
2  * random.c -- get random bytes
3  *
4  * Copyright (C) 2010 Free Software Initiative of Japan
5  * Author: NIIBE Yutaka <gniibe@fsij.org>
6  *
7  * This file is a part of Gnuk, a GnuPG USB Token implementation.
8  *
9  * Gnuk is free software: you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Gnuk is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "config.h"
25 #include "ch.h"
26 #include "gnuk.h"
27
28 const uint8_t *
29 random_bytes_get (void)
30 {
31   uint32_t addr, addr0;
32
33   addr = (uint32_t)&random_bits_start + ((hardclock () << 5) & 0x3e0);
34   addr0 = addr; 
35
36   while (1)
37     {
38       if (*(uint32_t *)addr != 0 && *(uint32_t *)addr != 0xffffffff)
39         break;
40
41       addr += 32;
42       if (addr >= ((uint32_t)&random_bits_start) + 1024)
43         addr = ((uint32_t)&random_bits_start);
44
45       if (addr == addr0)
46         fatal (FATAL_RANDOM);
47     }
48
49   return (const uint8_t *)addr;
50 }
51
52 void
53 random_bytes_free (const uint8_t *p)
54 {
55   int i;
56   uint32_t addr = (uint32_t)p;
57
58   for (i = 0; i < 16; i++)
59     flash_clear_halfword (addr+i*2);
60 }
61
62 uint32_t
63 get_random (void)
64 {
65   const uint32_t *p = (const uint32_t *)random_bytes_get ();
66   uint32_t r = *p;
67
68   random_bytes_free ((const uint8_t *)p);
69   return r;
70 }