2 * Platform-specific and custom entropy polling functions
4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
6 * This file is part of mbed TLS (https://tls.mbed.org)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #if !defined(POLARSSL_CONFIG_FILE)
24 #include "polarssl/config.h"
26 #include POLARSSL_CONFIG_FILE
29 #if defined(POLARSSL_ENTROPY_C)
31 #include "polarssl/entropy.h"
32 #include "polarssl/entropy_poll.h"
34 #if defined(POLARSSL_TIMING_C)
36 #include "polarssl/timing.h"
38 #if defined(POLARSSL_HAVEGE_C)
39 #include "polarssl/havege.h"
42 #if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
43 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
45 #if !defined(_WIN32_WINNT)
46 #define _WIN32_WINNT 0x0400
51 int platform_entropy_poll( void *data
, unsigned char *output
, size_t len
,
58 if( CryptAcquireContext( &provider
, NULL
, NULL
,
59 PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
) == FALSE
)
61 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
64 if( CryptGenRandom( provider
, (DWORD
) len
, output
) == FALSE
)
65 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
67 CryptReleaseContext( provider
, 0 );
72 #else /* _WIN32 && !EFIX64 && !EFI32 */
75 * Test for Linux getrandom() support.
76 * Since there is no wrapper in the libc yet, use the generic syscall wrapper
77 * available in GNU libc and compatible libc's (eg uClibc).
79 #if defined(__linux__) && defined(__GLIBC__)
80 #include <linux/version.h>
82 #include <sys/syscall.h>
83 #if defined(SYS_getrandom)
84 #define HAVE_GETRANDOM
85 static int getrandom_wrapper( void *buf
, size_t buflen
, unsigned int flags
)
87 return( syscall( SYS_getrandom
, buf
, buflen
, flags
) );
90 #include <sys/utsname.h>
91 /* Check if version is at least 3.17.0 */
92 static int check_version_3_17_plus( void )
98 /* Get version information */
102 /* Check major version; assume a single digit */
103 if( ver
[0] < '3' || ver
[0] > '9' || ver
[1] != '.' )
106 if( ver
[0] - '0' > 3 )
109 /* Ok, so now we know major == 3, check minor.
110 * Assume 1 or 2 digits. */
111 if( ver
[2] < '0' || ver
[2] > '9' )
114 minor
= ver
[2] - '0';
116 if( ver
[3] >= '0' && ver
[3] <= '9' )
117 minor
= 10 * minor
+ ver
[3] - '0';
118 else if( ver
[3] != '.' )
126 static int has_getrandom
= -1;
127 #endif /* SYS_getrandom */
128 #endif /* __linux__ */
132 int platform_entropy_poll( void *data
,
133 unsigned char *output
, size_t len
, size_t *olen
)
139 #if defined(HAVE_GETRANDOM)
140 if( has_getrandom
== -1 )
141 has_getrandom
= ( check_version_3_17_plus() == 0 );
147 if( ( ret
= getrandom_wrapper( output
, len
, 0 ) ) < 0 )
148 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
153 #endif /* HAVE_GETRANDOM */
157 file
= fopen( "/dev/urandom", "rb" );
159 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
161 ret
= fread( output
, 1, len
, file
);
165 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
173 #endif /* _WIN32 && !EFIX64 && !EFI32 */
174 #endif /* !POLARSSL_NO_PLATFORM_ENTROPY */
176 #if defined(POLARSSL_TIMING_C)
177 int hardclock_poll( void *data
,
178 unsigned char *output
, size_t len
, size_t *olen
)
180 unsigned long timer
= hardclock();
184 if( len
< sizeof(unsigned long) )
187 memcpy( output
, &timer
, sizeof(unsigned long) );
188 *olen
= sizeof(unsigned long);
192 #endif /* POLARSSL_TIMING_C */
194 #if defined(POLARSSL_HAVEGE_C)
195 int havege_poll( void *data
,
196 unsigned char *output
, size_t len
, size_t *olen
)
198 havege_state
*hs
= (havege_state
*) data
;
201 if( havege_random( hs
, output
, len
) != 0 )
202 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED
);
208 #endif /* POLARSSL_HAVEGE_C */
210 #endif /* POLARSSL_ENTROPY_C */