Mercurial > dropbear
comparison libtomcrypt/notes/tech0001.txt @ 399:a707e6148060
merge of '5fdf69ca60d1683cdd9f4c2595134bed26394834'
and '6b61c50f4cf888bea302ac8fcf5dbb573b443251'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 03 Feb 2007 08:20:34 +0000 |
parents | 1b9e69c058d2 |
children |
comparison
equal
deleted
inserted
replaced
394:17d097fc111c | 399:a707e6148060 |
---|---|
1 Tech Note 0001 | |
2 How to Gather Entropy on Embedded Systems | |
3 Tom St Denis | |
4 | |
5 Introduction | |
6 ------------ | |
7 | |
8 This tech note explains a relatively simple way to gather entropy for a PRNG (Yarrow in this case) in embedded systems | |
9 where there are few sources of entropy or physical sources. | |
10 | |
11 When trying to setup a secure random number generator a fresh source of random data (entropy) is required to ensure the | |
12 deterministic state of the PRNG is not known or predetermined with respect to an attacker. | |
13 | |
14 At the very least the system requires one timer and one source of un-timed interrupts. by "un-timed" I mean interrupts | |
15 that do not occur at regular intervals [e.g. joypad/keypad input, network packets, etc...]. | |
16 | |
17 First we shall begin by taking an overview of how the Yarrow PRNG works within libtomcrypt. At the heart of all | |
18 PRNGs is the "prng_state" data type. This is a union of structures that hold the PRNG state for the various prngs. The | |
19 first thing we require is a state... | |
20 | |
21 prng_state myPrng; | |
22 | |
23 Next we must initialize the state once to get the ball rolling | |
24 | |
25 if (yarrow_start(&myPrng) != CRYPT_OK) { | |
26 // error should never happen! | |
27 } | |
28 | |
29 At this point the PRNG is ready to accept fresh entropy which is added with | |
30 | |
31 int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) | |
32 | |
33 This function is **NOT** thread safe which will come under consideration later. To add entropy to our PRNG we must | |
34 call this function with fresh data as its sampled. Lets say we have a timer counter called "uTimer" which is a 32-bit | |
35 long and say a 32-bit joyPad state called "uPad". An example interrupt handler would look like | |
36 | |
37 void joypad_interrupt(...) { | |
38 unsigned char buf[8]; | |
39 | |
40 STORE32L(uTimer, buf); | |
41 STORE32L(uPad, buf+4) | |
42 if (yarrow_add_entropy(buf, 8, &myPrng) != CRYPT_OK) { | |
43 // this should never occur either unless you didn't call yarrow_start | |
44 } | |
45 | |
46 // handle interrupt | |
47 } | |
48 | |
49 In this snippet the timer count and state of the joypad are added together into the entropy pool. The timer is important | |
50 because with respect to the joypad it is a good source of entropy (on its own its not). For example, the probability of | |
51 the user pushing the up arrow is fairly high, but at a specific time is not. | |
52 | |
53 This method doesn't gather alot of entropy and has to be used to for quite a while. One way to speed it up is to tap | |
54 multiple sources. If you have a network adapter and other sources of events (keyboard, mouse, etc...) trapping their | |
55 data is ideal as well. Its important to gather the timer along with the event data. | |
56 | |
57 As mentioned the "yarrow_add_entropy()" function is not thread safe. If your system allows interrupt handlers to be | |
58 interrupted themselves then you could have trouble. One simple way is to detect when an interrupt is in progress and | |
59 simply not add entropy during the call (jump over the yarrow_add_entropy() call) | |
60 | |
61 Once you feel that there has been enough entropy added to the pool then within a single thread you can call | |
62 | |
63 int yarrow_ready(prng_state *prng) | |
64 | |
65 Now the PRNG is ready to read via the | |
66 | |
67 unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) | |
68 | |
69 It is a very good idea that once you call the yarrow_ready() function that you stop harvesting entropy in your interrupt | |
70 functions. This will free up alot of CPU time. Also one more final note. The yarrow_read() function is not thread | |
71 safe either. This means if you have multiple threads or processes that read from it you will have to add your own semaphores | |
72 around calls to it. | |
73 |