LED blink
[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 extern void *_binary_random_bits_start;
29
30 const uint8_t *
31 random_bytes_get (void)
32 {
33   uint32_t addr, addr0;
34
35   addr = (uint32_t)&_binary_random_bits_start + ((hardclock () << 5) & 0x3e0);
36   addr0 = addr; 
37
38   while (1)
39     {
40       if (*(uint32_t *)addr != 0)
41         break;
42
43       addr += 32;
44       if (addr >= ((uint32_t)&_binary_random_bits_start) + 1024)
45         addr = ((uint32_t)&_binary_random_bits_start);
46
47       if (addr == addr0)
48         fatal (FATAL_RANDOM);
49     }
50
51   return (const uint8_t *)addr;
52 }
53
54 void
55 random_bytes_free (const uint8_t *p)
56 {
57   int i;
58   uint32_t addr = (uint32_t)p;
59
60   for (i = 0; i < 16; i++)
61     flash_clear_halfword (addr+i*2);
62 }
63
64 uint32_t
65 get_random (void)
66 {
67   const uint32_t *p = (const uint32_t *)random_bytes_get ();
68   uint32_t r = *p;
69
70   random_bytes_free ((const uint8_t *)p);
71   return r;
72 }