PolarSSL v1.1.5
Main Page
Modules
Data Structures
Files
File List
Globals
library
entropy.c
Go to the documentation of this file.
1
/*
2
* Entropy accumulator implementation
3
*
4
* Copyright (C) 2006-2011, Brainspark B.V.
5
*
6
* This file is part of PolarSSL (http://www.polarssl.org)
7
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8
*
9
* All rights reserved.
10
*
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
15
*
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
20
*
21
* You should have received a copy of the GNU General Public License along
22
* with this program; if not, write to the Free Software Foundation, Inc.,
23
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
*/
25
26
#include "
polarssl/config.h
"
27
28
#if defined(POLARSSL_ENTROPY_C)
29
30
#include "
polarssl/entropy.h
"
31
#include "
polarssl/entropy_poll.h
"
32
33
#if defined(POLARSSL_HAVEGE_C)
34
#include "
polarssl/havege.h
"
35
#endif
36
37
#define ENTROPY_MAX_LOOP 256
39
void entropy_init( entropy_context *ctx )
40
{
41
memset( ctx, 0,
sizeof
(
entropy_context
) );
42
43
sha4_starts
( &ctx->accumulator, 0 );
44
#if defined(POLARSSL_HAVEGE_C)
45
havege_init
( &ctx->havege_data );
46
#endif
47
48
#if !defined(POLARSSL_NO_DEFAULT_ENTROPY_SOURCES)
49
#if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
50
entropy_add_source
( ctx,
platform_entropy_poll
, NULL,
51
ENTROPY_MIN_PLATFORM
);
52
#endif
53
#if defined(POLARSSL_TIMING_C)
54
entropy_add_source
( ctx,
hardclock_poll
, NULL,
ENTROPY_MIN_HARDCLOCK
);
55
#endif
56
#if defined(POLARSSL_HAVEGE_C)
57
entropy_add_source
( ctx,
havege_poll
, &ctx->havege_data,
58
ENTROPY_MIN_HAVEGE
);
59
#endif
60
#endif
/* POLARSSL_NO_DEFAULT_ENTROPY_SOURCES */
61
}
62
63
int
entropy_add_source
(
entropy_context
*ctx,
64
f_source_ptr
f_source,
void
*p_source,
65
size_t
threshold )
66
{
67
int
index = ctx->
source_count
;
68
69
if
( index >=
ENTROPY_MAX_SOURCES
)
70
return
(
POLARSSL_ERR_ENTROPY_MAX_SOURCES
);
71
72
ctx->
source
[index].
f_source
= f_source;
73
ctx->
source
[index].
p_source
= p_source;
74
ctx->
source
[index].
threshold
= threshold;
75
76
ctx->
source_count
++;
77
78
return
( 0 );
79
}
80
81
/*
82
* Entropy accumulator update
83
*/
84
int
entropy_update(
entropy_context
*ctx,
unsigned
char
source_id,
85
const
unsigned
char
*data,
size_t
len )
86
{
87
unsigned
char
header[2];
88
unsigned
char
tmp[
ENTROPY_BLOCK_SIZE
];
89
size_t
use_len = len;
90
const
unsigned
char
*p = data;
91
92
if
( use_len >
ENTROPY_BLOCK_SIZE
)
93
{
94
sha4
( data, len, tmp, 0 );
95
96
p = tmp;
97
use_len =
ENTROPY_BLOCK_SIZE
;
98
}
99
100
header[0] = source_id;
101
header[1] = use_len & 0xFF;
102
103
sha4_update
( &ctx->
accumulator
, header, 2 );
104
sha4_update
( &ctx->
accumulator
, p, use_len );
105
106
return
( 0 );
107
}
108
109
int
entropy_update_manual
(
entropy_context
*ctx,
110
const
unsigned
char
*data,
size_t
len )
111
{
112
return
entropy_update( ctx,
ENTROPY_SOURCE_MANUAL
, data, len );
113
}
114
115
/*
116
* Run through the different sources to add entropy to our accumulator
117
*/
118
int
entropy_gather
(
entropy_context
*ctx )
119
{
120
int
ret, i;
121
unsigned
char
buf[
ENTROPY_MAX_GATHER
];
122
size_t
olen;
123
124
if
( ctx->
source_count
== 0 )
125
return
(
POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED
);
126
127
/*
128
* Run through our entropy sources
129
*/
130
for
( i = 0; i < ctx->
source_count
; i++ )
131
{
132
olen = 0;
133
if
( ( ret = ctx->
source
[i].
f_source
( ctx->
source
[i].
p_source
,
134
buf,
ENTROPY_MAX_GATHER
, &olen ) ) != 0 )
135
{
136
return
( ret );
137
}
138
139
/*
140
* Add if we actually gathered something
141
*/
142
if
( olen > 0 )
143
{
144
entropy_update( ctx, (
unsigned
char
) i, buf, olen );
145
ctx->
source
[i].
size
+= olen;
146
}
147
}
148
149
return
( 0 );
150
}
151
152
int
entropy_func
(
void
*data,
unsigned
char
*output,
size_t
len )
153
{
154
int
ret, count = 0, i, reached;
155
entropy_context
*ctx = (
entropy_context
*) data;
156
unsigned
char
buf[
ENTROPY_BLOCK_SIZE
];
157
158
if
( len >
ENTROPY_BLOCK_SIZE
)
159
return
(
POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
160
161
/*
162
* Always gather extra entropy before a call
163
*/
164
do
165
{
166
if
( count++ > ENTROPY_MAX_LOOP )
167
return
(
POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
168
169
if
( ( ret =
entropy_gather
( ctx ) ) != 0 )
170
return
( ret );
171
172
reached = 0;
173
174
for
( i = 0; i < ctx->
source_count
; i++ )
175
if
( ctx->
source
[i].
size
>= ctx->
source
[i].
threshold
)
176
reached++;
177
}
178
while
( reached != ctx->
source_count
);
179
180
memset( buf, 0,
ENTROPY_BLOCK_SIZE
);
181
182
sha4_finish
( &ctx->
accumulator
, buf );
183
184
/*
185
* Perform second SHA-512 on entropy
186
*/
187
sha4
( buf,
ENTROPY_BLOCK_SIZE
, buf, 0 );
188
189
/*
190
* Reset accumulator and counters and recycle existing entropy
191
*/
192
memset( &ctx->
accumulator
, 0,
sizeof
(
sha4_context
) );
193
sha4_starts
( &ctx->
accumulator
, 0 );
194
sha4_update
( &ctx->
accumulator
, buf,
ENTROPY_BLOCK_SIZE
);
195
196
for
( i = 0; i < ctx->
source_count
; i++ )
197
ctx->
source
[i].
size
= 0;
198
199
memcpy( output, buf, len );
200
201
return
( 0 );
202
}
203
204
#endif
Generated on Tue Feb 12 2013 03:48:19 for PolarSSL v1.1.5 by
1.8.1.1