Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl_cookie.c Source File

ssl_cookie.c

00001 /*
00002  *  DTLS cookie callbacks implementation
00003  *
00004  *  Copyright (C) 2006-2015, 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  * These session callbacks use a simple chained list
00023  * to store and retrieve the session information.
00024  */
00025 
00026 #if !defined(MBEDTLS_CONFIG_FILE)
00027 #include "mbedtls/config.h"
00028 #else
00029 #include MBEDTLS_CONFIG_FILE
00030 #endif
00031 
00032 #if defined(MBEDTLS_SSL_COOKIE_C)
00033 
00034 #if defined(MBEDTLS_PLATFORM_C)
00035 #include "mbedtls/platform.h"
00036 #else
00037 #define mbedtls_calloc    calloc
00038 #define mbedtls_free      free
00039 #endif
00040 
00041 #include "mbedtls/ssl_cookie.h"
00042 #include "mbedtls/ssl_internal.h"
00043 #include "mbedtls/platform_util.h"
00044 
00045 #include <string.h>
00046 
00047 /*
00048  * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
00049  * available. Try SHA-256 first, 512 wastes resources since we need to stay
00050  * with max 32 bytes of cookie for DTLS 1.0
00051  */
00052 #if defined(MBEDTLS_SHA256_C)
00053 #define COOKIE_MD           MBEDTLS_MD_SHA224
00054 #define COOKIE_MD_OUTLEN    32
00055 #define COOKIE_HMAC_LEN     28
00056 #elif defined(MBEDTLS_SHA512_C)
00057 #define COOKIE_MD           MBEDTLS_MD_SHA384
00058 #define COOKIE_MD_OUTLEN    48
00059 #define COOKIE_HMAC_LEN     28
00060 #elif defined(MBEDTLS_SHA1_C)
00061 #define COOKIE_MD           MBEDTLS_MD_SHA1
00062 #define COOKIE_MD_OUTLEN    20
00063 #define COOKIE_HMAC_LEN     20
00064 #else
00065 #error "DTLS hello verify needs SHA-1 or SHA-2"
00066 #endif
00067 
00068 /*
00069  * Cookies are formed of a 4-bytes timestamp (or serial number) and
00070  * an HMAC of timestemp and client ID.
00071  */
00072 #define COOKIE_LEN      ( 4 + COOKIE_HMAC_LEN )
00073 
00074 void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx )
00075 {
00076     mbedtls_md_init( &ctx->hmac_ctx  );
00077 #if !defined(MBEDTLS_HAVE_TIME)
00078     ctx->serial  = 0;
00079 #endif
00080     ctx->timeout  = MBEDTLS_SSL_COOKIE_TIMEOUT;
00081 
00082 #if defined(MBEDTLS_THREADING_C)
00083     mbedtls_mutex_init( &ctx->mutex );
00084 #endif
00085 }
00086 
00087 void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay )
00088 {
00089     ctx->timeout  = delay;
00090 }
00091 
00092 void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx )
00093 {
00094     mbedtls_md_free( &ctx->hmac_ctx  );
00095 
00096 #if defined(MBEDTLS_THREADING_C)
00097     mbedtls_mutex_free( &ctx->mutex );
00098 #endif
00099 
00100     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) );
00101 }
00102 
00103 int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
00104                       int (*f_rng)(void *, unsigned char *, size_t),
00105                       void *p_rng )
00106 {
00107     int ret;
00108     unsigned char key[COOKIE_MD_OUTLEN];
00109 
00110     if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 )
00111         return( ret );
00112 
00113     ret = mbedtls_md_setup( &ctx->hmac_ctx , mbedtls_md_info_from_type( COOKIE_MD ), 1 );
00114     if( ret != 0 )
00115         return( ret );
00116 
00117     ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx , key, sizeof( key ) );
00118     if( ret != 0 )
00119         return( ret );
00120 
00121     mbedtls_platform_zeroize( key, sizeof( key ) );
00122 
00123     return( 0 );
00124 }
00125 
00126 /*
00127  * Generate the HMAC part of a cookie
00128  */
00129 static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx,
00130                             const unsigned char time[4],
00131                             unsigned char **p, unsigned char *end,
00132                             const unsigned char *cli_id, size_t cli_id_len )
00133 {
00134     unsigned char hmac_out[COOKIE_MD_OUTLEN];
00135 
00136     if( (size_t)( end - *p ) < COOKIE_HMAC_LEN )
00137         return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
00138 
00139     if( mbedtls_md_hmac_reset(  hmac_ctx ) != 0 ||
00140         mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 ||
00141         mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 ||
00142         mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 )
00143     {
00144         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
00145     }
00146 
00147     memcpy( *p, hmac_out, COOKIE_HMAC_LEN );
00148     *p += COOKIE_HMAC_LEN;
00149 
00150     return( 0 );
00151 }
00152 
00153 /*
00154  * Generate cookie for DTLS ClientHello verification
00155  */
00156 int mbedtls_ssl_cookie_write( void *p_ctx,
00157                       unsigned char **p, unsigned char *end,
00158                       const unsigned char *cli_id, size_t cli_id_len )
00159 {
00160     int ret;
00161     mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
00162     unsigned long t;
00163 
00164     if( ctx == NULL || cli_id == NULL )
00165         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
00166 
00167     if( (size_t)( end - *p ) < COOKIE_LEN )
00168         return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
00169 
00170 #if defined(MBEDTLS_HAVE_TIME)
00171     t = (unsigned long) mbedtls_time( NULL );
00172 #else
00173     t = ctx->serial ++;
00174 #endif
00175 
00176     (*p)[0] = (unsigned char)( t >> 24 );
00177     (*p)[1] = (unsigned char)( t >> 16 );
00178     (*p)[2] = (unsigned char)( t >>  8 );
00179     (*p)[3] = (unsigned char)( t       );
00180     *p += 4;
00181 
00182 #if defined(MBEDTLS_THREADING_C)
00183     if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
00184         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
00185 #endif
00186 
00187     ret = ssl_cookie_hmac( &ctx->hmac_ctx , *p - 4,
00188                            p, end, cli_id, cli_id_len );
00189 
00190 #if defined(MBEDTLS_THREADING_C)
00191     if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
00192         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
00193                 MBEDTLS_ERR_THREADING_MUTEX_ERROR );
00194 #endif
00195 
00196     return( ret );
00197 }
00198 
00199 /*
00200  * Check a cookie
00201  */
00202 int mbedtls_ssl_cookie_check( void *p_ctx,
00203                       const unsigned char *cookie, size_t cookie_len,
00204                       const unsigned char *cli_id, size_t cli_id_len )
00205 {
00206     unsigned char ref_hmac[COOKIE_HMAC_LEN];
00207     int ret = 0;
00208     unsigned char *p = ref_hmac;
00209     mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
00210     unsigned long cur_time, cookie_time;
00211 
00212     if( ctx == NULL || cli_id == NULL )
00213         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
00214 
00215     if( cookie_len != COOKIE_LEN )
00216         return( -1 );
00217 
00218 #if defined(MBEDTLS_THREADING_C)
00219     if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
00220         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
00221 #endif
00222 
00223     if( ssl_cookie_hmac( &ctx->hmac_ctx , cookie,
00224                          &p, p + sizeof( ref_hmac ),
00225                          cli_id, cli_id_len ) != 0 )
00226         ret = -1;
00227 
00228 #if defined(MBEDTLS_THREADING_C)
00229     if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
00230         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
00231                 MBEDTLS_ERR_THREADING_MUTEX_ERROR );
00232 #endif
00233 
00234     if( ret != 0 )
00235         return( ret );
00236 
00237     if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
00238         return( -1 );
00239 
00240 #if defined(MBEDTLS_HAVE_TIME)
00241     cur_time = (unsigned long) mbedtls_time( NULL );
00242 #else
00243     cur_time = ctx->serial ;
00244 #endif
00245 
00246     cookie_time = ( (unsigned long) cookie[0] << 24 ) |
00247                   ( (unsigned long) cookie[1] << 16 ) |
00248                   ( (unsigned long) cookie[2] <<  8 ) |
00249                   ( (unsigned long) cookie[3]       );
00250 
00251     if( ctx->timeout  != 0 && cur_time - cookie_time > ctx->timeout  )
00252         return( -1 );
00253 
00254     return( 0 );
00255 }
00256 #endif /* MBEDTLS_SSL_COOKIE_C */