Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedtls by
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 00044 #include <string.h> 00045 00046 /* Implementation that should never be optimized out by the compiler */ 00047 static void mbedtls_zeroize( void *v, size_t n ) { 00048 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00049 } 00050 00051 /* 00052 * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is 00053 * available. Try SHA-256 first, 512 wastes resources since we need to stay 00054 * with max 32 bytes of cookie for DTLS 1.0 00055 */ 00056 #if defined(MBEDTLS_SHA256_C) 00057 #define COOKIE_MD MBEDTLS_MD_SHA224 00058 #define COOKIE_MD_OUTLEN 32 00059 #define COOKIE_HMAC_LEN 28 00060 #elif defined(MBEDTLS_SHA512_C) 00061 #define COOKIE_MD MBEDTLS_MD_SHA384 00062 #define COOKIE_MD_OUTLEN 48 00063 #define COOKIE_HMAC_LEN 28 00064 #elif defined(MBEDTLS_SHA1_C) 00065 #define COOKIE_MD MBEDTLS_MD_SHA1 00066 #define COOKIE_MD_OUTLEN 20 00067 #define COOKIE_HMAC_LEN 20 00068 #else 00069 #error "DTLS hello verify needs SHA-1 or SHA-2" 00070 #endif 00071 00072 /* 00073 * Cookies are formed of a 4-bytes timestamp (or serial number) and 00074 * an HMAC of timestemp and client ID. 00075 */ 00076 #define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN ) 00077 00078 void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ) 00079 { 00080 mbedtls_md_init( &ctx->hmac_ctx ); 00081 #if !defined(MBEDTLS_HAVE_TIME) 00082 ctx->serial = 0; 00083 #endif 00084 ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT; 00085 00086 #if defined(MBEDTLS_THREADING_C) 00087 mbedtls_mutex_init( &ctx->mutex ); 00088 #endif 00089 } 00090 00091 void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ) 00092 { 00093 ctx->timeout = delay; 00094 } 00095 00096 void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ) 00097 { 00098 mbedtls_md_free( &ctx->hmac_ctx ); 00099 00100 #if defined(MBEDTLS_THREADING_C) 00101 mbedtls_mutex_free( &ctx->mutex ); 00102 #endif 00103 00104 mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); 00105 } 00106 00107 int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, 00108 int (*f_rng)(void *, unsigned char *, size_t), 00109 void *p_rng ) 00110 { 00111 int ret; 00112 unsigned char key[COOKIE_MD_OUTLEN]; 00113 00114 if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) 00115 return( ret ); 00116 00117 ret = mbedtls_md_setup( &ctx->hmac_ctx , mbedtls_md_info_from_type( COOKIE_MD ), 1 ); 00118 if( ret != 0 ) 00119 return( ret ); 00120 00121 ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx , key, sizeof( key ) ); 00122 if( ret != 0 ) 00123 return( ret ); 00124 00125 mbedtls_zeroize( key, sizeof( key ) ); 00126 00127 return( 0 ); 00128 } 00129 00130 /* 00131 * Generate the HMAC part of a cookie 00132 */ 00133 static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx, 00134 const unsigned char time[4], 00135 unsigned char **p, unsigned char *end, 00136 const unsigned char *cli_id, size_t cli_id_len ) 00137 { 00138 unsigned char hmac_out[COOKIE_MD_OUTLEN]; 00139 00140 if( (size_t)( end - *p ) < COOKIE_HMAC_LEN ) 00141 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 00142 00143 if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 || 00144 mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 || 00145 mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 || 00146 mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 ) 00147 { 00148 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 00149 } 00150 00151 memcpy( *p, hmac_out, COOKIE_HMAC_LEN ); 00152 *p += COOKIE_HMAC_LEN; 00153 00154 return( 0 ); 00155 } 00156 00157 /* 00158 * Generate cookie for DTLS ClientHello verification 00159 */ 00160 int mbedtls_ssl_cookie_write( void *p_ctx, 00161 unsigned char **p, unsigned char *end, 00162 const unsigned char *cli_id, size_t cli_id_len ) 00163 { 00164 int ret; 00165 mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; 00166 unsigned long t; 00167 00168 if( ctx == NULL || cli_id == NULL ) 00169 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 00170 00171 if( (size_t)( end - *p ) < COOKIE_LEN ) 00172 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 00173 00174 #if defined(MBEDTLS_HAVE_TIME) 00175 t = (unsigned long) mbedtls_time( NULL ); 00176 #else 00177 t = ctx->serial ++; 00178 #endif 00179 00180 (*p)[0] = (unsigned char)( t >> 24 ); 00181 (*p)[1] = (unsigned char)( t >> 16 ); 00182 (*p)[2] = (unsigned char)( t >> 8 ); 00183 (*p)[3] = (unsigned char)( t ); 00184 *p += 4; 00185 00186 #if defined(MBEDTLS_THREADING_C) 00187 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 00188 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); 00189 #endif 00190 00191 ret = ssl_cookie_hmac( &ctx->hmac_ctx , *p - 4, 00192 p, end, cli_id, cli_id_len ); 00193 00194 #if defined(MBEDTLS_THREADING_C) 00195 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 00196 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + 00197 MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00198 #endif 00199 00200 return( ret ); 00201 } 00202 00203 /* 00204 * Check a cookie 00205 */ 00206 int mbedtls_ssl_cookie_check( void *p_ctx, 00207 const unsigned char *cookie, size_t cookie_len, 00208 const unsigned char *cli_id, size_t cli_id_len ) 00209 { 00210 unsigned char ref_hmac[COOKIE_HMAC_LEN]; 00211 int ret = 0; 00212 unsigned char *p = ref_hmac; 00213 mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; 00214 unsigned long cur_time, cookie_time; 00215 00216 if( ctx == NULL || cli_id == NULL ) 00217 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 00218 00219 if( cookie_len != COOKIE_LEN ) 00220 return( -1 ); 00221 00222 #if defined(MBEDTLS_THREADING_C) 00223 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 00224 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); 00225 #endif 00226 00227 if( ssl_cookie_hmac( &ctx->hmac_ctx , cookie, 00228 &p, p + sizeof( ref_hmac ), 00229 cli_id, cli_id_len ) != 0 ) 00230 ret = -1; 00231 00232 #if defined(MBEDTLS_THREADING_C) 00233 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 00234 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + 00235 MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00236 #endif 00237 00238 if( ret != 0 ) 00239 return( ret ); 00240 00241 if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 ) 00242 return( -1 ); 00243 00244 #if defined(MBEDTLS_HAVE_TIME) 00245 cur_time = (unsigned long) mbedtls_time( NULL ); 00246 #else 00247 cur_time = ctx->serial ; 00248 #endif 00249 00250 cookie_time = ( (unsigned long) cookie[0] << 24 ) | 00251 ( (unsigned long) cookie[1] << 16 ) | 00252 ( (unsigned long) cookie[2] << 8 ) | 00253 ( (unsigned long) cookie[3] ); 00254 00255 if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout ) 00256 return( -1 ); 00257 00258 return( 0 ); 00259 } 00260 #endif /* MBEDTLS_SSL_COOKIE_C */
Generated on Tue Jul 12 2022 17:25:43 by
