mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
entropy_poll.c
00001 /* 00002 * Platform-specific and custom entropy polling functions 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 00023 #if !defined(POLARSSL_CONFIG_FILE) 00024 #include "polarssl/config.h" 00025 #else 00026 #include POLARSSL_CONFIG_FILE 00027 #endif 00028 00029 #if defined(POLARSSL_ENTROPY_C) 00030 00031 #include "polarssl/entropy.h" 00032 #include "polarssl/entropy_poll.h" 00033 00034 #if defined(POLARSSL_TIMING_C) 00035 #include <string.h> 00036 #include "polarssl/timing.h" 00037 #endif 00038 #if defined(POLARSSL_HAVEGE_C) 00039 #include "polarssl/havege.h" 00040 #endif 00041 00042 #if !defined(POLARSSL_NO_PLATFORM_ENTROPY) 00043 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00044 00045 #if !defined(_WIN32_WINNT) 00046 #define _WIN32_WINNT 0x0400 00047 #endif 00048 #include <windows.h> 00049 #include <wincrypt.h> 00050 00051 int platform_entropy_poll( void *data, unsigned char *output, size_t len, 00052 size_t *olen ) 00053 { 00054 HCRYPTPROV provider; 00055 ((void) data); 00056 *olen = 0; 00057 00058 if( CryptAcquireContext( &provider, NULL, NULL, 00059 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) 00060 { 00061 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); 00062 } 00063 00064 if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) 00065 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); 00066 00067 CryptReleaseContext( provider, 0 ); 00068 *olen = len; 00069 00070 return( 0 ); 00071 } 00072 #else /* _WIN32 && !EFIX64 && !EFI32 */ 00073 00074 /* 00075 * Test for Linux getrandom() support. 00076 * Since there is no wrapper in the libc yet, use the generic syscall wrapper 00077 * available in GNU libc and compatible libc's (eg uClibc). 00078 */ 00079 #if defined(__linux__) && defined(__GLIBC__) 00080 #include <linux/version.h> 00081 #include <unistd.h> 00082 #include <sys/syscall.h> 00083 #if defined(SYS_getrandom) 00084 #define HAVE_GETRANDOM 00085 static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) 00086 { 00087 return( syscall( SYS_getrandom, buf, buflen, flags ) ); 00088 } 00089 00090 #include <sys/utsname.h> 00091 /* Check if version is at least 3.17.0 */ 00092 static int check_version_3_17_plus( void ) 00093 { 00094 int minor; 00095 struct utsname un; 00096 const char *ver; 00097 00098 /* Get version information */ 00099 uname(&un); 00100 ver = un.release; 00101 00102 /* Check major version; assume a single digit */ 00103 if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' ) 00104 return( -1 ); 00105 00106 if( ver[0] - '0' > 3 ) 00107 return( 0 ); 00108 00109 /* Ok, so now we know major == 3, check minor. 00110 * Assume 1 or 2 digits. */ 00111 if( ver[2] < '0' || ver[2] > '9' ) 00112 return( -1 ); 00113 00114 minor = ver[2] - '0'; 00115 00116 if( ver[3] >= '0' && ver[3] <= '9' ) 00117 minor = 10 * minor + ver[3] - '0'; 00118 else if( ver [3] != '.' ) 00119 return( -1 ); 00120 00121 if( minor < 17 ) 00122 return( -1 ); 00123 00124 return( 0 ); 00125 } 00126 static int has_getrandom = -1; 00127 #endif /* SYS_getrandom */ 00128 #endif /* __linux__ */ 00129 00130 #include <stdio.h> 00131 00132 int platform_entropy_poll( void *data, 00133 unsigned char *output, size_t len, size_t *olen ) 00134 { 00135 FILE *file; 00136 size_t ret; 00137 ((void) data); 00138 00139 #if defined(HAVE_GETRANDOM) 00140 if( has_getrandom == -1 ) 00141 has_getrandom = ( check_version_3_17_plus() == 0 ); 00142 00143 if( has_getrandom ) 00144 { 00145 int ret; 00146 00147 if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 ) 00148 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); 00149 00150 *olen = ret; 00151 return( 0 ); 00152 } 00153 #endif /* HAVE_GETRANDOM */ 00154 00155 *olen = 0; 00156 00157 file = fopen( "/dev/urandom", "rb" ); 00158 if( file == NULL ) 00159 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); 00160 00161 ret = fread( output, 1, len, file ); 00162 if( ret != len ) 00163 { 00164 fclose( file ); 00165 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); 00166 } 00167 00168 fclose( file ); 00169 *olen = len; 00170 00171 return( 0 ); 00172 } 00173 #endif /* _WIN32 && !EFIX64 && !EFI32 */ 00174 #endif /* !POLARSSL_NO_PLATFORM_ENTROPY */ 00175 00176 #if defined(POLARSSL_TIMING_C) 00177 int hardclock_poll( void *data, 00178 unsigned char *output, size_t len, size_t *olen ) 00179 { 00180 unsigned long timer = hardclock(); 00181 ((void) data); 00182 *olen = 0; 00183 00184 if( len < sizeof(unsigned long) ) 00185 return( 0 ); 00186 00187 memcpy( output, &timer, sizeof(unsigned long) ); 00188 *olen = sizeof(unsigned long); 00189 00190 return( 0 ); 00191 } 00192 #endif /* POLARSSL_TIMING_C */ 00193 00194 #if defined(POLARSSL_HAVEGE_C) 00195 int havege_poll( void *data, 00196 unsigned char *output, size_t len, size_t *olen ) 00197 { 00198 havege_state *hs = (havege_state *) data; 00199 *olen = 0; 00200 00201 if( havege_random( hs, output, len ) != 0 ) 00202 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); 00203 00204 *olen = len; 00205 00206 return( 0 ); 00207 } 00208 #endif /* POLARSSL_HAVEGE_C */ 00209 00210 #endif /* POLARSSL_ENTROPY_C */ 00211
Generated on Tue Jul 12 2022 13:50:37 by 1.7.2