mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /*
ansond 0:137634ff4186 2 * Platform-specific and custom entropy polling functions
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 9 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 10 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 11 * (at your option) any later version.
ansond 0:137634ff4186 12 *
ansond 0:137634ff4186 13 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 16 * GNU General Public License for more details.
ansond 0:137634ff4186 17 *
ansond 0:137634ff4186 18 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 19 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 21 */
ansond 0:137634ff4186 22
ansond 0:137634ff4186 23 #if !defined(POLARSSL_CONFIG_FILE)
ansond 0:137634ff4186 24 #include "polarssl/config.h"
ansond 0:137634ff4186 25 #else
ansond 0:137634ff4186 26 #include POLARSSL_CONFIG_FILE
ansond 0:137634ff4186 27 #endif
ansond 0:137634ff4186 28
ansond 0:137634ff4186 29 #if defined(POLARSSL_ENTROPY_C)
ansond 0:137634ff4186 30
ansond 0:137634ff4186 31 #include "polarssl/entropy.h"
ansond 0:137634ff4186 32 #include "polarssl/entropy_poll.h"
ansond 0:137634ff4186 33
ansond 0:137634ff4186 34 #if defined(POLARSSL_TIMING_C)
ansond 0:137634ff4186 35 #include <string.h>
ansond 0:137634ff4186 36 #include "polarssl/timing.h"
ansond 0:137634ff4186 37 #endif
ansond 0:137634ff4186 38 #if defined(POLARSSL_HAVEGE_C)
ansond 0:137634ff4186 39 #include "polarssl/havege.h"
ansond 0:137634ff4186 40 #endif
ansond 0:137634ff4186 41
ansond 0:137634ff4186 42 #if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
ansond 0:137634ff4186 43 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
ansond 0:137634ff4186 44
ansond 0:137634ff4186 45 #if !defined(_WIN32_WINNT)
ansond 0:137634ff4186 46 #define _WIN32_WINNT 0x0400
ansond 0:137634ff4186 47 #endif
ansond 0:137634ff4186 48 #include <windows.h>
ansond 0:137634ff4186 49 #include <wincrypt.h>
ansond 0:137634ff4186 50
ansond 0:137634ff4186 51 int platform_entropy_poll( void *data, unsigned char *output, size_t len,
ansond 0:137634ff4186 52 size_t *olen )
ansond 0:137634ff4186 53 {
ansond 0:137634ff4186 54 HCRYPTPROV provider;
ansond 0:137634ff4186 55 ((void) data);
ansond 0:137634ff4186 56 *olen = 0;
ansond 0:137634ff4186 57
ansond 0:137634ff4186 58 if( CryptAcquireContext( &provider, NULL, NULL,
ansond 0:137634ff4186 59 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
ansond 0:137634ff4186 60 {
ansond 0:137634ff4186 61 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
ansond 0:137634ff4186 62 }
ansond 0:137634ff4186 63
ansond 0:137634ff4186 64 if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
ansond 0:137634ff4186 65 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
ansond 0:137634ff4186 66
ansond 0:137634ff4186 67 CryptReleaseContext( provider, 0 );
ansond 0:137634ff4186 68 *olen = len;
ansond 0:137634ff4186 69
ansond 0:137634ff4186 70 return( 0 );
ansond 0:137634ff4186 71 }
ansond 0:137634ff4186 72 #else /* _WIN32 && !EFIX64 && !EFI32 */
ansond 0:137634ff4186 73
ansond 0:137634ff4186 74 /*
ansond 0:137634ff4186 75 * Test for Linux getrandom() support.
ansond 0:137634ff4186 76 * Since there is no wrapper in the libc yet, use the generic syscall wrapper
ansond 0:137634ff4186 77 * available in GNU libc and compatible libc's (eg uClibc).
ansond 0:137634ff4186 78 */
ansond 0:137634ff4186 79 #if defined(__linux__) && defined(__GLIBC__)
ansond 0:137634ff4186 80 #include <linux/version.h>
ansond 0:137634ff4186 81 #include <unistd.h>
ansond 0:137634ff4186 82 #include <sys/syscall.h>
ansond 0:137634ff4186 83 #if defined(SYS_getrandom)
ansond 0:137634ff4186 84 #define HAVE_GETRANDOM
ansond 0:137634ff4186 85 static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
ansond 0:137634ff4186 86 {
ansond 0:137634ff4186 87 return( syscall( SYS_getrandom, buf, buflen, flags ) );
ansond 0:137634ff4186 88 }
ansond 0:137634ff4186 89
ansond 0:137634ff4186 90 #include <sys/utsname.h>
ansond 0:137634ff4186 91 /* Check if version is at least 3.17.0 */
ansond 0:137634ff4186 92 static int check_version_3_17_plus( void )
ansond 0:137634ff4186 93 {
ansond 0:137634ff4186 94 int minor;
ansond 0:137634ff4186 95 struct utsname un;
ansond 0:137634ff4186 96 const char *ver;
ansond 0:137634ff4186 97
ansond 0:137634ff4186 98 /* Get version information */
ansond 0:137634ff4186 99 uname(&un);
ansond 0:137634ff4186 100 ver = un.release;
ansond 0:137634ff4186 101
ansond 0:137634ff4186 102 /* Check major version; assume a single digit */
ansond 0:137634ff4186 103 if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
ansond 0:137634ff4186 104 return( -1 );
ansond 0:137634ff4186 105
ansond 0:137634ff4186 106 if( ver[0] - '0' > 3 )
ansond 0:137634ff4186 107 return( 0 );
ansond 0:137634ff4186 108
ansond 0:137634ff4186 109 /* Ok, so now we know major == 3, check minor.
ansond 0:137634ff4186 110 * Assume 1 or 2 digits. */
ansond 0:137634ff4186 111 if( ver[2] < '0' || ver[2] > '9' )
ansond 0:137634ff4186 112 return( -1 );
ansond 0:137634ff4186 113
ansond 0:137634ff4186 114 minor = ver[2] - '0';
ansond 0:137634ff4186 115
ansond 0:137634ff4186 116 if( ver[3] >= '0' && ver[3] <= '9' )
ansond 0:137634ff4186 117 minor = 10 * minor + ver[3] - '0';
ansond 0:137634ff4186 118 else if( ver [3] != '.' )
ansond 0:137634ff4186 119 return( -1 );
ansond 0:137634ff4186 120
ansond 0:137634ff4186 121 if( minor < 17 )
ansond 0:137634ff4186 122 return( -1 );
ansond 0:137634ff4186 123
ansond 0:137634ff4186 124 return( 0 );
ansond 0:137634ff4186 125 }
ansond 0:137634ff4186 126 static int has_getrandom = -1;
ansond 0:137634ff4186 127 #endif /* SYS_getrandom */
ansond 0:137634ff4186 128 #endif /* __linux__ */
ansond 0:137634ff4186 129
ansond 0:137634ff4186 130 #include <stdio.h>
ansond 0:137634ff4186 131
ansond 0:137634ff4186 132 int platform_entropy_poll( void *data,
ansond 0:137634ff4186 133 unsigned char *output, size_t len, size_t *olen )
ansond 0:137634ff4186 134 {
ansond 0:137634ff4186 135 FILE *file;
ansond 0:137634ff4186 136 size_t ret;
ansond 0:137634ff4186 137 ((void) data);
ansond 0:137634ff4186 138
ansond 0:137634ff4186 139 #if defined(HAVE_GETRANDOM)
ansond 0:137634ff4186 140 if( has_getrandom == -1 )
ansond 0:137634ff4186 141 has_getrandom = ( check_version_3_17_plus() == 0 );
ansond 0:137634ff4186 142
ansond 0:137634ff4186 143 if( has_getrandom )
ansond 0:137634ff4186 144 {
ansond 0:137634ff4186 145 int ret;
ansond 0:137634ff4186 146
ansond 0:137634ff4186 147 if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
ansond 0:137634ff4186 148 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
ansond 0:137634ff4186 149
ansond 0:137634ff4186 150 *olen = ret;
ansond 0:137634ff4186 151 return( 0 );
ansond 0:137634ff4186 152 }
ansond 0:137634ff4186 153 #endif /* HAVE_GETRANDOM */
ansond 0:137634ff4186 154
ansond 0:137634ff4186 155 *olen = 0;
ansond 0:137634ff4186 156
ansond 0:137634ff4186 157 file = fopen( "/dev/urandom", "rb" );
ansond 0:137634ff4186 158 if( file == NULL )
ansond 0:137634ff4186 159 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
ansond 0:137634ff4186 160
ansond 0:137634ff4186 161 ret = fread( output, 1, len, file );
ansond 0:137634ff4186 162 if( ret != len )
ansond 0:137634ff4186 163 {
ansond 0:137634ff4186 164 fclose( file );
ansond 0:137634ff4186 165 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
ansond 0:137634ff4186 166 }
ansond 0:137634ff4186 167
ansond 0:137634ff4186 168 fclose( file );
ansond 0:137634ff4186 169 *olen = len;
ansond 0:137634ff4186 170
ansond 0:137634ff4186 171 return( 0 );
ansond 0:137634ff4186 172 }
ansond 0:137634ff4186 173 #endif /* _WIN32 && !EFIX64 && !EFI32 */
ansond 0:137634ff4186 174 #endif /* !POLARSSL_NO_PLATFORM_ENTROPY */
ansond 0:137634ff4186 175
ansond 0:137634ff4186 176 #if defined(POLARSSL_TIMING_C)
ansond 0:137634ff4186 177 int hardclock_poll( void *data,
ansond 0:137634ff4186 178 unsigned char *output, size_t len, size_t *olen )
ansond 0:137634ff4186 179 {
ansond 0:137634ff4186 180 unsigned long timer = hardclock();
ansond 0:137634ff4186 181 ((void) data);
ansond 0:137634ff4186 182 *olen = 0;
ansond 0:137634ff4186 183
ansond 0:137634ff4186 184 if( len < sizeof(unsigned long) )
ansond 0:137634ff4186 185 return( 0 );
ansond 0:137634ff4186 186
ansond 0:137634ff4186 187 memcpy( output, &timer, sizeof(unsigned long) );
ansond 0:137634ff4186 188 *olen = sizeof(unsigned long);
ansond 0:137634ff4186 189
ansond 0:137634ff4186 190 return( 0 );
ansond 0:137634ff4186 191 }
ansond 0:137634ff4186 192 #endif /* POLARSSL_TIMING_C */
ansond 0:137634ff4186 193
ansond 0:137634ff4186 194 #if defined(POLARSSL_HAVEGE_C)
ansond 0:137634ff4186 195 int havege_poll( void *data,
ansond 0:137634ff4186 196 unsigned char *output, size_t len, size_t *olen )
ansond 0:137634ff4186 197 {
ansond 0:137634ff4186 198 havege_state *hs = (havege_state *) data;
ansond 0:137634ff4186 199 *olen = 0;
ansond 0:137634ff4186 200
ansond 0:137634ff4186 201 if( havege_random( hs, output, len ) != 0 )
ansond 0:137634ff4186 202 return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
ansond 0:137634ff4186 203
ansond 0:137634ff4186 204 *olen = len;
ansond 0:137634ff4186 205
ansond 0:137634ff4186 206 return( 0 );
ansond 0:137634ff4186 207 }
ansond 0:137634ff4186 208 #endif /* POLARSSL_HAVEGE_C */
ansond 0:137634ff4186 209
ansond 0:137634ff4186 210 #endif /* POLARSSL_ENTROPY_C */
ansond 0:137634ff4186 211