1 From 947179cd0d3646359272cc0645e5049e2426f9e0 Mon Sep 17 00:00:00 2001
2 From: Sachin Agrawal <sachin.agrawal@intel.com>
3 Date: Thu, 6 Aug 2015 15:13:29 -0700
4 Subject: [PATCH 1/1] Add TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 cipher suite
7 [Patch #1] Initial upload
8 [Patch #2] Add function to calculate the pre-master key of ECDHE_PSK cipher suite.
9 [Patch #3] Update codes according to review comments
10 [Patch #4] Modify code alignment.
12 Change-Id: I70be3a8e9469cc1913373d820b4a3d4f4a6d6d0d
13 Signed-off-by: leechul <chuls.lee@samsung.com>
14 Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
16 extlibs/tinydtls/crypto.c | 41 +++-
17 extlibs/tinydtls/crypto.h | 9 +
18 extlibs/tinydtls/dtls.c | 401 ++++++++++++++++++++++++++++++++--
19 extlibs/tinydtls/global.h | 1 +
20 extlibs/tinydtls/tests/dtls-client.c | 8 +-
21 5 files changed, 444 insertions(+), 16 deletions(-)
23 diff --git a/extlibs/tinydtls/crypto.c b/extlibs/tinydtls/crypto.c
24 index 3fbb993..deaf581 100644
25 --- a/extlibs/tinydtls/crypto.c
26 +++ b/extlibs/tinydtls/crypto.c
27 @@ -641,6 +641,41 @@ dtls_ecdsa_verify_sig(const unsigned char *pub_key_x,
31 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
32 +int dtls_ecdhe_psk_pre_master_secret(unsigned char *psk, size_t psklen,
33 + unsigned char *ecc_priv_key,
34 + unsigned char *ecc_pub_key_x,
35 + unsigned char *ecc_pub_key_y,
36 + size_t ecc_key_size,
37 + unsigned char *result,
40 + uint8_t eccPublicKey[64];
41 + uint8_t eccPrivateKey[32];
42 + unsigned char *p = result;
44 + if (result_len < uECC_BYTES + psklen + (sizeof(uint16) * 2)) {
48 + dtls_int_to_uint16(p, uECC_BYTES);
49 + p += sizeof(uint16);
51 + memcpy(eccPublicKey, ecc_pub_key_x, 32);
52 + memcpy(eccPublicKey + 32, ecc_pub_key_y, 32);
53 + memcpy(eccPrivateKey, ecc_priv_key, 32);
54 + uECC_shared_secret(eccPublicKey, eccPrivateKey, p);
57 + dtls_int_to_uint16(p, psklen);
58 + p += sizeof(uint16);
60 + memcpy(p, psk, psklen);
62 + return uECC_BYTES + psklen + (sizeof(uint16) * 2);
64 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
67 dtls_encrypt(const unsigned char *src, size_t length,
69 @@ -665,7 +700,8 @@ dtls_encrypt(const unsigned char *src, size_t length,
70 memmove(buf, src, length);
71 ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
73 - if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256) {
74 + if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
75 + cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
76 ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
78 /* cleanup everything in case the key has the wrong size */
79 @@ -708,7 +744,8 @@ dtls_decrypt(const unsigned char *src, size_t length,
80 ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
83 - if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256) {
84 + if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
85 + cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
86 ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
88 /* cleanup everything in case the key has the wrong size */
89 diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h
90 index a81d306..f4cfc66 100644
91 --- a/extlibs/tinydtls/crypto.h
92 +++ b/extlibs/tinydtls/crypto.h
99 /* TLS_PSK_WITH_AES_128_CCM_8 */
100 #define DTLS_MAC_KEY_LENGTH 0
101 @@ -129,6 +130,13 @@ typedef struct {
102 dtls_compression_t compression; /**< compression method */
103 dtls_cipher_t cipher; /**< cipher type */
104 unsigned int do_client_auth:1;
106 +#ifdef DTLS_ECC && DTLS_PSK
108 + dtls_handshake_parameters_ecc_t ecc;
109 + dtls_handshake_parameters_psk_t psk;
111 +#else /* DTLS_ECC && DTLS_PSK */
114 dtls_handshake_parameters_ecc_t ecc;
115 @@ -137,6 +145,7 @@ typedef struct {
116 dtls_handshake_parameters_psk_t psk;
117 #endif /* DTLS_PSK */
119 +#endif /* DTLS_ECC && DTLS_PSK */
120 } dtls_handshake_parameters_t;
122 /* The following macros provide access to the components of the
123 diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c
124 index b5b8fd1..6104a08 100644
125 --- a/extlibs/tinydtls/dtls.c
126 +++ b/extlibs/tinydtls/dtls.c
127 @@ -506,6 +506,17 @@ static inline int is_tls_ecdh_anon_with_aes_128_cbc_sha_256(dtls_cipher_t cipher
131 +/** returns true if the cipher matches TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 */
132 +static inline int is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(dtls_cipher_t cipher)
134 +#if defined(DTLS_ECC) && defined(DTLS_PSK)
135 + return cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
138 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
143 /** returns true if the application is configured for psk */
144 static inline int is_psk_supported(dtls_context_t *ctx)
145 @@ -549,6 +560,17 @@ static inline int is_ecdh_anon_supported(dtls_context_t *ctx)
149 +/** returns true if ecdhe_psk_with_aes_128_cbc_sha_256 is supported */
150 +static inline int is_ecdhe_psk_supported(dtls_context_t *ctx)
152 +#if defined(DTLS_ECC) && defined(DTLS_PSK)
153 + return is_psk_supported(ctx);
156 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
161 * Returns @c 1 if @p code is a cipher suite other than @c
162 * TLS_NULL_WITH_NULL_NULL that we recognize.
163 @@ -563,14 +585,17 @@ known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) {
169 psk = is_psk_supported(ctx);
170 ecdsa = is_ecdsa_supported(ctx, is_client);
171 ecdh_anon = is_ecdh_anon_supported(ctx);
172 + ecdhe_psk = is_ecdhe_psk_supported(ctx);
174 return (psk && is_tls_psk_with_aes_128_ccm_8(code)) ||
175 (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)) ||
176 - (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code));
177 + (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code)) ||
178 + (ecdhe_psk && is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(code));
182 @@ -676,7 +701,11 @@ calculate_key_block(dtls_context_t *ctx,
185 dtls_peer_type role) {
186 - unsigned char *pre_master_secret;
187 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
188 + unsigned char pre_master_secret[MAX_KEYBLOCK_LENGTH + uECC_BYTES];
190 + unsigned char pre_master_secret[MAX_KEYBLOCK_LENGTH];
191 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
192 int pre_master_len = 0;
193 dtls_security_parameters_t *security = dtls_security_params_next(peer);
194 uint8 master_secret[DTLS_MASTER_SECRET_LENGTH];
195 @@ -685,8 +714,6 @@ calculate_key_block(dtls_context_t *ctx,
196 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
199 - pre_master_secret = security->key_block;
201 switch (handshake->cipher) {
203 case TLS_PSK_WITH_AES_128_CCM_8: {
204 @@ -733,6 +760,35 @@ calculate_key_block(dtls_context_t *ctx,
207 #endif /* DTLS_ECC */
208 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
209 + case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256: {
210 + unsigned char psk[DTLS_PSK_MAX_KEY_LEN];
213 + psklen = CALL(ctx, get_psk_info, session, DTLS_PSK_KEY,
214 + handshake->keyx.psk.identity,
215 + handshake->keyx.psk.id_length,
216 + psk, DTLS_PSK_MAX_KEY_LEN);
218 + dtls_crit("no psk key for session available\n");
222 + pre_master_len = dtls_ecdhe_psk_pre_master_secret(psk, psklen,
223 + handshake->keyx.ecc.own_eph_priv,
224 + handshake->keyx.ecc.other_eph_pub_x,
225 + handshake->keyx.ecc.other_eph_pub_y,
226 + sizeof(handshake->keyx.ecc.own_eph_priv),
228 + MAX_KEYBLOCK_LENGTH + uECC_BYTES);
230 + if (pre_master_len < 0) {
231 + dtls_crit("the curve was too long, for the pre master secret\n");
232 + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
236 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
238 dtls_crit("calculate_key_block: unknown cipher\n");
239 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
240 @@ -1113,6 +1169,56 @@ check_client_keyexchange(dtls_context_t *ctx,
241 data += sizeof(handshake->keyx.ecc.other_eph_pub_y);
243 #endif /* DTLS_ECC */
244 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
245 + if (is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(handshake->cipher)) {
248 + if (length < DTLS_HS_LENGTH + DTLS_CKXEC_LENGTH) {
249 + dtls_debug("The client key exchange is too short\n");
250 + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
252 + data += DTLS_HS_LENGTH;
255 + id_length = dtls_uint16_to_int(data);
256 + data += sizeof(uint16);
258 + if (DTLS_HS_LENGTH + DTLS_CKXPSK_LENGTH_MIN + DTLS_CKXEC_LENGTH + id_length != length) {
259 + dtls_debug("The identity has a wrong length\n");
260 + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
263 + if (id_length > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) {
264 + dtls_warn("please use a smaller client identity\n");
265 + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
268 + handshake->keyx.psk.id_length = id_length;
269 + memcpy(handshake->keyx.psk.identity, data, id_length);
273 + if (dtls_uint8_to_int(data) != 1 + 2 * DTLS_EC_KEY_SIZE) {
274 + dtls_alert("expected 65 bytes long public point\n");
275 + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
277 + data += sizeof(uint8);
279 + if (dtls_uint8_to_int(data) != 4) {
280 + dtls_alert("expected uncompressed public point\n");
281 + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
283 + data += sizeof(uint8);
285 + memcpy(handshake->keyx.ecc.other_eph_pub_x, data,
286 + sizeof(handshake->keyx.ecc.other_eph_pub_x));
287 + data += sizeof(handshake->keyx.ecc.other_eph_pub_x);
289 + memcpy(handshake->keyx.ecc.other_eph_pub_y, data,
290 + sizeof(handshake->keyx.ecc.other_eph_pub_y));
291 + data += sizeof(handshake->keyx.ecc.other_eph_pub_y);
293 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
295 if (is_tls_psk_with_aes_128_ccm_8(handshake->cipher)) {
297 @@ -1286,7 +1392,8 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
298 p += data_len_array[i];
299 res += data_len_array[i];
301 - } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher)) {
302 + } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher) ||
303 + is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(security->cipher)) {
305 unsigned char nonce[DTLS_CBC_IV_LENGTH];
307 @@ -2116,6 +2223,80 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
309 #endif /* DTLS_ECC */
311 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
312 +static int dtls_send_server_key_exchange_ecdhe_psk(dtls_context_t *ctx, dtls_peer_t *peer,
313 + const unsigned char *psk_hint, size_t psk_hint_len)
315 + /* The ASN.1 Integer representation of an 32 byte unsigned int could be
316 + * 33 bytes long add space for that */
317 + uint8 buf[DTLS_SKEXEC_LENGTH + DTLS_SKEXECPSK_LENGTH_MAX + 2];
319 + uint8 *ephemeral_pub_x;
320 + uint8 *ephemeral_pub_y;
321 + dtls_handshake_parameters_t *config = peer->handshake_params;
323 + /* ServerKeyExchange
324 + * Please see Session 2, RFC 5489.
327 + select (KeyExchangeAlgorithm) {
328 + //other cases for rsa, diffie_hellman, etc.
329 + case ec_diffie_hellman_psk: // NEW
330 + opaque psk_identity_hint<0..2^16-1>;
331 + ServerECDHParams params;
333 + } ServerKeyExchange; */
336 + assert(psk_hint_len <= DTLS_PSK_MAX_CLIENT_IDENTITY_LEN);
337 + if (psk_hint_len > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) {
338 + // should never happen
339 + dtls_warn("psk identity hint is too long\n");
340 + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
343 + // psk_identity_hint
344 + dtls_int_to_uint16(p, psk_hint_len);
345 + p += sizeof(uint16);
347 + memcpy(p, psk_hint, psk_hint_len);
350 + /* ServerECDHParams. */
351 + /* ECCurveType curve_type: named_curve */
352 + dtls_int_to_uint8(p, TLS_EC_CURVE_TYPE_NAMED_CURVE);
353 + p += sizeof(uint8);
355 + /* NamedCurve namedcurve: secp256r1 */
356 + dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES_SECP256R1);
357 + p += sizeof(uint16);
359 + dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE);
360 + p += sizeof(uint8);
362 + /* This should be an uncompressed point, but I do not have access to the spec. */
363 + dtls_int_to_uint8(p, 4);
364 + p += sizeof(uint8);
366 + /* store the pointer to the x component of the pub key and make space */
367 + ephemeral_pub_x = p;
368 + p += DTLS_EC_KEY_SIZE;
370 + /* store the pointer to the y component of the pub key and make space */
371 + ephemeral_pub_y = p;
372 + p += DTLS_EC_KEY_SIZE;
374 + dtls_ecdsa_generate_key(config->keyx.ecc.own_eph_priv,
375 + ephemeral_pub_x, ephemeral_pub_y,
378 + assert(p - buf <= sizeof(buf));
380 + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE,
383 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
387 dtls_send_server_key_exchange_psk(dtls_context_t *ctx, dtls_peer_t *peer,
388 @@ -2207,6 +2388,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
394 res = dtls_send_server_hello(ctx, peer);
396 @@ -2217,6 +2399,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
398 ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher);
399 ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
400 + ecdhe_psk = is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
404 @@ -2261,7 +2444,31 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
407 #endif /* DTLS_ECC */
408 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
409 + else if(ecdhe_psk) {
410 + unsigned char psk_hint[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
413 + /* The identity hint is optional, therefore we ignore the result
414 + * and check psk only. */
415 + psk_len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_HINT,
416 + NULL, 0, psk_hint, DTLS_PSK_MAX_CLIENT_IDENTITY_LEN);
419 + dtls_debug("dtls_server_hello: cannot create ServerKeyExchange\n");
424 + res = dtls_send_server_key_exchange_ecdhe_psk(ctx, peer, psk_hint, (size_t)psk_len);
427 + dtls_debug("dtls_server_hello(with ECDHE): cannot prepare Server Key Exchange record\n");
432 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
434 if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) {
435 unsigned char psk_hint[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
436 @@ -2308,7 +2515,11 @@ dtls_send_ccs(dtls_context_t *ctx, dtls_peer_t *peer) {
438 dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
440 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
441 + uint8 buf[DTLS_CKXEC_LENGTH + 2 + DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
443 uint8 buf[DTLS_CKXEC_LENGTH];
444 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
445 uint8 client_id[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
447 dtls_handshake_parameters_t *handshake = peer->handshake_params;
448 @@ -2368,6 +2579,60 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
451 #endif /* DTLS_ECC */
452 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
453 + case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256: {
455 + uint8 *ephemeral_pub_x;
456 + uint8 *ephemeral_pub_y;
458 + /* Please see Session 2, RFC 5489.
460 + select (KeyExchangeAlgorithm) {
461 + // other cases for rsa, diffie_hellman, etc.
462 + case ec_diffie_hellman_psk:
463 + opaque psk_identity<0..2^16-1>;
464 + ClientECDiffieHellmanPublic public;
466 + } ClientKeyExchange;
469 + psk_len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_IDENTITY,
472 + sizeof(client_id));
474 + dtls_crit("no psk identity set in kx\n");
478 + if (psk_len + sizeof(uint16) > DTLS_CKXEC_LENGTH) {
479 + dtls_warn("the psk identity is too long\n");
480 + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
483 + dtls_int_to_uint16(p, psk_len);
484 + p += sizeof(uint16);
486 + memcpy(p, client_id, psk_len);
489 + dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE);
490 + p += sizeof(uint8);
492 + dtls_int_to_uint8(p, 4);
493 + p += sizeof(uint8);
495 + ephemeral_pub_x = p;
496 + p += DTLS_EC_KEY_SIZE;
497 + ephemeral_pub_y = p;
498 + p += DTLS_EC_KEY_SIZE;
500 + dtls_ecdsa_generate_key(peer->handshake_params->keyx.ecc.own_eph_priv,
501 + ephemeral_pub_x, ephemeral_pub_y,
505 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
507 dtls_crit("cipher not supported\n");
508 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
509 @@ -2457,6 +2722,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
514 dtls_handshake_parameters_t *handshake = peer->handshake_params;
517 @@ -2471,14 +2737,18 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
518 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
519 ecdh_anon = is_ecdh_anon_supported(ctx);
521 + case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
522 + ecdhe_psk = is_ecdhe_psk_supported(ctx);
525 psk = is_psk_supported(ctx);
526 ecdsa = is_ecdsa_supported(ctx, 1);
527 ecdh_anon = is_ecdh_anon_supported(ctx);
528 + ecdhe_psk = is_ecdhe_psk_supported(ctx);
532 - cipher_size = 2 + (ecdsa ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0);
533 + cipher_size = 2 + (ecdsa ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
534 extension_size = (ecdsa) ? (2 + 6 + 6 + 8 + 6) : 0;
536 if (cipher_size == 0) {
537 @@ -2533,6 +2803,10 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
538 dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
542 + dtls_int_to_uint16(p, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
543 + p += sizeof(uint16);
546 /* compression method */
547 dtls_int_to_uint8(p, 1);
548 @@ -2900,8 +3174,97 @@ check_server_key_exchange_ecdh(dtls_context_t *ctx,
553 #endif /* DTLS_ECC */
554 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
555 +check_server_key_exchange_ecdhe_psk(dtls_context_t *ctx,
557 + uint8 *data, size_t data_length)
559 + dtls_handshake_parameters_t *config = peer->handshake_params;
560 + uint16_t psk_len = 0;
562 + /* ServerKeyExchange
563 + * Please see Session 2, RFC 5489.
566 + select (KeyExchangeAlgorithm) {
567 + //other cases for rsa, diffie_hellman, etc.
568 + case ec_diffie_hellman_psk: // NEW
569 + opaque psk_identity_hint<0..2^16-1>;
570 + ServerECDHParams params;
572 + } ServerKeyExchange; */
574 + update_hs_hash(peer, data, data_length);
576 + assert(is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(config->cipher));
578 + data += DTLS_HS_LENGTH;
580 + psk_len = dtls_uint16_to_int(data);
581 + data += sizeof(uint16);
583 + if (psk_len != data_length - DTLS_HS_LENGTH - DTLS_SKEXEC_ECDH_ANON_LENGTH - sizeof(uint16)) {
584 + dtls_warn("the length of the server identity hint is worng\n");
585 + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
588 + if (psk_len > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) {
589 + dtls_warn("please use a smaller server identity hint\n");
590 + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
593 + // store the psk_identity_hint in config->keyx.psk for later use
594 + config->keyx.psk.id_length = psk_len;
595 + memcpy(config->keyx.psk.identity, data, psk_len);
598 + data_length -= psk_len;
600 + if (data_length < DTLS_HS_LENGTH + DTLS_SKEXEC_ECDH_ANON_LENGTH) {
601 + dtls_alert("the packet length does not match the expected\n");
602 + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
605 + if (dtls_uint8_to_int(data) != TLS_EC_CURVE_TYPE_NAMED_CURVE) {
606 + dtls_alert("Only named curves supported\n");
607 + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
609 + data += sizeof(uint8);
610 + data_length -= sizeof(uint8);
612 + if (dtls_uint16_to_int(data) != TLS_EXT_ELLIPTIC_CURVES_SECP256R1) {
613 + dtls_alert("secp256r1 supported\n");
614 + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
616 + data += sizeof(uint16);
617 + data_length -= sizeof(uint16);
619 + if (dtls_uint8_to_int(data) != 1 + 2 * DTLS_EC_KEY_SIZE) {
620 + dtls_alert("expected 65 bytes long public point\n");
621 + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
623 + data += sizeof(uint8);
624 + data_length -= sizeof(uint8);
626 + if (dtls_uint8_to_int(data) != 4) {
627 + dtls_alert("expected uncompressed public point\n");
628 + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
630 + data += sizeof(uint8);
631 + data_length -= sizeof(uint8);
633 + memcpy(config->keyx.ecc.other_eph_pub_x, data, sizeof(config->keyx.ecc.other_eph_pub_x));
634 + data += sizeof(config->keyx.ecc.other_eph_pub_x);
635 + data_length -= sizeof(config->keyx.ecc.other_eph_pub_x);
637 + memcpy(config->keyx.ecc.other_eph_pub_y, data, sizeof(config->keyx.ecc.other_eph_pub_y));
638 + data += sizeof(config->keyx.ecc.other_eph_pub_y);
639 + data_length -= sizeof(config->keyx.ecc.other_eph_pub_y);
643 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
647 @@ -3113,7 +3476,8 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
648 if (security->cipher == TLS_NULL_WITH_NULL_NULL) {
649 /* no cipher suite selected */
651 - } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher)) {
652 + } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher) ||
653 + is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(security->cipher)) {
655 unsigned char nonce[DTLS_CBC_IV_LENGTH];
657 @@ -3169,17 +3533,17 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
658 dtls_kb_remote_write_key(security, peer->role),
659 dtls_kb_key_size(security, peer->role),
666 dtls_warn("decryption failed\n");
669 - dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
670 + dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
672 - dtls_security_params_free_other(peer);
673 - dtls_debug_dump("cleartext", *cleartext, clen);
674 + dtls_security_params_free_other(peer);
675 + dtls_debug_dump("cleartext", *cleartext, clen);
679 @@ -3282,7 +3646,8 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
681 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher))
682 peer->state = DTLS_STATE_WAIT_SERVERCERTIFICATE; //ecdsa
683 - else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher))
684 + else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher) ||
685 + is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher))
686 peer->state = DTLS_STATE_WAIT_SERVERKEYEXCHANGE; //ecdh
688 peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; //psk
689 @@ -3329,6 +3694,16 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
690 err = check_server_key_exchange_ecdh(ctx, peer, data, data_length);
692 #endif /* DTLS_ECC */
694 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
695 + if (is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher)) {
696 + if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
697 + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
699 + err = check_server_key_exchange_ecdhe_psk(ctx, peer, data, data_length);
701 +#endif defined(DTLS_PSK) && defined(DTLS_ECC)
704 if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) {
705 if (state != DTLS_STATE_WAIT_SERVERHELLODONE) {
706 diff --git a/extlibs/tinydtls/global.h b/extlibs/tinydtls/global.h
707 index 169c726..8b3c518 100644
708 --- a/extlibs/tinydtls/global.h
709 +++ b/extlibs/tinydtls/global.h
710 @@ -75,6 +75,7 @@ typedef enum {
711 TLS_NULL_WITH_NULL_NULL = 0x0000, /**< NULL cipher */
712 TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 = 0xC018, /**< see RFC 4492 */
713 TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, /**< see RFC 6655 */
714 + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
715 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE /**< see RFC 7251 */
718 diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c
719 index dfc822a..dfd34c8 100644
720 --- a/extlibs/tinydtls/tests/dtls-client.c
721 +++ b/extlibs/tinydtls/tests/dtls-client.c
722 @@ -311,7 +311,8 @@ usage( const char *program, const char *version) {
723 "\t-c num\t\tcipher suite (default: 1)\n"
724 "\t\t\t1: TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 \n"
725 "\t\t\t2: TLS_PSK_WITH_AES_128_CCM_8\n"
726 - "\t\t\t3: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n",
727 + "\t\t\t3: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n"
728 + "\t\t\t4: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256\n",
729 program, version, program, DEFAULT_PORT);
732 @@ -430,6 +431,11 @@ main(int argc, char **argv) {
733 selected_cipher = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ;
734 ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
736 + else if( strcmp(optarg, "4") == 0)
738 + selected_cipher = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
739 + ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
743 usage(argv[0], dtls_package_version());