mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Committer:
Christopher Haster
Date:
Fri Jan 22 16:44:49 2016 -0600
Revision:
1:24750b9ad5ef
Initial move of mbedtls to mercurial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 1:24750b9ad5ef 1 /**
Christopher Haster 1:24750b9ad5ef 2 * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
Christopher Haster 1:24750b9ad5ef 3 *
Christopher Haster 1:24750b9ad5ef 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Christopher Haster 1:24750b9ad5ef 5 * SPDX-License-Identifier: Apache-2.0
Christopher Haster 1:24750b9ad5ef 6 *
Christopher Haster 1:24750b9ad5ef 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Christopher Haster 1:24750b9ad5ef 8 * not use this file except in compliance with the License.
Christopher Haster 1:24750b9ad5ef 9 * You may obtain a copy of the License at
Christopher Haster 1:24750b9ad5ef 10 *
Christopher Haster 1:24750b9ad5ef 11 * http://www.apache.org/licenses/LICENSE-2.0
Christopher Haster 1:24750b9ad5ef 12 *
Christopher Haster 1:24750b9ad5ef 13 * Unless required by applicable law or agreed to in writing, software
Christopher Haster 1:24750b9ad5ef 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Christopher Haster 1:24750b9ad5ef 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Christopher Haster 1:24750b9ad5ef 16 * See the License for the specific language governing permissions and
Christopher Haster 1:24750b9ad5ef 17 * limitations under the License.
Christopher Haster 1:24750b9ad5ef 18 *
Christopher Haster 1:24750b9ad5ef 19 * This file is part of mbed TLS (https://tls.mbed.org)
Christopher Haster 1:24750b9ad5ef 20 */
Christopher Haster 1:24750b9ad5ef 21 /*
Christopher Haster 1:24750b9ad5ef 22 * The HAVEGE RNG was designed by Andre Seznec in 2002.
Christopher Haster 1:24750b9ad5ef 23 *
Christopher Haster 1:24750b9ad5ef 24 * http://www.irisa.fr/caps/projects/hipsor/publi.php
Christopher Haster 1:24750b9ad5ef 25 *
Christopher Haster 1:24750b9ad5ef 26 * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
Christopher Haster 1:24750b9ad5ef 27 */
Christopher Haster 1:24750b9ad5ef 28
Christopher Haster 1:24750b9ad5ef 29 #if !defined(MBEDTLS_CONFIG_FILE)
Christopher Haster 1:24750b9ad5ef 30 #include "mbedtls/config.h"
Christopher Haster 1:24750b9ad5ef 31 #else
Christopher Haster 1:24750b9ad5ef 32 #include MBEDTLS_CONFIG_FILE
Christopher Haster 1:24750b9ad5ef 33 #endif
Christopher Haster 1:24750b9ad5ef 34
Christopher Haster 1:24750b9ad5ef 35 #if defined(MBEDTLS_HAVEGE_C)
Christopher Haster 1:24750b9ad5ef 36
Christopher Haster 1:24750b9ad5ef 37 #include "mbedtls/havege.h"
Christopher Haster 1:24750b9ad5ef 38 #include "mbedtls/timing.h"
Christopher Haster 1:24750b9ad5ef 39
Christopher Haster 1:24750b9ad5ef 40 #include <string.h>
Christopher Haster 1:24750b9ad5ef 41
Christopher Haster 1:24750b9ad5ef 42 /* Implementation that should never be optimized out by the compiler */
Christopher Haster 1:24750b9ad5ef 43 static void mbedtls_zeroize( void *v, size_t n ) {
Christopher Haster 1:24750b9ad5ef 44 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
Christopher Haster 1:24750b9ad5ef 45 }
Christopher Haster 1:24750b9ad5ef 46
Christopher Haster 1:24750b9ad5ef 47 /* ------------------------------------------------------------------------
Christopher Haster 1:24750b9ad5ef 48 * On average, one iteration accesses two 8-word blocks in the havege WALK
Christopher Haster 1:24750b9ad5ef 49 * table, and generates 16 words in the RES array.
Christopher Haster 1:24750b9ad5ef 50 *
Christopher Haster 1:24750b9ad5ef 51 * The data read in the WALK table is updated and permuted after each use.
Christopher Haster 1:24750b9ad5ef 52 * The result of the hardware clock counter read is used for this update.
Christopher Haster 1:24750b9ad5ef 53 *
Christopher Haster 1:24750b9ad5ef 54 * 25 conditional tests are present. The conditional tests are grouped in
Christopher Haster 1:24750b9ad5ef 55 * two nested groups of 12 conditional tests and 1 test that controls the
Christopher Haster 1:24750b9ad5ef 56 * permutation; on average, there should be 6 tests executed and 3 of them
Christopher Haster 1:24750b9ad5ef 57 * should be mispredicted.
Christopher Haster 1:24750b9ad5ef 58 * ------------------------------------------------------------------------
Christopher Haster 1:24750b9ad5ef 59 */
Christopher Haster 1:24750b9ad5ef 60
Christopher Haster 1:24750b9ad5ef 61 #define SWAP(X,Y) { int *T = X; X = Y; Y = T; }
Christopher Haster 1:24750b9ad5ef 62
Christopher Haster 1:24750b9ad5ef 63 #define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
Christopher Haster 1:24750b9ad5ef 64 #define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
Christopher Haster 1:24750b9ad5ef 65
Christopher Haster 1:24750b9ad5ef 66 #define TST1_LEAVE U1++; }
Christopher Haster 1:24750b9ad5ef 67 #define TST2_LEAVE U2++; }
Christopher Haster 1:24750b9ad5ef 68
Christopher Haster 1:24750b9ad5ef 69 #define ONE_ITERATION \
Christopher Haster 1:24750b9ad5ef 70 \
Christopher Haster 1:24750b9ad5ef 71 PTEST = PT1 >> 20; \
Christopher Haster 1:24750b9ad5ef 72 \
Christopher Haster 1:24750b9ad5ef 73 TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
Christopher Haster 1:24750b9ad5ef 74 TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
Christopher Haster 1:24750b9ad5ef 75 TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
Christopher Haster 1:24750b9ad5ef 76 \
Christopher Haster 1:24750b9ad5ef 77 TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
Christopher Haster 1:24750b9ad5ef 78 TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
Christopher Haster 1:24750b9ad5ef 79 TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
Christopher Haster 1:24750b9ad5ef 80 \
Christopher Haster 1:24750b9ad5ef 81 PTX = (PT1 >> 18) & 7; \
Christopher Haster 1:24750b9ad5ef 82 PT1 &= 0x1FFF; \
Christopher Haster 1:24750b9ad5ef 83 PT2 &= 0x1FFF; \
Christopher Haster 1:24750b9ad5ef 84 CLK = (int) mbedtls_timing_hardclock(); \
Christopher Haster 1:24750b9ad5ef 85 \
Christopher Haster 1:24750b9ad5ef 86 i = 0; \
Christopher Haster 1:24750b9ad5ef 87 A = &WALK[PT1 ]; RES[i++] ^= *A; \
Christopher Haster 1:24750b9ad5ef 88 B = &WALK[PT2 ]; RES[i++] ^= *B; \
Christopher Haster 1:24750b9ad5ef 89 C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \
Christopher Haster 1:24750b9ad5ef 90 D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \
Christopher Haster 1:24750b9ad5ef 91 \
Christopher Haster 1:24750b9ad5ef 92 IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 93 *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 94 *B = IN ^ U1; \
Christopher Haster 1:24750b9ad5ef 95 *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 96 *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 97 \
Christopher Haster 1:24750b9ad5ef 98 A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \
Christopher Haster 1:24750b9ad5ef 99 B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \
Christopher Haster 1:24750b9ad5ef 100 C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \
Christopher Haster 1:24750b9ad5ef 101 D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \
Christopher Haster 1:24750b9ad5ef 102 \
Christopher Haster 1:24750b9ad5ef 103 if( PTEST & 1 ) SWAP( A, C ); \
Christopher Haster 1:24750b9ad5ef 104 \
Christopher Haster 1:24750b9ad5ef 105 IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 106 *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 107 *B = IN; CLK = (int) mbedtls_timing_hardclock(); \
Christopher Haster 1:24750b9ad5ef 108 *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 109 *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 110 \
Christopher Haster 1:24750b9ad5ef 111 A = &WALK[PT1 ^ 4]; \
Christopher Haster 1:24750b9ad5ef 112 B = &WALK[PT2 ^ 1]; \
Christopher Haster 1:24750b9ad5ef 113 \
Christopher Haster 1:24750b9ad5ef 114 PTEST = PT2 >> 1; \
Christopher Haster 1:24750b9ad5ef 115 \
Christopher Haster 1:24750b9ad5ef 116 PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \
Christopher Haster 1:24750b9ad5ef 117 PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \
Christopher Haster 1:24750b9ad5ef 118 PTY = (PT2 >> 10) & 7; \
Christopher Haster 1:24750b9ad5ef 119 \
Christopher Haster 1:24750b9ad5ef 120 TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
Christopher Haster 1:24750b9ad5ef 121 TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
Christopher Haster 1:24750b9ad5ef 122 TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
Christopher Haster 1:24750b9ad5ef 123 \
Christopher Haster 1:24750b9ad5ef 124 TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
Christopher Haster 1:24750b9ad5ef 125 TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
Christopher Haster 1:24750b9ad5ef 126 TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
Christopher Haster 1:24750b9ad5ef 127 \
Christopher Haster 1:24750b9ad5ef 128 C = &WALK[PT1 ^ 5]; \
Christopher Haster 1:24750b9ad5ef 129 D = &WALK[PT2 ^ 5]; \
Christopher Haster 1:24750b9ad5ef 130 \
Christopher Haster 1:24750b9ad5ef 131 RES[i++] ^= *A; \
Christopher Haster 1:24750b9ad5ef 132 RES[i++] ^= *B; \
Christopher Haster 1:24750b9ad5ef 133 RES[i++] ^= *C; \
Christopher Haster 1:24750b9ad5ef 134 RES[i++] ^= *D; \
Christopher Haster 1:24750b9ad5ef 135 \
Christopher Haster 1:24750b9ad5ef 136 IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 137 *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 138 *B = IN ^ U2; \
Christopher Haster 1:24750b9ad5ef 139 *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 140 *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 141 \
Christopher Haster 1:24750b9ad5ef 142 A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \
Christopher Haster 1:24750b9ad5ef 143 B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \
Christopher Haster 1:24750b9ad5ef 144 C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \
Christopher Haster 1:24750b9ad5ef 145 D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \
Christopher Haster 1:24750b9ad5ef 146 \
Christopher Haster 1:24750b9ad5ef 147 IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 148 *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 149 *B = IN; \
Christopher Haster 1:24750b9ad5ef 150 *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 151 *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \
Christopher Haster 1:24750b9ad5ef 152 \
Christopher Haster 1:24750b9ad5ef 153 PT1 = ( RES[( i - 8 ) ^ PTX] ^ \
Christopher Haster 1:24750b9ad5ef 154 WALK[PT1 ^ PTX ^ 7] ) & (~1); \
Christopher Haster 1:24750b9ad5ef 155 PT1 ^= (PT2 ^ 0x10) & 0x10; \
Christopher Haster 1:24750b9ad5ef 156 \
Christopher Haster 1:24750b9ad5ef 157 for( n++, i = 0; i < 16; i++ ) \
Christopher Haster 1:24750b9ad5ef 158 hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
Christopher Haster 1:24750b9ad5ef 159
Christopher Haster 1:24750b9ad5ef 160 /*
Christopher Haster 1:24750b9ad5ef 161 * Entropy gathering function
Christopher Haster 1:24750b9ad5ef 162 */
Christopher Haster 1:24750b9ad5ef 163 static void havege_fill( mbedtls_havege_state *hs )
Christopher Haster 1:24750b9ad5ef 164 {
Christopher Haster 1:24750b9ad5ef 165 int i, n = 0;
Christopher Haster 1:24750b9ad5ef 166 int U1, U2, *A, *B, *C, *D;
Christopher Haster 1:24750b9ad5ef 167 int PT1, PT2, *WALK, RES[16];
Christopher Haster 1:24750b9ad5ef 168 int PTX, PTY, CLK, PTEST, IN;
Christopher Haster 1:24750b9ad5ef 169
Christopher Haster 1:24750b9ad5ef 170 WALK = hs->WALK;
Christopher Haster 1:24750b9ad5ef 171 PT1 = hs->PT1;
Christopher Haster 1:24750b9ad5ef 172 PT2 = hs->PT2;
Christopher Haster 1:24750b9ad5ef 173
Christopher Haster 1:24750b9ad5ef 174 PTX = U1 = 0;
Christopher Haster 1:24750b9ad5ef 175 PTY = U2 = 0;
Christopher Haster 1:24750b9ad5ef 176
Christopher Haster 1:24750b9ad5ef 177 memset( RES, 0, sizeof( RES ) );
Christopher Haster 1:24750b9ad5ef 178
Christopher Haster 1:24750b9ad5ef 179 while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 )
Christopher Haster 1:24750b9ad5ef 180 {
Christopher Haster 1:24750b9ad5ef 181 ONE_ITERATION
Christopher Haster 1:24750b9ad5ef 182 ONE_ITERATION
Christopher Haster 1:24750b9ad5ef 183 ONE_ITERATION
Christopher Haster 1:24750b9ad5ef 184 ONE_ITERATION
Christopher Haster 1:24750b9ad5ef 185 }
Christopher Haster 1:24750b9ad5ef 186
Christopher Haster 1:24750b9ad5ef 187 hs->PT1 = PT1;
Christopher Haster 1:24750b9ad5ef 188 hs->PT2 = PT2;
Christopher Haster 1:24750b9ad5ef 189
Christopher Haster 1:24750b9ad5ef 190 hs->offset[0] = 0;
Christopher Haster 1:24750b9ad5ef 191 hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2;
Christopher Haster 1:24750b9ad5ef 192 }
Christopher Haster 1:24750b9ad5ef 193
Christopher Haster 1:24750b9ad5ef 194 /*
Christopher Haster 1:24750b9ad5ef 195 * HAVEGE initialization
Christopher Haster 1:24750b9ad5ef 196 */
Christopher Haster 1:24750b9ad5ef 197 void mbedtls_havege_init( mbedtls_havege_state *hs )
Christopher Haster 1:24750b9ad5ef 198 {
Christopher Haster 1:24750b9ad5ef 199 memset( hs, 0, sizeof( mbedtls_havege_state ) );
Christopher Haster 1:24750b9ad5ef 200
Christopher Haster 1:24750b9ad5ef 201 havege_fill( hs );
Christopher Haster 1:24750b9ad5ef 202 }
Christopher Haster 1:24750b9ad5ef 203
Christopher Haster 1:24750b9ad5ef 204 void mbedtls_havege_free( mbedtls_havege_state *hs )
Christopher Haster 1:24750b9ad5ef 205 {
Christopher Haster 1:24750b9ad5ef 206 if( hs == NULL )
Christopher Haster 1:24750b9ad5ef 207 return;
Christopher Haster 1:24750b9ad5ef 208
Christopher Haster 1:24750b9ad5ef 209 mbedtls_zeroize( hs, sizeof( mbedtls_havege_state ) );
Christopher Haster 1:24750b9ad5ef 210 }
Christopher Haster 1:24750b9ad5ef 211
Christopher Haster 1:24750b9ad5ef 212 /*
Christopher Haster 1:24750b9ad5ef 213 * HAVEGE rand function
Christopher Haster 1:24750b9ad5ef 214 */
Christopher Haster 1:24750b9ad5ef 215 int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
Christopher Haster 1:24750b9ad5ef 216 {
Christopher Haster 1:24750b9ad5ef 217 int val;
Christopher Haster 1:24750b9ad5ef 218 size_t use_len;
Christopher Haster 1:24750b9ad5ef 219 mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng;
Christopher Haster 1:24750b9ad5ef 220 unsigned char *p = buf;
Christopher Haster 1:24750b9ad5ef 221
Christopher Haster 1:24750b9ad5ef 222 while( len > 0 )
Christopher Haster 1:24750b9ad5ef 223 {
Christopher Haster 1:24750b9ad5ef 224 use_len = len;
Christopher Haster 1:24750b9ad5ef 225 if( use_len > sizeof(int) )
Christopher Haster 1:24750b9ad5ef 226 use_len = sizeof(int);
Christopher Haster 1:24750b9ad5ef 227
Christopher Haster 1:24750b9ad5ef 228 if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
Christopher Haster 1:24750b9ad5ef 229 havege_fill( hs );
Christopher Haster 1:24750b9ad5ef 230
Christopher Haster 1:24750b9ad5ef 231 val = hs->pool[hs->offset[0]++];
Christopher Haster 1:24750b9ad5ef 232 val ^= hs->pool[hs->offset[1]++];
Christopher Haster 1:24750b9ad5ef 233
Christopher Haster 1:24750b9ad5ef 234 memcpy( p, &val, use_len );
Christopher Haster 1:24750b9ad5ef 235
Christopher Haster 1:24750b9ad5ef 236 len -= use_len;
Christopher Haster 1:24750b9ad5ef 237 p += use_len;
Christopher Haster 1:24750b9ad5ef 238 }
Christopher Haster 1:24750b9ad5ef 239
Christopher Haster 1:24750b9ad5ef 240 return( 0 );
Christopher Haster 1:24750b9ad5ef 241 }
Christopher Haster 1:24750b9ad5ef 242
Christopher Haster 1:24750b9ad5ef 243 #endif /* MBEDTLS_HAVEGE_C */