2 * DTLS cookie callbacks implementation
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 * These session callbacks use a simple chained list
25 * to store and retrieve the session information.
28 #if !defined(MBEDTLS_CONFIG_FILE)
29 #include "mbedtls/config.h"
31 #include MBEDTLS_CONFIG_FILE
34 #if defined(MBEDTLS_SSL_COOKIE_C)
36 #if defined(MBEDTLS_PLATFORM_C)
37 #include "mbedtls/platform.h"
39 #define mbedtls_calloc calloc
40 #define mbedtls_free free
41 #define mbedtls_time time
42 #define mbedtls_time_t time_t
45 #include "mbedtls/ssl_cookie.h"
46 #include "mbedtls/ssl_internal.h"
50 /* Implementation that should never be optimized out by the compiler */
51 static void mbedtls_zeroize( void *v
, size_t n
) {
52 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
56 * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
57 * available. Try SHA-256 first, 512 wastes resources since we need to stay
58 * with max 32 bytes of cookie for DTLS 1.0
60 #if defined(MBEDTLS_SHA256_C)
61 #define COOKIE_MD MBEDTLS_MD_SHA224
62 #define COOKIE_MD_OUTLEN 32
63 #define COOKIE_HMAC_LEN 28
64 #elif defined(MBEDTLS_SHA512_C)
65 #define COOKIE_MD MBEDTLS_MD_SHA384
66 #define COOKIE_MD_OUTLEN 48
67 #define COOKIE_HMAC_LEN 28
68 #elif defined(MBEDTLS_SHA1_C)
69 #define COOKIE_MD MBEDTLS_MD_SHA1
70 #define COOKIE_MD_OUTLEN 20
71 #define COOKIE_HMAC_LEN 20
73 #error "DTLS hello verify needs SHA-1 or SHA-2"
77 * Cookies are formed of a 4-bytes timestamp (or serial number) and
78 * an HMAC of timestemp and client ID.
80 #define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN )
82 void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx
*ctx
)
84 mbedtls_md_init( &ctx
->hmac_ctx
);
85 #if !defined(MBEDTLS_HAVE_TIME)
88 ctx
->timeout
= MBEDTLS_SSL_COOKIE_TIMEOUT
;
90 #if defined(MBEDTLS_THREADING_C)
91 mbedtls_mutex_init( &ctx
->mutex
);
95 void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx
*ctx
, unsigned long delay
)
100 void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx
*ctx
)
102 mbedtls_md_free( &ctx
->hmac_ctx
);
104 #if defined(MBEDTLS_THREADING_C)
105 mbedtls_mutex_init( &ctx
->mutex
);
108 mbedtls_zeroize( ctx
, sizeof( mbedtls_ssl_cookie_ctx
) );
111 int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx
*ctx
,
112 int (*f_rng
)(void *, unsigned char *, size_t),
116 unsigned char key
[COOKIE_MD_OUTLEN
];
118 if( ( ret
= f_rng( p_rng
, key
, sizeof( key
) ) ) != 0 )
121 ret
= mbedtls_md_setup( &ctx
->hmac_ctx
, mbedtls_md_info_from_type( COOKIE_MD
), 1 );
125 ret
= mbedtls_md_hmac_starts( &ctx
->hmac_ctx
, key
, sizeof( key
) );
129 mbedtls_zeroize( key
, sizeof( key
) );
135 * Generate the HMAC part of a cookie
137 static int ssl_cookie_hmac( mbedtls_md_context_t
*hmac_ctx
,
138 const unsigned char time
[4],
139 unsigned char **p
, unsigned char *end
,
140 const unsigned char *cli_id
, size_t cli_id_len
)
142 unsigned char hmac_out
[COOKIE_MD_OUTLEN
];
144 if( (size_t)( end
- *p
) < COOKIE_HMAC_LEN
)
145 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL
);
147 if( mbedtls_md_hmac_reset( hmac_ctx
) != 0 ||
148 mbedtls_md_hmac_update( hmac_ctx
, time
, 4 ) != 0 ||
149 mbedtls_md_hmac_update( hmac_ctx
, cli_id
, cli_id_len
) != 0 ||
150 mbedtls_md_hmac_finish( hmac_ctx
, hmac_out
) != 0 )
152 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR
);
155 memcpy( *p
, hmac_out
, COOKIE_HMAC_LEN
);
156 *p
+= COOKIE_HMAC_LEN
;
162 * Generate cookie for DTLS ClientHello verification
164 int mbedtls_ssl_cookie_write( void *p_ctx
,
165 unsigned char **p
, unsigned char *end
,
166 const unsigned char *cli_id
, size_t cli_id_len
)
169 mbedtls_ssl_cookie_ctx
*ctx
= (mbedtls_ssl_cookie_ctx
*) p_ctx
;
172 if( ctx
== NULL
|| cli_id
== NULL
)
173 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA
);
175 if( (size_t)( end
- *p
) < COOKIE_LEN
)
176 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL
);
178 #if defined(MBEDTLS_HAVE_TIME)
179 t
= (unsigned long) mbedtls_time( NULL
);
184 (*p
)[0] = (unsigned char)( t
>> 24 );
185 (*p
)[1] = (unsigned char)( t
>> 16 );
186 (*p
)[2] = (unsigned char)( t
>> 8 );
187 (*p
)[3] = (unsigned char)( t
);
190 #if defined(MBEDTLS_THREADING_C)
191 if( ( ret
= mbedtls_mutex_lock( &ctx
->mutex
) ) != 0 )
192 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR
+ ret
);
195 ret
= ssl_cookie_hmac( &ctx
->hmac_ctx
, *p
- 4,
196 p
, end
, cli_id
, cli_id_len
);
198 #if defined(MBEDTLS_THREADING_C)
199 if( mbedtls_mutex_unlock( &ctx
->mutex
) != 0 )
200 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR
+
201 MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
210 int mbedtls_ssl_cookie_check( void *p_ctx
,
211 const unsigned char *cookie
, size_t cookie_len
,
212 const unsigned char *cli_id
, size_t cli_id_len
)
214 unsigned char ref_hmac
[COOKIE_HMAC_LEN
];
216 unsigned char *p
= ref_hmac
;
217 mbedtls_ssl_cookie_ctx
*ctx
= (mbedtls_ssl_cookie_ctx
*) p_ctx
;
218 unsigned long cur_time
, cookie_time
;
220 if( ctx
== NULL
|| cli_id
== NULL
)
221 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA
);
223 if( cookie_len
!= COOKIE_LEN
)
226 #if defined(MBEDTLS_THREADING_C)
227 if( ( ret
= mbedtls_mutex_lock( &ctx
->mutex
) ) != 0 )
228 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR
+ ret
);
231 if( ssl_cookie_hmac( &ctx
->hmac_ctx
, cookie
,
232 &p
, p
+ sizeof( ref_hmac
),
233 cli_id
, cli_id_len
) != 0 )
236 #if defined(MBEDTLS_THREADING_C)
237 if( mbedtls_mutex_unlock( &ctx
->mutex
) != 0 )
238 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR
+
239 MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
245 if( mbedtls_ssl_safer_memcmp( cookie
+ 4, ref_hmac
, sizeof( ref_hmac
) ) != 0 )
248 #if defined(MBEDTLS_HAVE_TIME)
249 cur_time
= (unsigned long) mbedtls_time( NULL
);
251 cur_time
= ctx
->serial
;
254 cookie_time
= ( (unsigned long) cookie
[0] << 24 ) |
255 ( (unsigned long) cookie
[1] << 16 ) |
256 ( (unsigned long) cookie
[2] << 8 ) |
257 ( (unsigned long) cookie
[3] );
259 if( ctx
->timeout
!= 0 && cur_time
- cookie_time
> ctx
->timeout
)
264 #endif /* MBEDTLS_SSL_COOKIE_C */