]> begriffs open source - freertos/blob - FreeRTOS-Plus/CyaSSL/ctaocrypt/src/random.c
Commit 3 RX100 low power demos.
[freertos] / FreeRTOS-Plus / CyaSSL / ctaocrypt / src / random.c
1 /* random.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 /* on HPUX 11 you may need to install /dev/random see
27    http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
28
29 */
30
31 #include <cyassl/ctaocrypt/random.h>
32 #include <cyassl/ctaocrypt/error.h>
33
34
35 #if defined(USE_WINDOWS_API)
36     #ifndef _WIN32_WINNT
37         #define _WIN32_WINNT 0x0400
38     #endif
39     #include <windows.h>
40     #include <wincrypt.h>
41 #else
42     #ifndef NO_DEV_RANDOM
43         #include <fcntl.h>
44         #include <unistd.h>
45     #else
46         /* include headers that may be needed to get good seed */
47     #endif
48 #endif /* USE_WINDOWS_API */
49
50
51
52 /* Get seed and key cipher */
53 int InitRng(RNG* rng)
54 {
55     byte key[32];
56     byte junk[256];
57
58     int  ret = GenerateSeed(&rng->seed, key, sizeof(key));
59
60     if (ret == 0) {
61         Arc4SetKey(&rng->cipher, key, sizeof(key));
62         RNG_GenerateBlock(rng, junk, sizeof(junk));  /* rid initial state */
63     }
64
65     return ret;
66 }
67
68
69 /* place a generated block in output */
70 void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
71 {
72     XMEMSET(output, 0, sz);
73     Arc4Process(&rng->cipher, output, output, sz);
74 }
75
76
77 byte RNG_GenerateByte(RNG* rng)
78 {
79     byte b;
80     RNG_GenerateBlock(rng, &b, 1);
81
82     return b;
83 }
84
85
86 #if defined(USE_WINDOWS_API)
87
88
89 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
90 {
91     if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
92                             CRYPT_VERIFYCONTEXT))
93         return WINCRYPT_E;
94
95     if (!CryptGenRandom(os->handle, sz, output))
96         return CRYPTGEN_E;
97
98     CryptReleaseContext(os->handle, 0);
99
100     return 0;
101 }
102
103
104 #elif defined(THREADX)
105
106 #include "rtprand.h"   /* rtp_rand () */
107 #include "rtptime.h"   /* rtp_get_system_msec() */
108
109
110 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
111 {
112     int i;
113     rtp_srand(rtp_get_system_msec());
114
115     for (i = 0; i < sz; i++ ) {
116         output[i] = rtp_rand() % 256;
117         if ( (i % 8) == 7)
118             rtp_srand(rtp_get_system_msec());
119     }
120
121     return 0;
122 }
123
124
125 #elif defined(MICRIUM)
126
127 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
128 {
129     #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
130         NetSecure_InitSeed(output, sz);
131     #endif
132     return 0;
133 }
134
135 #elif defined(MBED)
136
137 /* write a real one !!!, just for testing board */
138 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
139 {
140     int i;
141     for (i = 0; i < sz; i++ )
142         output[i] = i;
143
144     return 0;
145 }
146
147 #elif defined(NO_DEV_RANDOM)
148
149 #error "you need to write an os specific GenerateSeed() here"
150
151
152 #else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !NO_DEV_RANDOM */
153
154
155 /* may block */
156 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
157 {
158     int ret = 0;
159
160     os->fd = open("/dev/urandom",O_RDONLY);
161     if (os->fd == -1) {
162         /* may still have /dev/random */
163         os->fd = open("/dev/random",O_RDONLY);
164         if (os->fd == -1)
165             return OPEN_RAN_E;
166     }
167
168     while (sz) {
169         int len = read(os->fd, output, sz);
170         if (len == -1) { 
171             ret = READ_RAN_E;
172             break;
173         }
174
175         sz     -= len;
176         output += len;
177
178         if (sz) {
179 #ifdef BLOCKING
180             sleep(0);             /* context switch */
181 #else
182             ret = RAN_BLOCK_E;
183             break;
184 #endif
185         }
186     }
187     close(os->fd);
188
189     return ret;
190 }
191
192 #endif /* USE_WINDOWS_API */
193