Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedtls by
entropy_poll.c
00001 /* 00002 * Platform-specific and custom entropy polling functions 00003 * 00004 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if !defined(MBEDTLS_CONFIG_FILE) 00023 #include "mbedtls/config.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_ENTROPY_C) 00029 00030 #include "mbedtls/entropy.h" 00031 #include "mbedtls/entropy_poll.h" 00032 00033 #if defined(MBEDTLS_TIMING_C) 00034 #include <string.h> 00035 #include "mbedtls/timing.h" 00036 #endif 00037 #if defined(MBEDTLS_HAVEGE_C) 00038 #include "mbedtls/havege.h" 00039 #endif 00040 #if defined(MBEDTLS_ENTROPY_NV_SEED) 00041 #include "mbedtls/platform.h" 00042 #endif 00043 00044 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) 00045 00046 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ 00047 !defined(__APPLE__) && !defined(_WIN32) 00048 #error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" 00049 #endif 00050 00051 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00052 00053 #if !defined(_WIN32_WINNT) 00054 #define _WIN32_WINNT 0x0400 00055 #endif 00056 #include <windows.h> 00057 #include <wincrypt.h> 00058 00059 int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, 00060 size_t *olen ) 00061 { 00062 HCRYPTPROV provider; 00063 ((void) data); 00064 *olen = 0; 00065 00066 if( CryptAcquireContext( &provider, NULL, NULL, 00067 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) 00068 { 00069 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 00070 } 00071 00072 if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) 00073 { 00074 CryptReleaseContext( provider, 0 ); 00075 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 00076 } 00077 00078 CryptReleaseContext( provider, 0 ); 00079 *olen = len; 00080 00081 return( 0 ); 00082 } 00083 #else /* _WIN32 && !EFIX64 && !EFI32 */ 00084 00085 /* 00086 * Test for Linux getrandom() support. 00087 * Since there is no wrapper in the libc yet, use the generic syscall wrapper 00088 * available in GNU libc and compatible libc's (eg uClibc). 00089 */ 00090 #if defined(__linux__) && defined(__GLIBC__) 00091 #include <unistd.h> 00092 #include <sys/syscall.h> 00093 #if defined(SYS_getrandom) 00094 #define HAVE_GETRANDOM 00095 00096 static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) 00097 { 00098 /* MemSan cannot understand that the syscall writes to the buffer */ 00099 #if defined(__has_feature) 00100 #if __has_feature(memory_sanitizer) 00101 memset( buf, 0, buflen ); 00102 #endif 00103 #endif 00104 00105 return( syscall( SYS_getrandom, buf, buflen, flags ) ); 00106 } 00107 00108 #include <sys/utsname.h> 00109 /* Check if version is at least 3.17.0 */ 00110 static int check_version_3_17_plus( void ) 00111 { 00112 int minor; 00113 struct utsname un; 00114 const char *ver; 00115 00116 /* Get version information */ 00117 uname(&un); 00118 ver = un.release; 00119 00120 /* Check major version; assume a single digit */ 00121 if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' ) 00122 return( -1 ); 00123 00124 if( ver[0] - '0' > 3 ) 00125 return( 0 ); 00126 00127 /* Ok, so now we know major == 3, check minor. 00128 * Assume 1 or 2 digits. */ 00129 if( ver[2] < '0' || ver[2] > '9' ) 00130 return( -1 ); 00131 00132 minor = ver[2] - '0'; 00133 00134 if( ver[3] >= '0' && ver[3] <= '9' ) 00135 minor = 10 * minor + ver[3] - '0'; 00136 else if( ver [3] != '.' ) 00137 return( -1 ); 00138 00139 if( minor < 17 ) 00140 return( -1 ); 00141 00142 return( 0 ); 00143 } 00144 static int has_getrandom = -1; 00145 #endif /* SYS_getrandom */ 00146 #endif /* __linux__ */ 00147 00148 #include <stdio.h> 00149 00150 int mbedtls_platform_entropy_poll( void *data, 00151 unsigned char *output, size_t len, size_t *olen ) 00152 { 00153 FILE *file; 00154 size_t read_len; 00155 ((void) data); 00156 00157 #if defined(HAVE_GETRANDOM) 00158 if( has_getrandom == -1 ) 00159 has_getrandom = ( check_version_3_17_plus() == 0 ); 00160 00161 if( has_getrandom ) 00162 { 00163 int ret; 00164 00165 if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 ) 00166 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 00167 00168 *olen = ret; 00169 return( 0 ); 00170 } 00171 #endif /* HAVE_GETRANDOM */ 00172 00173 *olen = 0; 00174 00175 file = fopen( "/dev/urandom", "rb" ); 00176 if( file == NULL ) 00177 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 00178 00179 read_len = fread( output, 1, len, file ); 00180 if( read_len != len ) 00181 { 00182 fclose( file ); 00183 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 00184 } 00185 00186 fclose( file ); 00187 *olen = len; 00188 00189 return( 0 ); 00190 } 00191 #endif /* _WIN32 && !EFIX64 && !EFI32 */ 00192 #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ 00193 00194 #if defined(MBEDTLS_TEST_NULL_ENTROPY) 00195 int mbedtls_null_entropy_poll( void *data, 00196 unsigned char *output, size_t len, size_t *olen ) 00197 { 00198 ((void) data); 00199 ((void) output); 00200 *olen = 0; 00201 00202 if( len < sizeof(unsigned char) ) 00203 return( 0 ); 00204 00205 *olen = sizeof(unsigned char); 00206 00207 return( 0 ); 00208 } 00209 #endif 00210 00211 #if defined(MBEDTLS_TIMING_C) 00212 int mbedtls_hardclock_poll( void *data, 00213 unsigned char *output, size_t len, size_t *olen ) 00214 { 00215 unsigned long timer = mbedtls_timing_hardclock(); 00216 ((void) data); 00217 *olen = 0; 00218 00219 if( len < sizeof(unsigned long) ) 00220 return( 0 ); 00221 00222 memcpy( output, &timer, sizeof(unsigned long) ); 00223 *olen = sizeof(unsigned long); 00224 00225 return( 0 ); 00226 } 00227 #endif /* MBEDTLS_TIMING_C */ 00228 00229 #if defined(MBEDTLS_HAVEGE_C) 00230 int mbedtls_havege_poll( void *data, 00231 unsigned char *output, size_t len, size_t *olen ) 00232 { 00233 mbedtls_havege_state *hs = (mbedtls_havege_state *) data; 00234 *olen = 0; 00235 00236 if( mbedtls_havege_random( hs, output, len ) != 0 ) 00237 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 00238 00239 *olen = len; 00240 00241 return( 0 ); 00242 } 00243 #endif /* MBEDTLS_HAVEGE_C */ 00244 00245 #if defined(MBEDTLS_ENTROPY_NV_SEED) 00246 int mbedtls_nv_seed_poll( void *data, 00247 unsigned char *output, size_t len, size_t *olen ) 00248 { 00249 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; 00250 size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; 00251 ((void) data); 00252 00253 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); 00254 00255 if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) 00256 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 00257 00258 if( len < use_len ) 00259 use_len = len; 00260 00261 memcpy( output, buf, use_len ); 00262 *olen = use_len; 00263 00264 return( 0 ); 00265 } 00266 #endif /* MBEDTLS_ENTROPY_NV_SEED */ 00267 00268 #endif /* MBEDTLS_ENTROPY_C */
Generated on Tue Jul 12 2022 17:25:41 by
