diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index cf18ea7517..b8d798b18c 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -1520,6 +1520,12 @@ int ssl_write_finished( ssl_context *ssl ); void ssl_optimize_checksum( ssl_context *ssl, const ssl_ciphersuite_t *ciphersuite_info ); +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ); +#endif + #if defined(POLARSSL_PK_C) unsigned char ssl_sig_from_pk( pk_context *pk ); pk_type_t ssl_pk_alg_from_sig( unsigned char sig ); diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 699bcb6fd4..bc67957791 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1805,8 +1805,6 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ) { - unsigned char *p = ssl->handshake->premaster; - /* * PSK key exchange * @@ -1815,35 +1813,26 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) if( ssl->psk == NULL ) return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); - if( sizeof(ssl->handshake->premaster) < 4 + 2 * ssl->psk_len ) - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); - + i = 4; n = ssl->psk_identity_len; - - ssl->out_msg[4] = (unsigned char)( n >> 8 ); - ssl->out_msg[5] = (unsigned char)( n ); - i = 6; + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); memcpy( ssl->out_msg + i, ssl->psk_identity, ssl->psk_identity_len ); + i += ssl->psk_identity_len; - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - p += ssl->psk_len; - - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - memcpy( p, ssl->psk, ssl->psk_len ); - p += ssl->psk_len; - - ssl->handshake->pmslen = 4 + 2 * ssl->psk_len; + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); + } } else #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { - unsigned char *p = ssl->handshake->premaster; - /* * DHE_PSK key exchange * @@ -1853,24 +1842,21 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) if( ssl->psk == NULL ) return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); - if( sizeof(ssl->handshake->premaster) < 4 + ssl->psk_identity_len + - ssl->handshake->dhm_ctx.len ) - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); - i = 4; n = ssl->psk_identity_len; - ssl->out_msg[4] = (unsigned char)( n >> 8 ); - ssl->out_msg[5] = (unsigned char)( n ); + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); - memcpy( ssl->out_msg + 6, ssl->psk_identity, ssl->psk_identity_len ); + memcpy( ssl->out_msg + i, ssl->psk_identity, ssl->psk_identity_len ); + i += ssl->psk_identity_len; n = ssl->handshake->dhm_ctx.len; - ssl->out_msg[6 + ssl->psk_identity_len] = (unsigned char)( n >> 8 ); - ssl->out_msg[7 + ssl->psk_identity_len] = (unsigned char)( n ); + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); ret = dhm_make_public( &ssl->handshake->dhm_ctx, mpi_size( &ssl->handshake->dhm_ctx.P ), - &ssl->out_msg[8 + ssl->psk_identity_len], n, + &ssl->out_msg[i], n, ssl->f_rng, ssl->p_rng ); if( ret != 0 ) { @@ -1878,38 +1864,18 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) return( ret ); } - SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); - SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); - - *(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len >> 8 ); - *(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len ); - if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, - p, &n, ssl->f_rng, ssl->p_rng ) ) != 0 ) + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) { - SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); return( ret ); } - - SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - - p += ssl->handshake->dhm_ctx.len; - - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - memcpy( p, ssl->psk, ssl->psk_len ); - p += ssl->psk_len; - - ssl->handshake->pmslen = 4 + ssl->handshake->dhm_ctx.len + ssl->psk_len; - n = ssl->handshake->pmslen; } else #endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) { - unsigned char *p = ssl->handshake->premaster; - size_t zlen; - /* * ECDHE_PSK key exchange: RFC 5489, section 2 * @@ -1919,9 +1885,6 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) if( ssl->psk == NULL ) return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); - if( sizeof(ssl->handshake->premaster) < 4 + ssl->psk_identity_len ) - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); - i = 4; ssl->out_msg[i++] = (unsigned char)( ssl->psk_identity_len >> 8 ); ssl->out_msg[i++] = (unsigned char)( ssl->psk_identity_len ); @@ -1930,7 +1893,7 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) i += ssl->psk_identity_len; ret = ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, - &ssl->out_msg[i], 1000, + &ssl->out_msg[i], SSL_MAX_CONTENT_LEN - i, ssl->f_rng, ssl->p_rng ); if( ret != 0 ) { @@ -1940,33 +1903,12 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); - /* - * PMS = struct { - * opaque other_secret<0..2^16-1>; - * opaque psk<0..2^16-1>; - * }; - * with "other_secret" containing Z from ECDH - */ - if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, - p + 2, POLARSSL_MPI_MAX_SIZE, - ssl->f_rng, ssl->p_rng ) ) != 0 ) + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) { - SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret ); + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); return( ret ); } - - *(p++) = (unsigned char)( zlen >> 8 ); - *(p++) = (unsigned char)( zlen ); - p += zlen; - - SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); - - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - memcpy( p, ssl->psk, ssl->psk_len ); - p += ssl->psk_len; - - ssl->handshake->pmslen = p - ssl->handshake->premaster; } else #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 158877090b..f09b924672 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -2022,10 +2022,9 @@ static int ssl_write_server_key_exchange( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "ECDH curve size: %d", (int) ssl->handshake->ecdh_ctx.grp.nbits ) ); - if( ( ret = ecdh_make_params( &ssl->handshake->ecdh_ctx, - &len, - p, - 1000, ssl->f_rng, ssl->p_rng ) ) != 0 ) + if( ( ret = ecdh_make_params( &ssl->handshake->ecdh_ctx, &len, + p, SSL_MAX_CONTENT_LEN - n, + ssl->f_rng, ssl->p_rng ) ) != 0 ) { SSL_DEBUG_RET( 1, "ecdh_make_params", ret ); return( ret ); @@ -2532,26 +2531,18 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) return( ret ); } - // Set up the premaster secret - // - p = ssl->handshake->premaster; - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - p += ssl->psk_len; - - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - memcpy( p, ssl->psk, ssl->psk_len ); - p += ssl->psk_len; - - ssl->handshake->pmslen = 4 + 2 * ssl->psk_len; + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); + } } else #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) { - size_t n; unsigned char *p = ssl->in_msg + 4; unsigned char *end = ssl->in_msg + ssl->in_msglen; @@ -2566,38 +2557,18 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) return( ret ); } - // Set up the premaster secret - // - p = ssl->handshake->premaster; - *(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len >> 8 ); - *(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len ); - - n = ssl->handshake->dhm_ctx.len; - - if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, - p, &n, ssl->f_rng, ssl->p_rng ) ) != 0 ) + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) { - SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); - return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); } - - SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - - p += ssl->handshake->dhm_ctx.len; - - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - memcpy( p, ssl->psk, ssl->psk_len ); - p += ssl->psk_len; - - ssl->handshake->pmslen = 4 + ssl->handshake->dhm_ctx.len + ssl->psk_len; } else #endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) { - size_t n; unsigned char *p = ssl->in_msg + 4; unsigned char *end = ssl->in_msg + ssl->in_msglen; @@ -2616,31 +2587,12 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); - // Set up the premaster secret - // - p = ssl->handshake->premaster; - - if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &n, - p + 2, POLARSSL_MPI_MAX_SIZE, - ssl->f_rng, ssl->p_rng ) ) != 0 ) + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) { - SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret ); + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); return( ret ); } - - *(p++) = (unsigned char)( n >> 8 ); - *(p++) = (unsigned char)( n ); - p += n; - - SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); - - *(p++) = (unsigned char)( ssl->psk_len >> 8 ); - *(p++) = (unsigned char)( ssl->psk_len ); - memcpy( p, ssl->psk, ssl->psk_len ); - p += ssl->psk_len; - - ssl->handshake->pmslen = 4 + n + ssl->psk_len; - n = ssl->handshake->pmslen; } else #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d3b4ce3a09..e4ae682297 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -825,6 +825,96 @@ void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] ) #endif /* POLARSSL_SHA512_C */ #endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ) +{ + int ret; + unsigned char *p = ssl->handshake->premaster; + unsigned char *end = p + sizeof( ssl->handshake->premaster ); + + /* + * PMS = struct { + * opaque other_secret<0..2^16-1>; + * opaque psk<0..2^16-1>; + * }; + * with "other_secret" depending on the particular key exchange + */ +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + if( key_ex == POLARSSL_KEY_EXCHANGE_PSK ) + { + if( end - p < 2 + (int) ssl->psk_len ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + *(p++) = (unsigned char)( ssl->psk_len >> 8 ); + *(p++) = (unsigned char)( ssl->psk_len ); + p += ssl->psk_len; + } + else +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( key_ex == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + size_t len = ssl->handshake->dhm_ctx.len; + + if( end - p < 2 + (int) len ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + *(p++) = (unsigned char)( len >> 8 ); + *(p++) = (unsigned char)( len ); + if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, + p, &len, ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); + return( ret ); + } + p += len; + + SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( key_ex == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + size_t zlen; + + if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, + p + 2, end - (p + 2), + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret ); + return( ret ); + } + + *(p++) = (unsigned char)( zlen >> 8 ); + *(p++) = (unsigned char)( zlen ); + p += zlen; + + SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + /* opaque psk<0..2^16-1>; */ + *(p++) = (unsigned char)( ssl->psk_len >> 8 ); + *(p++) = (unsigned char)( ssl->psk_len ); + memcpy( p, ssl->psk, ssl->psk_len ); + p += ssl->psk_len; + + ssl->handshake->pmslen = p - ssl->handshake->premaster; + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED || + POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + #if defined(POLARSSL_SSL_PROTO_SSL3) /* * SSLv3.0 MAC functions