Includes library modifications to allow access to AIN_4 (AIN_0 / 5)

Committer:
bryantaylor
Date:
Tue Sep 20 21:26:12 2016 +0000
Revision:
0:eafc3fd41f75
hackathon

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bryantaylor 0:eafc3fd41f75 1 /*
bryantaylor 0:eafc3fd41f75 2 * DTLS cookie callbacks implementation
bryantaylor 0:eafc3fd41f75 3 *
bryantaylor 0:eafc3fd41f75 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
bryantaylor 0:eafc3fd41f75 5 * SPDX-License-Identifier: Apache-2.0
bryantaylor 0:eafc3fd41f75 6 *
bryantaylor 0:eafc3fd41f75 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
bryantaylor 0:eafc3fd41f75 8 * not use this file except in compliance with the License.
bryantaylor 0:eafc3fd41f75 9 * You may obtain a copy of the License at
bryantaylor 0:eafc3fd41f75 10 *
bryantaylor 0:eafc3fd41f75 11 * http://www.apache.org/licenses/LICENSE-2.0
bryantaylor 0:eafc3fd41f75 12 *
bryantaylor 0:eafc3fd41f75 13 * Unless required by applicable law or agreed to in writing, software
bryantaylor 0:eafc3fd41f75 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
bryantaylor 0:eafc3fd41f75 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bryantaylor 0:eafc3fd41f75 16 * See the License for the specific language governing permissions and
bryantaylor 0:eafc3fd41f75 17 * limitations under the License.
bryantaylor 0:eafc3fd41f75 18 *
bryantaylor 0:eafc3fd41f75 19 * This file is part of mbed TLS (https://tls.mbed.org)
bryantaylor 0:eafc3fd41f75 20 */
bryantaylor 0:eafc3fd41f75 21 /*
bryantaylor 0:eafc3fd41f75 22 * These session callbacks use a simple chained list
bryantaylor 0:eafc3fd41f75 23 * to store and retrieve the session information.
bryantaylor 0:eafc3fd41f75 24 */
bryantaylor 0:eafc3fd41f75 25
bryantaylor 0:eafc3fd41f75 26 #if !defined(MBEDTLS_CONFIG_FILE)
bryantaylor 0:eafc3fd41f75 27 #include "mbedtls/config.h"
bryantaylor 0:eafc3fd41f75 28 #else
bryantaylor 0:eafc3fd41f75 29 #include MBEDTLS_CONFIG_FILE
bryantaylor 0:eafc3fd41f75 30 #endif
bryantaylor 0:eafc3fd41f75 31
bryantaylor 0:eafc3fd41f75 32 #if defined(MBEDTLS_SSL_COOKIE_C)
bryantaylor 0:eafc3fd41f75 33
bryantaylor 0:eafc3fd41f75 34 #if defined(MBEDTLS_PLATFORM_C)
bryantaylor 0:eafc3fd41f75 35 #include "mbedtls/platform.h"
bryantaylor 0:eafc3fd41f75 36 #else
bryantaylor 0:eafc3fd41f75 37 #define mbedtls_calloc calloc
bryantaylor 0:eafc3fd41f75 38 #define mbedtls_free free
bryantaylor 0:eafc3fd41f75 39 #define mbedtls_time time
bryantaylor 0:eafc3fd41f75 40 #define mbedtls_time_t time_t
bryantaylor 0:eafc3fd41f75 41 #endif
bryantaylor 0:eafc3fd41f75 42
bryantaylor 0:eafc3fd41f75 43 #include "mbedtls/ssl_cookie.h"
bryantaylor 0:eafc3fd41f75 44 #include "mbedtls/ssl_internal.h"
bryantaylor 0:eafc3fd41f75 45
bryantaylor 0:eafc3fd41f75 46 #include <string.h>
bryantaylor 0:eafc3fd41f75 47
bryantaylor 0:eafc3fd41f75 48 /* Implementation that should never be optimized out by the compiler */
bryantaylor 0:eafc3fd41f75 49 static void mbedtls_zeroize( void *v, size_t n ) {
bryantaylor 0:eafc3fd41f75 50 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
bryantaylor 0:eafc3fd41f75 51 }
bryantaylor 0:eafc3fd41f75 52
bryantaylor 0:eafc3fd41f75 53 /*
bryantaylor 0:eafc3fd41f75 54 * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
bryantaylor 0:eafc3fd41f75 55 * available. Try SHA-256 first, 512 wastes resources since we need to stay
bryantaylor 0:eafc3fd41f75 56 * with max 32 bytes of cookie for DTLS 1.0
bryantaylor 0:eafc3fd41f75 57 */
bryantaylor 0:eafc3fd41f75 58 #if defined(MBEDTLS_SHA256_C)
bryantaylor 0:eafc3fd41f75 59 #define COOKIE_MD MBEDTLS_MD_SHA224
bryantaylor 0:eafc3fd41f75 60 #define COOKIE_MD_OUTLEN 32
bryantaylor 0:eafc3fd41f75 61 #define COOKIE_HMAC_LEN 28
bryantaylor 0:eafc3fd41f75 62 #elif defined(MBEDTLS_SHA512_C)
bryantaylor 0:eafc3fd41f75 63 #define COOKIE_MD MBEDTLS_MD_SHA384
bryantaylor 0:eafc3fd41f75 64 #define COOKIE_MD_OUTLEN 48
bryantaylor 0:eafc3fd41f75 65 #define COOKIE_HMAC_LEN 28
bryantaylor 0:eafc3fd41f75 66 #elif defined(MBEDTLS_SHA1_C)
bryantaylor 0:eafc3fd41f75 67 #define COOKIE_MD MBEDTLS_MD_SHA1
bryantaylor 0:eafc3fd41f75 68 #define COOKIE_MD_OUTLEN 20
bryantaylor 0:eafc3fd41f75 69 #define COOKIE_HMAC_LEN 20
bryantaylor 0:eafc3fd41f75 70 #else
bryantaylor 0:eafc3fd41f75 71 #error "DTLS hello verify needs SHA-1 or SHA-2"
bryantaylor 0:eafc3fd41f75 72 #endif
bryantaylor 0:eafc3fd41f75 73
bryantaylor 0:eafc3fd41f75 74 /*
bryantaylor 0:eafc3fd41f75 75 * Cookies are formed of a 4-bytes timestamp (or serial number) and
bryantaylor 0:eafc3fd41f75 76 * an HMAC of timestemp and client ID.
bryantaylor 0:eafc3fd41f75 77 */
bryantaylor 0:eafc3fd41f75 78 #define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN )
bryantaylor 0:eafc3fd41f75 79
bryantaylor 0:eafc3fd41f75 80 void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx )
bryantaylor 0:eafc3fd41f75 81 {
bryantaylor 0:eafc3fd41f75 82 mbedtls_md_init( &ctx->hmac_ctx );
bryantaylor 0:eafc3fd41f75 83 #if !defined(MBEDTLS_HAVE_TIME)
bryantaylor 0:eafc3fd41f75 84 ctx->serial = 0;
bryantaylor 0:eafc3fd41f75 85 #endif
bryantaylor 0:eafc3fd41f75 86 ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT;
bryantaylor 0:eafc3fd41f75 87
bryantaylor 0:eafc3fd41f75 88 #if defined(MBEDTLS_THREADING_C)
bryantaylor 0:eafc3fd41f75 89 mbedtls_mutex_init( &ctx->mutex );
bryantaylor 0:eafc3fd41f75 90 #endif
bryantaylor 0:eafc3fd41f75 91 }
bryantaylor 0:eafc3fd41f75 92
bryantaylor 0:eafc3fd41f75 93 void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay )
bryantaylor 0:eafc3fd41f75 94 {
bryantaylor 0:eafc3fd41f75 95 ctx->timeout = delay;
bryantaylor 0:eafc3fd41f75 96 }
bryantaylor 0:eafc3fd41f75 97
bryantaylor 0:eafc3fd41f75 98 void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx )
bryantaylor 0:eafc3fd41f75 99 {
bryantaylor 0:eafc3fd41f75 100 mbedtls_md_free( &ctx->hmac_ctx );
bryantaylor 0:eafc3fd41f75 101
bryantaylor 0:eafc3fd41f75 102 #if defined(MBEDTLS_THREADING_C)
bryantaylor 0:eafc3fd41f75 103 mbedtls_mutex_init( &ctx->mutex );
bryantaylor 0:eafc3fd41f75 104 #endif
bryantaylor 0:eafc3fd41f75 105
bryantaylor 0:eafc3fd41f75 106 mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) );
bryantaylor 0:eafc3fd41f75 107 }
bryantaylor 0:eafc3fd41f75 108
bryantaylor 0:eafc3fd41f75 109 int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
bryantaylor 0:eafc3fd41f75 110 int (*f_rng)(void *, unsigned char *, size_t),
bryantaylor 0:eafc3fd41f75 111 void *p_rng )
bryantaylor 0:eafc3fd41f75 112 {
bryantaylor 0:eafc3fd41f75 113 int ret;
bryantaylor 0:eafc3fd41f75 114 unsigned char key[COOKIE_MD_OUTLEN];
bryantaylor 0:eafc3fd41f75 115
bryantaylor 0:eafc3fd41f75 116 if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 )
bryantaylor 0:eafc3fd41f75 117 return( ret );
bryantaylor 0:eafc3fd41f75 118
bryantaylor 0:eafc3fd41f75 119 ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 );
bryantaylor 0:eafc3fd41f75 120 if( ret != 0 )
bryantaylor 0:eafc3fd41f75 121 return( ret );
bryantaylor 0:eafc3fd41f75 122
bryantaylor 0:eafc3fd41f75 123 ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) );
bryantaylor 0:eafc3fd41f75 124 if( ret != 0 )
bryantaylor 0:eafc3fd41f75 125 return( ret );
bryantaylor 0:eafc3fd41f75 126
bryantaylor 0:eafc3fd41f75 127 mbedtls_zeroize( key, sizeof( key ) );
bryantaylor 0:eafc3fd41f75 128
bryantaylor 0:eafc3fd41f75 129 return( 0 );
bryantaylor 0:eafc3fd41f75 130 }
bryantaylor 0:eafc3fd41f75 131
bryantaylor 0:eafc3fd41f75 132 /*
bryantaylor 0:eafc3fd41f75 133 * Generate the HMAC part of a cookie
bryantaylor 0:eafc3fd41f75 134 */
bryantaylor 0:eafc3fd41f75 135 static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx,
bryantaylor 0:eafc3fd41f75 136 const unsigned char time[4],
bryantaylor 0:eafc3fd41f75 137 unsigned char **p, unsigned char *end,
bryantaylor 0:eafc3fd41f75 138 const unsigned char *cli_id, size_t cli_id_len )
bryantaylor 0:eafc3fd41f75 139 {
bryantaylor 0:eafc3fd41f75 140 unsigned char hmac_out[COOKIE_MD_OUTLEN];
bryantaylor 0:eafc3fd41f75 141
bryantaylor 0:eafc3fd41f75 142 if( (size_t)( end - *p ) < COOKIE_HMAC_LEN )
bryantaylor 0:eafc3fd41f75 143 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
bryantaylor 0:eafc3fd41f75 144
bryantaylor 0:eafc3fd41f75 145 if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 ||
bryantaylor 0:eafc3fd41f75 146 mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 ||
bryantaylor 0:eafc3fd41f75 147 mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 ||
bryantaylor 0:eafc3fd41f75 148 mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 )
bryantaylor 0:eafc3fd41f75 149 {
bryantaylor 0:eafc3fd41f75 150 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
bryantaylor 0:eafc3fd41f75 151 }
bryantaylor 0:eafc3fd41f75 152
bryantaylor 0:eafc3fd41f75 153 memcpy( *p, hmac_out, COOKIE_HMAC_LEN );
bryantaylor 0:eafc3fd41f75 154 *p += COOKIE_HMAC_LEN;
bryantaylor 0:eafc3fd41f75 155
bryantaylor 0:eafc3fd41f75 156 return( 0 );
bryantaylor 0:eafc3fd41f75 157 }
bryantaylor 0:eafc3fd41f75 158
bryantaylor 0:eafc3fd41f75 159 /*
bryantaylor 0:eafc3fd41f75 160 * Generate cookie for DTLS ClientHello verification
bryantaylor 0:eafc3fd41f75 161 */
bryantaylor 0:eafc3fd41f75 162 int mbedtls_ssl_cookie_write( void *p_ctx,
bryantaylor 0:eafc3fd41f75 163 unsigned char **p, unsigned char *end,
bryantaylor 0:eafc3fd41f75 164 const unsigned char *cli_id, size_t cli_id_len )
bryantaylor 0:eafc3fd41f75 165 {
bryantaylor 0:eafc3fd41f75 166 int ret;
bryantaylor 0:eafc3fd41f75 167 mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
bryantaylor 0:eafc3fd41f75 168 unsigned long t;
bryantaylor 0:eafc3fd41f75 169
bryantaylor 0:eafc3fd41f75 170 if( ctx == NULL || cli_id == NULL )
bryantaylor 0:eafc3fd41f75 171 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
bryantaylor 0:eafc3fd41f75 172
bryantaylor 0:eafc3fd41f75 173 if( (size_t)( end - *p ) < COOKIE_LEN )
bryantaylor 0:eafc3fd41f75 174 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
bryantaylor 0:eafc3fd41f75 175
bryantaylor 0:eafc3fd41f75 176 #if defined(MBEDTLS_HAVE_TIME)
bryantaylor 0:eafc3fd41f75 177 t = (unsigned long) mbedtls_time( NULL );
bryantaylor 0:eafc3fd41f75 178 #else
bryantaylor 0:eafc3fd41f75 179 t = ctx->serial++;
bryantaylor 0:eafc3fd41f75 180 #endif
bryantaylor 0:eafc3fd41f75 181
bryantaylor 0:eafc3fd41f75 182 (*p)[0] = (unsigned char)( t >> 24 );
bryantaylor 0:eafc3fd41f75 183 (*p)[1] = (unsigned char)( t >> 16 );
bryantaylor 0:eafc3fd41f75 184 (*p)[2] = (unsigned char)( t >> 8 );
bryantaylor 0:eafc3fd41f75 185 (*p)[3] = (unsigned char)( t );
bryantaylor 0:eafc3fd41f75 186 *p += 4;
bryantaylor 0:eafc3fd41f75 187
bryantaylor 0:eafc3fd41f75 188 #if defined(MBEDTLS_THREADING_C)
bryantaylor 0:eafc3fd41f75 189 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
bryantaylor 0:eafc3fd41f75 190 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
bryantaylor 0:eafc3fd41f75 191 #endif
bryantaylor 0:eafc3fd41f75 192
bryantaylor 0:eafc3fd41f75 193 ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4,
bryantaylor 0:eafc3fd41f75 194 p, end, cli_id, cli_id_len );
bryantaylor 0:eafc3fd41f75 195
bryantaylor 0:eafc3fd41f75 196 #if defined(MBEDTLS_THREADING_C)
bryantaylor 0:eafc3fd41f75 197 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
bryantaylor 0:eafc3fd41f75 198 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
bryantaylor 0:eafc3fd41f75 199 MBEDTLS_ERR_THREADING_MUTEX_ERROR );
bryantaylor 0:eafc3fd41f75 200 #endif
bryantaylor 0:eafc3fd41f75 201
bryantaylor 0:eafc3fd41f75 202 return( ret );
bryantaylor 0:eafc3fd41f75 203 }
bryantaylor 0:eafc3fd41f75 204
bryantaylor 0:eafc3fd41f75 205 /*
bryantaylor 0:eafc3fd41f75 206 * Check a cookie
bryantaylor 0:eafc3fd41f75 207 */
bryantaylor 0:eafc3fd41f75 208 int mbedtls_ssl_cookie_check( void *p_ctx,
bryantaylor 0:eafc3fd41f75 209 const unsigned char *cookie, size_t cookie_len,
bryantaylor 0:eafc3fd41f75 210 const unsigned char *cli_id, size_t cli_id_len )
bryantaylor 0:eafc3fd41f75 211 {
bryantaylor 0:eafc3fd41f75 212 unsigned char ref_hmac[COOKIE_HMAC_LEN];
bryantaylor 0:eafc3fd41f75 213 int ret = 0;
bryantaylor 0:eafc3fd41f75 214 unsigned char *p = ref_hmac;
bryantaylor 0:eafc3fd41f75 215 mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
bryantaylor 0:eafc3fd41f75 216 unsigned long cur_time, cookie_time;
bryantaylor 0:eafc3fd41f75 217
bryantaylor 0:eafc3fd41f75 218 if( ctx == NULL || cli_id == NULL )
bryantaylor 0:eafc3fd41f75 219 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
bryantaylor 0:eafc3fd41f75 220
bryantaylor 0:eafc3fd41f75 221 if( cookie_len != COOKIE_LEN )
bryantaylor 0:eafc3fd41f75 222 return( -1 );
bryantaylor 0:eafc3fd41f75 223
bryantaylor 0:eafc3fd41f75 224 #if defined(MBEDTLS_THREADING_C)
bryantaylor 0:eafc3fd41f75 225 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
bryantaylor 0:eafc3fd41f75 226 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
bryantaylor 0:eafc3fd41f75 227 #endif
bryantaylor 0:eafc3fd41f75 228
bryantaylor 0:eafc3fd41f75 229 if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie,
bryantaylor 0:eafc3fd41f75 230 &p, p + sizeof( ref_hmac ),
bryantaylor 0:eafc3fd41f75 231 cli_id, cli_id_len ) != 0 )
bryantaylor 0:eafc3fd41f75 232 ret = -1;
bryantaylor 0:eafc3fd41f75 233
bryantaylor 0:eafc3fd41f75 234 #if defined(MBEDTLS_THREADING_C)
bryantaylor 0:eafc3fd41f75 235 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
bryantaylor 0:eafc3fd41f75 236 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
bryantaylor 0:eafc3fd41f75 237 MBEDTLS_ERR_THREADING_MUTEX_ERROR );
bryantaylor 0:eafc3fd41f75 238 #endif
bryantaylor 0:eafc3fd41f75 239
bryantaylor 0:eafc3fd41f75 240 if( ret != 0 )
bryantaylor 0:eafc3fd41f75 241 return( ret );
bryantaylor 0:eafc3fd41f75 242
bryantaylor 0:eafc3fd41f75 243 if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
bryantaylor 0:eafc3fd41f75 244 return( -1 );
bryantaylor 0:eafc3fd41f75 245
bryantaylor 0:eafc3fd41f75 246 #if defined(MBEDTLS_HAVE_TIME)
bryantaylor 0:eafc3fd41f75 247 cur_time = (unsigned long) mbedtls_time( NULL );
bryantaylor 0:eafc3fd41f75 248 #else
bryantaylor 0:eafc3fd41f75 249 cur_time = ctx->serial;
bryantaylor 0:eafc3fd41f75 250 #endif
bryantaylor 0:eafc3fd41f75 251
bryantaylor 0:eafc3fd41f75 252 cookie_time = ( (unsigned long) cookie[0] << 24 ) |
bryantaylor 0:eafc3fd41f75 253 ( (unsigned long) cookie[1] << 16 ) |
bryantaylor 0:eafc3fd41f75 254 ( (unsigned long) cookie[2] << 8 ) |
bryantaylor 0:eafc3fd41f75 255 ( (unsigned long) cookie[3] );
bryantaylor 0:eafc3fd41f75 256
bryantaylor 0:eafc3fd41f75 257 if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout )
bryantaylor 0:eafc3fd41f75 258 return( -1 );
bryantaylor 0:eafc3fd41f75 259
bryantaylor 0:eafc3fd41f75 260 return( 0 );
bryantaylor 0:eafc3fd41f75 261 }
bryantaylor 0:eafc3fd41f75 262 #endif /* MBEDTLS_SSL_COOKIE_C */