Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 Sun Jul 17 2022 08:25:22 by 1.7.2