Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / extlibs / tinydtls / 0001-Add-TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256-cipher-su.patch
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
5  in tinydtls
6
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.
11
12 Change-Id: I70be3a8e9469cc1913373d820b4a3d4f4a6d6d0d
13 Signed-off-by: leechul <chuls.lee@samsung.com>
14 Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
15 ---
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(-)
22
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,
28  }
29  #endif /* DTLS_ECC */
30  
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,
38 +                                     size_t result_len)
39 +{
40 +  uint8_t eccPublicKey[64];
41 +  uint8_t eccPrivateKey[32];
42 +  unsigned char *p = result;
43 +
44 +  if (result_len < uECC_BYTES + psklen + (sizeof(uint16) * 2)) {
45 +    return -1;
46 +  }
47 +
48 +  dtls_int_to_uint16(p, uECC_BYTES);
49 +  p += sizeof(uint16);
50 +
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);
55 +  p += uECC_BYTES;
56 +
57 +  dtls_int_to_uint16(p, psklen);
58 +  p += sizeof(uint16);
59 +
60 +  memcpy(p, psk, psklen);
61 +
62 +  return uECC_BYTES + psklen + (sizeof(uint16) * 2);
63 +}
64 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
65 +
66  int
67  dtls_encrypt(const unsigned char *src, size_t length,
68              unsigned char *buf,
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);
72    }
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);
77        if (ret < 0) {
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);
81    }
82  
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);
87        if (ret < 0) {
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
93 @@ -39,6 +39,7 @@
94  #include "numeric.h"
95  #include "hmac.h"
96  #include "ccm.h"
97 +#include "ecc/ecc.h"
98  
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;
105 +
106 +#ifdef DTLS_ECC && DTLS_PSK
107 +  struct keyx_t {
108 +    dtls_handshake_parameters_ecc_t ecc;
109 +    dtls_handshake_parameters_psk_t psk;
110 +  } keyx;
111 +#else /* DTLS_ECC && DTLS_PSK */
112    union {
113  #ifdef DTLS_ECC
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 */
118    } keyx;
119 +#endif /* DTLS_ECC && DTLS_PSK */
120  } dtls_handshake_parameters_t;
121  
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
128  #endif
129  }
130  
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)
133 +{
134 +#if defined(DTLS_ECC) && defined(DTLS_PSK)
135 +  return cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
136 +#else
137 +  return 0;
138 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
139 +}
140 +
141 +
142  
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)
146  #endif
147  }
148  
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)
151 +{
152 +#if defined(DTLS_ECC) && defined(DTLS_PSK)
153 +    return is_psk_supported(ctx);
154 +#else
155 +    return 0;
156 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
157 +}
158 +
159 +
160  /**
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) {
164    int psk;
165    int ecdsa;
166    int ecdh_anon;
167 +  int ecdhe_psk;
168  
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);
173  
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));
179  }
180  
181  /**
182 @@ -676,7 +701,11 @@ calculate_key_block(dtls_context_t *ctx,
183                     dtls_peer_t *peer,
184                     session_t *session,
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];
189 +#else
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);
197    }
198  
199 -  pre_master_secret = security->key_block;
200 -
201    switch (handshake->cipher) {
202  #ifdef DTLS_PSK
203    case TLS_PSK_WITH_AES_128_CCM_8: {
204 @@ -733,6 +760,35 @@ calculate_key_block(dtls_context_t *ctx,
205      break;
206    }
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];
211 +      int psklen;
212 +
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);
217 +      if (psklen < 0) {
218 +        dtls_crit("no psk key for session available\n");
219 +        return psklen;
220 +      }
221 +
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),
227 +                           pre_master_secret,
228 +                           MAX_KEYBLOCK_LENGTH + uECC_BYTES);
229 +
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);
233 +      }
234 +      break;
235 +    }
236 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC)  */
237    default:
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);
242    }
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)) {
246 +    int id_length;
247 +
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);
251 +    }
252 +    data += DTLS_HS_LENGTH;
253 +
254 +    //PSK hint
255 +    id_length = dtls_uint16_to_int(data);
256 +    data += sizeof(uint16);
257 +
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);
261 +    }
262 +
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);
266 +    }
267 +
268 +    handshake->keyx.psk.id_length = id_length;
269 +    memcpy(handshake->keyx.psk.identity, data, id_length);
270 +    data += id_length;
271 +
272 +    //ECDH public
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);
276 +    }
277 +    data += sizeof(uint8);
278 +
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);
282 +    }
283 +    data += sizeof(uint8);
284 +
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);
288 +
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);
292 +  }
293 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
294  #ifdef DTLS_PSK
295    if (is_tls_psk_with_aes_128_ccm_8(handshake->cipher)) {
296      int id_length;
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];
300      }
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)) {
304  
305      unsigned char nonce[DTLS_CBC_IV_LENGTH];
306  
307 @@ -2116,6 +2223,80 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
308  }
309  #endif /* DTLS_ECC */
310  
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)
314 +{
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];
318 +  uint8 *p;
319 +  uint8 *ephemeral_pub_x;
320 +  uint8 *ephemeral_pub_y;
321 +  dtls_handshake_parameters_t *config = peer->handshake_params;
322 +
323 +  /* ServerKeyExchange
324 +    * Please see Session 2, RFC 5489.
325 +
326 +         struct {
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;
332 +          };
333 +      } ServerKeyExchange; */
334 +  p = buf;
335 +
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);
341 +  }
342 +
343 +  // psk_identity_hint
344 +  dtls_int_to_uint16(p, psk_hint_len);
345 +  p += sizeof(uint16);
346 +
347 +  memcpy(p, psk_hint, psk_hint_len);
348 +  p += psk_hint_len;
349 +
350 +  /* ServerECDHParams. */
351 +  /* ECCurveType curve_type: named_curve */
352 +  dtls_int_to_uint8(p, TLS_EC_CURVE_TYPE_NAMED_CURVE);
353 +  p += sizeof(uint8);
354 +
355 +  /* NamedCurve namedcurve: secp256r1 */
356 +  dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES_SECP256R1);
357 +  p += sizeof(uint16);
358 +
359 +  dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE);
360 +  p += sizeof(uint8);
361 +
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);
365 +
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;
369 +
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;
373 +
374 +  dtls_ecdsa_generate_key(config->keyx.ecc.own_eph_priv,
375 +              ephemeral_pub_x, ephemeral_pub_y,
376 +              DTLS_EC_KEY_SIZE);
377 +
378 +  assert(p - buf <= sizeof(buf));
379 +
380 +  return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE,
381 +                                buf, p - buf);
382 +}
383 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
384 +
385  #ifdef DTLS_PSK
386  static int
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)
389    int res;
390    int ecdsa;
391    int ecdh_anon;
392 +  int ecdhe_psk;
393  
394    res = dtls_send_server_hello(ctx, peer);
395  
396 @@ -2217,6 +2399,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
397  
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);
401  
402  #ifdef DTLS_ECC
403    if(ecdh_anon) {
404 @@ -2261,7 +2444,31 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
405      }
406    }
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];
411 +    int psk_len;
412 +
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);
417  
418 +    if (psk_len < 0) {
419 +      dtls_debug("dtls_server_hello: cannot create ServerKeyExchange\n");
420 +      return psk_len;
421 +    }
422 +
423 +    if (psk_len > 0) {
424 +      res = dtls_send_server_key_exchange_ecdhe_psk(ctx, peer, psk_hint, (size_t)psk_len);
425 +
426 +      if (res < 0) {
427 +        dtls_debug("dtls_server_hello(with ECDHE): cannot prepare Server Key Exchange record\n");
428 +        return res;
429 +      }
430 +    }
431 +  }
432 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
433  #ifdef DTLS_PSK
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) {
437  static int
438  dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
439  {
440 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
441 +  uint8 buf[DTLS_CKXEC_LENGTH + 2 + DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
442 +#else
443    uint8 buf[DTLS_CKXEC_LENGTH];
444 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
445    uint8 client_id[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
446    uint8 *p;
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)
449      break;
450    }
451  #endif /* DTLS_ECC */
452 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
453 +  case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256: {
454 +      int psk_len;
455 +      uint8 *ephemeral_pub_x;
456 +      uint8 *ephemeral_pub_y;
457 +
458 +    /* Please see Session 2, RFC 5489.
459 +         struct {
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;
465 +            } exchange_keys;
466 +        } ClientKeyExchange;
467 +    */
468 +
469 +    psk_len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_IDENTITY,
470 +               NULL, 0,
471 +               client_id,
472 +               sizeof(client_id));
473 +    if (psk_len < 0) {
474 +      dtls_crit("no psk identity set in kx\n");
475 +      return psk_len;
476 +    }
477 +
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);
481 +    }
482 +
483 +    dtls_int_to_uint16(p, psk_len);
484 +    p += sizeof(uint16);
485 +
486 +    memcpy(p, client_id, psk_len);
487 +    p += psk_len;
488 +
489 +    dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE);
490 +    p += sizeof(uint8);
491 +
492 +    dtls_int_to_uint8(p, 4);
493 +    p += sizeof(uint8);
494 +
495 +    ephemeral_pub_x = p;
496 +    p += DTLS_EC_KEY_SIZE;
497 +    ephemeral_pub_y = p;
498 +    p += DTLS_EC_KEY_SIZE;
499 +
500 +    dtls_ecdsa_generate_key(peer->handshake_params->keyx.ecc.own_eph_priv,
501 +                           ephemeral_pub_x, ephemeral_pub_y,
502 +                           DTLS_EC_KEY_SIZE);
503 +    break;
504 +  }
505 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
506    default:
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,
510    int psk = 0;
511    int ecdsa = 0;
512    int ecdh_anon = 0;
513 +  int ecdhe_psk = 0;
514    dtls_handshake_parameters_t *handshake = peer->handshake_params;
515    dtls_tick_t now;
516  
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);
520          break;
521 +      case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
522 +        ecdhe_psk = is_ecdhe_psk_supported(ctx);
523 +        break;
524        default:
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);
529          break;
530     }
531  
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;
535  
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);
539      p += sizeof(uint16);
540    }
541 +  if (ecdhe_psk) {
542 +      dtls_int_to_uint16(p, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
543 +      p += sizeof(uint16);
544 +  }
545  
546    /* compression method */
547    dtls_int_to_uint8(p, 1);
548 @@ -2900,8 +3174,97 @@ check_server_key_exchange_ecdh(dtls_context_t *ctx,
549  
550    return 0;
551  }
552 -
553  #endif /* DTLS_ECC */
554 +#if defined(DTLS_PSK) && defined(DTLS_ECC)
555 +check_server_key_exchange_ecdhe_psk(dtls_context_t *ctx,
556 +                             dtls_peer_t *peer,
557 +                             uint8 *data, size_t data_length)
558 +{
559 +  dtls_handshake_parameters_t *config = peer->handshake_params;
560 +  uint16_t psk_len = 0;
561 +
562 +  /* ServerKeyExchange
563 +    * Please see Session 2, RFC 5489.
564 +
565 +         struct {
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;
571 +          };
572 +      } ServerKeyExchange; */
573 +
574 +  update_hs_hash(peer, data, data_length);
575 +
576 +  assert(is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(config->cipher));
577 +
578 +  data += DTLS_HS_LENGTH;
579 +
580 +  psk_len = dtls_uint16_to_int(data);
581 +  data += sizeof(uint16);
582 +
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);
586 +  }
587 +
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);
591 +  }
592 +
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);
596 +
597 +  data += psk_len;
598 +  data_length -= psk_len;
599 +
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);
603 +  }
604 +
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);
608 +  }
609 +  data += sizeof(uint8);
610 +  data_length -= sizeof(uint8);
611 +
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);
615 +  }
616 +  data += sizeof(uint16);
617 +  data_length -= sizeof(uint16);
618 +
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);
622 +  }
623 +  data += sizeof(uint8);
624 +  data_length -= sizeof(uint8);
625 +
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);
629 +  }
630 +  data += sizeof(uint8);
631 +  data_length -= sizeof(uint8);
632 +
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);
636 +
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);
640 +
641 +  return 0;
642 +}
643 +#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
644  
645  #ifdef DTLS_PSK
646  static int
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 */
650      return clen;
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)) {
654  
655      unsigned char nonce[DTLS_CBC_IV_LENGTH];
656  
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),
660                        A_DATA, A_DATA_LEN,
661 -                      security->cipher);
662 +                      security->cipher);
663    }
664  
665    if (clen < 0)
666      dtls_warn("decryption failed\n");
667    else {
668  #ifndef NDEBUG
669 -      dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
670 +    dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
671  #endif
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);
676    }
677  
678    return clen;
679 @@ -3282,7 +3646,8 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
680      }
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
687      else
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);
691      }
692  #endif /* DTLS_ECC */
693 +
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);
698 +        }
699 +      err = check_server_key_exchange_ecdhe_psk(ctx, peer, data, data_length);
700 +    }
701 +#endif defined(DTLS_PSK) && defined(DTLS_ECC)
702 +
703  #ifdef DTLS_PSK
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 */
716  } dtls_cipher_t;
717  
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);
730  }
731  
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;
735        }
736 +      else if( strcmp(optarg, "4") == 0)
737 +      {
738 +          selected_cipher = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
739 +          ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
740 +      }
741        break;
742      default:
743        usage(argv[0], dtls_package_version());
744 -- 
745 1.7.9.5
746