mbed TLS Build

Dependents:   Encrypt_Decrypt1 mbed_blink_tls encrypt encrypt

Committer:
markrad
Date:
Thu Jan 05 00:18:44 2017 +0000
Revision:
0:cdf462088d13
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 0:cdf462088d13 1 /*
markrad 0:cdf462088d13 2 * Platform-specific and custom entropy polling functions
markrad 0:cdf462088d13 3 *
markrad 0:cdf462088d13 4 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
markrad 0:cdf462088d13 5 * SPDX-License-Identifier: Apache-2.0
markrad 0:cdf462088d13 6 *
markrad 0:cdf462088d13 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
markrad 0:cdf462088d13 8 * not use this file except in compliance with the License.
markrad 0:cdf462088d13 9 * You may obtain a copy of the License at
markrad 0:cdf462088d13 10 *
markrad 0:cdf462088d13 11 * http://www.apache.org/licenses/LICENSE-2.0
markrad 0:cdf462088d13 12 *
markrad 0:cdf462088d13 13 * Unless required by applicable law or agreed to in writing, software
markrad 0:cdf462088d13 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
markrad 0:cdf462088d13 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
markrad 0:cdf462088d13 16 * See the License for the specific language governing permissions and
markrad 0:cdf462088d13 17 * limitations under the License.
markrad 0:cdf462088d13 18 *
markrad 0:cdf462088d13 19 * This file is part of mbed TLS (https://tls.mbed.org)
markrad 0:cdf462088d13 20 */
markrad 0:cdf462088d13 21
markrad 0:cdf462088d13 22 #if !defined(MBEDTLS_CONFIG_FILE)
markrad 0:cdf462088d13 23 #include "mbedtls/config.h"
markrad 0:cdf462088d13 24 #else
markrad 0:cdf462088d13 25 #include MBEDTLS_CONFIG_FILE
markrad 0:cdf462088d13 26 #endif
markrad 0:cdf462088d13 27
markrad 0:cdf462088d13 28 #if defined(MBEDTLS_ENTROPY_C)
markrad 0:cdf462088d13 29
markrad 0:cdf462088d13 30 #include "mbedtls/entropy.h"
markrad 0:cdf462088d13 31 #include "mbedtls/entropy_poll.h"
markrad 0:cdf462088d13 32
markrad 0:cdf462088d13 33 #if defined(MBEDTLS_TIMING_C)
markrad 0:cdf462088d13 34 #include <string.h>
markrad 0:cdf462088d13 35 #include "mbedtls/timing.h"
markrad 0:cdf462088d13 36 #endif
markrad 0:cdf462088d13 37 #if defined(MBEDTLS_HAVEGE_C)
markrad 0:cdf462088d13 38 #include "mbedtls/havege.h"
markrad 0:cdf462088d13 39 #endif
markrad 0:cdf462088d13 40 #if defined(MBEDTLS_ENTROPY_NV_SEED)
markrad 0:cdf462088d13 41 #include "mbedtls/platform.h"
markrad 0:cdf462088d13 42 #endif
markrad 0:cdf462088d13 43
markrad 0:cdf462088d13 44 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
markrad 0:cdf462088d13 45
markrad 0:cdf462088d13 46 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
markrad 0:cdf462088d13 47 !defined(__APPLE__) && !defined(_WIN32)
markrad 0:cdf462088d13 48 #error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
markrad 0:cdf462088d13 49 #endif
markrad 0:cdf462088d13 50
markrad 0:cdf462088d13 51 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
markrad 0:cdf462088d13 52
markrad 0:cdf462088d13 53 #if !defined(_WIN32_WINNT)
markrad 0:cdf462088d13 54 #define _WIN32_WINNT 0x0400
markrad 0:cdf462088d13 55 #endif
markrad 0:cdf462088d13 56 #include <windows.h>
markrad 0:cdf462088d13 57 #include <wincrypt.h>
markrad 0:cdf462088d13 58
markrad 0:cdf462088d13 59 int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
markrad 0:cdf462088d13 60 size_t *olen )
markrad 0:cdf462088d13 61 {
markrad 0:cdf462088d13 62 HCRYPTPROV provider;
markrad 0:cdf462088d13 63 ((void) data);
markrad 0:cdf462088d13 64 *olen = 0;
markrad 0:cdf462088d13 65
markrad 0:cdf462088d13 66 if( CryptAcquireContext( &provider, NULL, NULL,
markrad 0:cdf462088d13 67 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
markrad 0:cdf462088d13 68 {
markrad 0:cdf462088d13 69 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
markrad 0:cdf462088d13 70 }
markrad 0:cdf462088d13 71
markrad 0:cdf462088d13 72 if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
markrad 0:cdf462088d13 73 {
markrad 0:cdf462088d13 74 CryptReleaseContext( provider, 0 );
markrad 0:cdf462088d13 75 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
markrad 0:cdf462088d13 76 }
markrad 0:cdf462088d13 77
markrad 0:cdf462088d13 78 CryptReleaseContext( provider, 0 );
markrad 0:cdf462088d13 79 *olen = len;
markrad 0:cdf462088d13 80
markrad 0:cdf462088d13 81 return( 0 );
markrad 0:cdf462088d13 82 }
markrad 0:cdf462088d13 83 #else /* _WIN32 && !EFIX64 && !EFI32 */
markrad 0:cdf462088d13 84
markrad 0:cdf462088d13 85 /*
markrad 0:cdf462088d13 86 * Test for Linux getrandom() support.
markrad 0:cdf462088d13 87 * Since there is no wrapper in the libc yet, use the generic syscall wrapper
markrad 0:cdf462088d13 88 * available in GNU libc and compatible libc's (eg uClibc).
markrad 0:cdf462088d13 89 */
markrad 0:cdf462088d13 90 #if defined(__linux__) && defined(__GLIBC__)
markrad 0:cdf462088d13 91 #include <unistd.h>
markrad 0:cdf462088d13 92 #include <sys/syscall.h>
markrad 0:cdf462088d13 93 #if defined(SYS_getrandom)
markrad 0:cdf462088d13 94 #define HAVE_GETRANDOM
markrad 0:cdf462088d13 95
markrad 0:cdf462088d13 96 static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
markrad 0:cdf462088d13 97 {
markrad 0:cdf462088d13 98 /* MemSan cannot understand that the syscall writes to the buffer */
markrad 0:cdf462088d13 99 #if defined(__has_feature)
markrad 0:cdf462088d13 100 #if __has_feature(memory_sanitizer)
markrad 0:cdf462088d13 101 memset( buf, 0, buflen );
markrad 0:cdf462088d13 102 #endif
markrad 0:cdf462088d13 103 #endif
markrad 0:cdf462088d13 104
markrad 0:cdf462088d13 105 return( syscall( SYS_getrandom, buf, buflen, flags ) );
markrad 0:cdf462088d13 106 }
markrad 0:cdf462088d13 107
markrad 0:cdf462088d13 108 #include <sys/utsname.h>
markrad 0:cdf462088d13 109 /* Check if version is at least 3.17.0 */
markrad 0:cdf462088d13 110 static int check_version_3_17_plus( void )
markrad 0:cdf462088d13 111 {
markrad 0:cdf462088d13 112 int minor;
markrad 0:cdf462088d13 113 struct utsname un;
markrad 0:cdf462088d13 114 const char *ver;
markrad 0:cdf462088d13 115
markrad 0:cdf462088d13 116 /* Get version information */
markrad 0:cdf462088d13 117 uname(&un);
markrad 0:cdf462088d13 118 ver = un.release;
markrad 0:cdf462088d13 119
markrad 0:cdf462088d13 120 /* Check major version; assume a single digit */
markrad 0:cdf462088d13 121 if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
markrad 0:cdf462088d13 122 return( -1 );
markrad 0:cdf462088d13 123
markrad 0:cdf462088d13 124 if( ver[0] - '0' > 3 )
markrad 0:cdf462088d13 125 return( 0 );
markrad 0:cdf462088d13 126
markrad 0:cdf462088d13 127 /* Ok, so now we know major == 3, check minor.
markrad 0:cdf462088d13 128 * Assume 1 or 2 digits. */
markrad 0:cdf462088d13 129 if( ver[2] < '0' || ver[2] > '9' )
markrad 0:cdf462088d13 130 return( -1 );
markrad 0:cdf462088d13 131
markrad 0:cdf462088d13 132 minor = ver[2] - '0';
markrad 0:cdf462088d13 133
markrad 0:cdf462088d13 134 if( ver[3] >= '0' && ver[3] <= '9' )
markrad 0:cdf462088d13 135 minor = 10 * minor + ver[3] - '0';
markrad 0:cdf462088d13 136 else if( ver [3] != '.' )
markrad 0:cdf462088d13 137 return( -1 );
markrad 0:cdf462088d13 138
markrad 0:cdf462088d13 139 if( minor < 17 )
markrad 0:cdf462088d13 140 return( -1 );
markrad 0:cdf462088d13 141
markrad 0:cdf462088d13 142 return( 0 );
markrad 0:cdf462088d13 143 }
markrad 0:cdf462088d13 144 static int has_getrandom = -1;
markrad 0:cdf462088d13 145 #endif /* SYS_getrandom */
markrad 0:cdf462088d13 146 #endif /* __linux__ */
markrad 0:cdf462088d13 147
markrad 0:cdf462088d13 148 #include <stdio.h>
markrad 0:cdf462088d13 149
markrad 0:cdf462088d13 150 int mbedtls_platform_entropy_poll( void *data,
markrad 0:cdf462088d13 151 unsigned char *output, size_t len, size_t *olen )
markrad 0:cdf462088d13 152 {
markrad 0:cdf462088d13 153 FILE *file;
markrad 0:cdf462088d13 154 size_t read_len;
markrad 0:cdf462088d13 155 ((void) data);
markrad 0:cdf462088d13 156
markrad 0:cdf462088d13 157 #if defined(HAVE_GETRANDOM)
markrad 0:cdf462088d13 158 if( has_getrandom == -1 )
markrad 0:cdf462088d13 159 has_getrandom = ( check_version_3_17_plus() == 0 );
markrad 0:cdf462088d13 160
markrad 0:cdf462088d13 161 if( has_getrandom )
markrad 0:cdf462088d13 162 {
markrad 0:cdf462088d13 163 int ret;
markrad 0:cdf462088d13 164
markrad 0:cdf462088d13 165 if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
markrad 0:cdf462088d13 166 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
markrad 0:cdf462088d13 167
markrad 0:cdf462088d13 168 *olen = ret;
markrad 0:cdf462088d13 169 return( 0 );
markrad 0:cdf462088d13 170 }
markrad 0:cdf462088d13 171 #endif /* HAVE_GETRANDOM */
markrad 0:cdf462088d13 172
markrad 0:cdf462088d13 173 *olen = 0;
markrad 0:cdf462088d13 174
markrad 0:cdf462088d13 175 file = fopen( "/dev/urandom", "rb" );
markrad 0:cdf462088d13 176 if( file == NULL )
markrad 0:cdf462088d13 177 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
markrad 0:cdf462088d13 178
markrad 0:cdf462088d13 179 read_len = fread( output, 1, len, file );
markrad 0:cdf462088d13 180 if( read_len != len )
markrad 0:cdf462088d13 181 {
markrad 0:cdf462088d13 182 fclose( file );
markrad 0:cdf462088d13 183 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
markrad 0:cdf462088d13 184 }
markrad 0:cdf462088d13 185
markrad 0:cdf462088d13 186 fclose( file );
markrad 0:cdf462088d13 187 *olen = len;
markrad 0:cdf462088d13 188
markrad 0:cdf462088d13 189 return( 0 );
markrad 0:cdf462088d13 190 }
markrad 0:cdf462088d13 191 #endif /* _WIN32 && !EFIX64 && !EFI32 */
markrad 0:cdf462088d13 192 #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
markrad 0:cdf462088d13 193
markrad 0:cdf462088d13 194 #if defined(MBEDTLS_TEST_NULL_ENTROPY)
markrad 0:cdf462088d13 195 int mbedtls_null_entropy_poll( void *data,
markrad 0:cdf462088d13 196 unsigned char *output, size_t len, size_t *olen )
markrad 0:cdf462088d13 197 {
markrad 0:cdf462088d13 198 ((void) data);
markrad 0:cdf462088d13 199 ((void) output);
markrad 0:cdf462088d13 200 *olen = 0;
markrad 0:cdf462088d13 201
markrad 0:cdf462088d13 202 if( len < sizeof(unsigned char) )
markrad 0:cdf462088d13 203 return( 0 );
markrad 0:cdf462088d13 204
markrad 0:cdf462088d13 205 *olen = sizeof(unsigned char);
markrad 0:cdf462088d13 206
markrad 0:cdf462088d13 207 return( 0 );
markrad 0:cdf462088d13 208 }
markrad 0:cdf462088d13 209 #endif
markrad 0:cdf462088d13 210
markrad 0:cdf462088d13 211 #if defined(MBEDTLS_TIMING_C)
markrad 0:cdf462088d13 212 int mbedtls_hardclock_poll( void *data,
markrad 0:cdf462088d13 213 unsigned char *output, size_t len, size_t *olen )
markrad 0:cdf462088d13 214 {
markrad 0:cdf462088d13 215 unsigned long timer = mbedtls_timing_hardclock();
markrad 0:cdf462088d13 216 ((void) data);
markrad 0:cdf462088d13 217 *olen = 0;
markrad 0:cdf462088d13 218
markrad 0:cdf462088d13 219 if( len < sizeof(unsigned long) )
markrad 0:cdf462088d13 220 return( 0 );
markrad 0:cdf462088d13 221
markrad 0:cdf462088d13 222 memcpy( output, &timer, sizeof(unsigned long) );
markrad 0:cdf462088d13 223 *olen = sizeof(unsigned long);
markrad 0:cdf462088d13 224
markrad 0:cdf462088d13 225 return( 0 );
markrad 0:cdf462088d13 226 }
markrad 0:cdf462088d13 227 #endif /* MBEDTLS_TIMING_C */
markrad 0:cdf462088d13 228
markrad 0:cdf462088d13 229 #if defined(MBEDTLS_HAVEGE_C)
markrad 0:cdf462088d13 230 int mbedtls_havege_poll( void *data,
markrad 0:cdf462088d13 231 unsigned char *output, size_t len, size_t *olen )
markrad 0:cdf462088d13 232 {
markrad 0:cdf462088d13 233 mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
markrad 0:cdf462088d13 234 *olen = 0;
markrad 0:cdf462088d13 235
markrad 0:cdf462088d13 236 if( mbedtls_havege_random( hs, output, len ) != 0 )
markrad 0:cdf462088d13 237 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
markrad 0:cdf462088d13 238
markrad 0:cdf462088d13 239 *olen = len;
markrad 0:cdf462088d13 240
markrad 0:cdf462088d13 241 return( 0 );
markrad 0:cdf462088d13 242 }
markrad 0:cdf462088d13 243 #endif /* MBEDTLS_HAVEGE_C */
markrad 0:cdf462088d13 244
markrad 0:cdf462088d13 245 #if defined(MBEDTLS_ENTROPY_NV_SEED)
markrad 0:cdf462088d13 246 int mbedtls_nv_seed_poll( void *data,
markrad 0:cdf462088d13 247 unsigned char *output, size_t len, size_t *olen )
markrad 0:cdf462088d13 248 {
markrad 0:cdf462088d13 249 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
markrad 0:cdf462088d13 250 size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
markrad 0:cdf462088d13 251 ((void) data);
markrad 0:cdf462088d13 252
markrad 0:cdf462088d13 253 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
markrad 0:cdf462088d13 254
markrad 0:cdf462088d13 255 if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
markrad 0:cdf462088d13 256 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
markrad 0:cdf462088d13 257
markrad 0:cdf462088d13 258 if( len < use_len )
markrad 0:cdf462088d13 259 use_len = len;
markrad 0:cdf462088d13 260
markrad 0:cdf462088d13 261 memcpy( output, buf, use_len );
markrad 0:cdf462088d13 262 *olen = use_len;
markrad 0:cdf462088d13 263
markrad 0:cdf462088d13 264 return( 0 );
markrad 0:cdf462088d13 265 }
markrad 0:cdf462088d13 266 #endif /* MBEDTLS_ENTROPY_NV_SEED */
markrad 0:cdf462088d13 267
markrad 0:cdf462088d13 268 #endif /* MBEDTLS_ENTROPY_C */