Merge branch 'development' into misc

This commit is contained in:
Simon Butcher 2015-10-27 16:57:34 +00:00
commit 204606238c
47 changed files with 2991 additions and 761 deletions

View file

@ -2,11 +2,27 @@ mbed TLS ChangeLog (Sorted per branch, date)
= mbed TLS 2.2.0 released 2015-10-xx = mbed TLS 2.2.0 released 2015-10-xx
Features
* Experimental support for EC J-PAKE as defined in Thread 1.0.0.
Disabled by default as the specification might still change.
* Added a key extraction callback to accees the master secret and key
block. (Potential uses include EAP-TLS and Thread.)
Bugfix Bugfix
* Fix build error with configurations where ECDHE-PSK is the only key * Fix build error with configurations where ECDHE-PSK is the only key
exchange. Found and fix provided by Chris Hammond. #270 exchange. Found and fix provided by Chris Hammond. #270
* Fix build error with configurations where RSA, RSA-PSK, ECDH-RSA or * Fix build error with configurations where RSA, RSA-PSK, ECDH-RSA or
ECHD-ECDSA if the only key exchange. Multiple reports. #310 ECHD-ECDSA if the only key exchange. Multiple reports. #310
* Fixed a bug causing some handshakes to fail due to some non-fatal alerts
not being properly ignored. Found by mancha and Kasom Koht-arsa, #308
* mbedtls_x509_crt_verify(_with_profile)() now also checks the key type and
size/curve against the profile. Before that, there was no way to set a
minimum key size for end-entity certificates with RSA keys. Found by
Matthew Page of Scannex Electronics Ltd.
Changes
* Improved performance of mbedtls_ecp_muladd() when one of the scalars is 1
or -1.
= mbed TLS 2.1.2 released 2015-10-06 = mbed TLS 2.1.2 released 2015-10-06

View file

@ -39,7 +39,7 @@ and build it with:
yotta build yotta build
If, on the other hand, you already have a copy of mbed TLS from a source other than the yotta registry, for example from cloning our github repository, or from downloading a tarball of the standalone edition, then you'll need first need to generate the yotta module by running: If, on the other hand, you already have a copy of mbed TLS from a source other than the yotta registry, for example from cloning our GitHub repository, or from downloading a tarball of the standalone edition, then you'll need first need to generate the yotta module by running:
yotta/create-module.sh yotta/create-module.sh
@ -50,7 +50,7 @@ from the mbed TLS root directory. This will create the yotta module in the `yott
In any case, you'll probably want to set the yotta target before building unless it's already set globally; for more information on using yotta, please consult the [yotta documentation](http://docs.yottabuild.org/). In any case, you'll probably want to set the yotta target before building unless it's already set globally; for more information on using yotta, please consult the [yotta documentation](http://docs.yottabuild.org/).
The yotta edition of mbed TLS includes a few example programs, some of which demonstrate integration with mbed OS; for more details, please consult the [Readme at the root of the yotta module](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/README.md). For more details on the yotta/mbed OS edition of mbed TLS, including example programs, please consult the [Readme at the root of the yotta module](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/README.md).
### Make ### Make

94
configs/config-thread.h Normal file
View file

@ -0,0 +1,94 @@
/*
* Minimal configuration for using TLS as part of Thread
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Minimal configuration for using TLS a part of Thread
* http://threadgroup.org/
*
* Distinguishing features:
* - no RSA or classic DH, fully based on ECC
* - no X.509
* - support for experimental EC J-PAKE key exchange
*
* See README.txt for usage instructions.
*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_HAVE_ASM
/* mbed TLS feature support */
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_NIST_OPTIM
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_SSL_PROTO_DTLS
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
#define MBEDTLS_SSL_EXPORT_KEYS
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_ECJPAKE_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SSL_COOKIE_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
/* For tests using ssl-opt.sh */
#define MBEDTLS_NET_C
#define MBEDTLS_TIMING_C
/* Save RAM at the expense of ROM */
#define MBEDTLS_AES_ROM_TABLES
/* Save RAM by adjusting to our exact needs */
#define MBEDTLS_ECP_MAX_BITS 256
#define MBEDTLS_MPI_MAX_SIZE 32 // 256 bits is 32 bytes
/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
#if defined(TARGET_LIKE_MBED)
#include "mbedtls/target_config.h"
#endif
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */

View file

@ -88,6 +88,11 @@
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" #error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) #if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif #endif
@ -187,6 +192,12 @@
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" #error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" #error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"

View file

@ -694,6 +694,25 @@
*/ */
#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
/**
* \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
*
* Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
*
* \warning This is currently experimental. EC J-PAKE support is based on the
* Thread v1.0.0 specification; incompatible changes to the specification
* might still happen. For this reason, this is disabled by default.
*
* Requires: MBEDTLS_ECJPAKE_C
* MBEDTLS_SHA256_C
* MBEDTLS_ECP_DP_SECP256R1_ENABLED
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
* MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
*/
//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
/** /**
* \def MBEDTLS_PK_PARSE_EC_EXTENDED * \def MBEDTLS_PK_PARSE_EC_EXTENDED
* *
@ -1175,6 +1194,16 @@
*/ */
#define MBEDTLS_SSL_SESSION_TICKETS #define MBEDTLS_SSL_SESSION_TICKETS
/**
* \def MBEDTLS_SSL_EXPORT_KEYS
*
* Enable support for exporting key block and master secret.
* This is required for certain users of TLS, e.g. EAP-TLS.
*
* Comment this macro to disable support for key export
*/
#define MBEDTLS_SSL_EXPORT_KEYS
/** /**
* \def MBEDTLS_SSL_SERVER_NAME_INDICATION * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
* *
@ -1688,6 +1717,25 @@
*/ */
#define MBEDTLS_ECDSA_C #define MBEDTLS_ECDSA_C
/**
* \def MBEDTLS_ECJPAKE_C
*
* Enable the elliptic curve J-PAKE library.
*
* \warning This is currently experimental. EC J-PAKE support is based on the
* Thread v1.0.0 specification; incompatible changes to the specification
* might still happen. For this reason, this is disabled by default.
*
* Module: library/ecjpake.c
* Caller:
*
* This module is used by the following key exchanges:
* ECJPAKE
*
* Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
*/
//#define MBEDTLS_ECJPAKE_C
/** /**
* \def MBEDTLS_ECP_C * \def MBEDTLS_ECP_C
* *
@ -1696,6 +1744,7 @@
* Module: library/ecp.c * Module: library/ecp.c
* Caller: library/ecdh.c * Caller: library/ecdh.c
* library/ecdsa.c * library/ecdsa.c
* library/ecjpake.c
* *
* Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
*/ */

238
include/mbedtls/ecjpake.h Normal file
View file

@ -0,0 +1,238 @@
/**
* \file ecjpake.h
*
* \brief Elliptic curve J-PAKE
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECJPAKE_H
#define MBEDTLS_ECJPAKE_H
/*
* J-PAKE is a password-authenticated key exchange that allows deriving a
* strong shared secret from a (potentially low entropy) pre-shared
* passphrase, with forward secrecy and mutual authentication.
* https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
*
* This file implements the Elliptic Curve variant of J-PAKE,
* as defined in Chapter 7.4 of the Thread v1.0 Specification,
* available to members of the Thread Group http://threadgroup.org/
*
* As the J-PAKE algorithm is inherently symmetric, so is our API.
* Each party needs to send its first round message, in any order, to the
* other party, then each sends its second round message, in any order.
* The payloads are serialized in a way suitable for use in TLS, but could
* also be use outside TLS.
*/
#include "ecp.h"
#include "md.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Roles in the EC J-PAKE exchange
*/
typedef enum {
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
MBEDTLS_ECJPAKE_SERVER, /**< Server */
} mbedtls_ecjpake_role;
/**
* EC J-PAKE context structure.
*
* J-PAKE is a symmetric protocol, except for the identifiers used in
* Zero-Knowledge Proofs, and the serialization of the second message
* (KeyExchange) as defined by the Thread spec.
*
* In order to benefit from this symmetry, we choose a different naming
* convetion from the Thread v1.0 spec. Correspondance is indicated in the
* description as a pair C: <client name>, S: <server name>
*/
typedef struct
{
const mbedtls_md_info_t *md_info; /**< Hash to use */
mbedtls_ecp_group grp; /**< Elliptic curve */
mbedtls_ecjpake_role role; /**< Are we client or server? */
int point_format; /**< Format for point export */
mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */
mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */
mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */
mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */
mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */
mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */
mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */
mbedtls_mpi s; /**< Pre-shared secret (passphrase) */
} mbedtls_ecjpake_context;
/**
* \brief Initialize a context
* (just makes it ready for setup() or free()).
*
* \param ctx context to initialize
*/
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
/**
* \brief Set up a context for use
*
* \note Currently the only values for hash/curve allowed by the
* standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1.
*
* \param ctx context to set up
* \param role Our role: client or server
* \param hash hash function to use (MBEDTLS_MD_XXX)
* \param curve elliptic curve identifier (MBEDTLS_ECP_DP_XXX)
* \param secret pre-shared secret (passphrase)
* \param len length of the shared secret
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
mbedtls_ecjpake_role role,
mbedtls_md_type_t hash,
mbedtls_ecp_group_id curve,
const unsigned char *secret,
size_t len );
/*
* \brief Check if a context is ready for use
*
* \param ctx Context to check
*
* \return 0 if the context is ready for use,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
*/
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
/**
* \brief Generate and write the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes)
*
* \param ctx Context to use
* \param buf Pointer to extension contents
* \param len Extension length
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Generate and write the second round message
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the second round message
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx Context to use
* \param buf Pointer to the message
* \param len Message length
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Derive the shared secret
* (TLS: Pre-Master Secret)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Free a context's content
*
* \param ctx context to free
*/
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_ecjpake_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* ecjpake.h */

View file

@ -346,6 +346,21 @@ int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
*/ */
int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
/**
* \brief Compare two points
*
* \note This assumes the points are normalized. Otherwise,
* they may compare as "not equal" even if they are.
*
* \param P First point to compare
* \param Q Second point to compare
*
* \return 0 if the points are equal,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
*/
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q );
/** /**
* \brief Import a non-zero point from two ASCII strings * \brief Import a non-zero point from two ASCII strings
* *
@ -569,6 +584,29 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_po
*/ */
int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ); int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
/**
* \brief Generate a keypair with configurable base point
*
* \param grp ECP group
* \param G Chosen base point
* \param d Destination MPI (secret part)
* \param Q Destination point (public part)
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*
* \note Uses bare components rather than an mbedtls_ecp_keypair structure
* in order to ease use with other structures such as
* mbedtls_ecdh_context of mbedtls_ecdsa_context.
*/
int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/** /**
* \brief Generate a keypair * \brief Generate a keypair
* *

View file

@ -332,6 +332,8 @@
#define MBEDTLS_TLS_EXT_SESSION_TICKET 35 #define MBEDTLS_TLS_EXT_SESSION_TICKET 35
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */
#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01
/* /*
@ -370,6 +372,9 @@ union mbedtls_ssl_premaster_secret
unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES
+ MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */
#endif
}; };
#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret ) #define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret )
@ -522,6 +527,13 @@ struct mbedtls_ssl_config
void *p_ticket; /*!< context for the ticket callbacks */ void *p_ticket; /*!< context for the ticket callbacks */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
/** Callback to export key block and master secret */
int (*f_export_keys)( void *, const unsigned char *,
const unsigned char *, size_t, size_t, size_t );
void *p_export_keys; /*!< context for key export callback */
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */
mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */
@ -1049,6 +1061,35 @@ typedef int mbedtls_ssl_ticket_write_t( void *p_ticket,
size_t *tlen, size_t *tlen,
uint32_t *lifetime ); uint32_t *lifetime );
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
/**
* \brief Callback type: Export key block and master secret
*
* \note This is required for certain uses of TLS, e.g. EAP-TLS
* (RFC 5216) and Thread. The key pointers are ephemeral and
* therefore must not be stored. The master secret and keys
* should not be used directly except as an input to a key
* derivation function.
*
* \param p_expkey Context for the callback
* \param ms Pointer to master secret (fixed length: 48 bytes)
* \param kb Pointer to key block, see RFC 5246 section 6.3
* (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
* \param maclen MAC length
* \param keylen Key length
* \param ivlen IV length
*
* \return 0 if successful, or
* a specific MBEDTLS_ERR_XXX code.
*/
typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
const unsigned char *ms,
const unsigned char *kb,
size_t maclen,
size_t keylen,
size_t ivlen );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
/** /**
* \brief Callback type: parse and load session ticket * \brief Callback type: parse and load session ticket
* *
@ -1098,6 +1139,22 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
void *p_ticket ); void *p_ticket );
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
/**
* \brief Configure key export callback.
* (Default: none.)
*
* \note See \c mbedtls_ssl_export_keys_t.
*
* \param conf SSL configuration context
* \param f_export_keys Callback for exporting keys
* \param p_export_keys Context for the callback
*/
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_t *f_export_keys,
void *p_export_keys );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
/** /**
* \brief Callback type: generate a cookie * \brief Callback type: generate a cookie
* *
@ -1365,6 +1422,10 @@ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
/** /**
* \brief Set the X.509 security profile used for verification * \brief Set the X.509 security profile used for verification
* *
* \note The restrictions are enforced for all certificates in the
* chain. However, signatures in the handshake are not covered
* by this setting but by \b mbedtls_ssl_conf_sig_hashes().
*
* \param conf SSL configuration * \param conf SSL configuration
* \param profile Profile to use * \param profile Profile to use
*/ */
@ -1526,16 +1587,14 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
* On client: this affects the list of curves offered for any * On client: this affects the list of curves offered for any
* use. The server can override our preference order. * use. The server can override our preference order.
* *
* Both sides: limits the set of curves used by peer to the * Both sides: limits the set of curves accepted for use in
* listed curves for any use ECDHE and the end-entity * ECDHE and in the peer's end-entity certificate.
* certificate.
* *
* \note This has no influence on which curve are allowed inside the * \note This has no influence on which curves are allowed inside the
* certificate chains, see \c mbedtls_ssl_conf_cert_profile() * certificate chains, see \c mbedtls_ssl_conf_cert_profile()
* for that. For example, if the peer's certificate chain is * for that. For the end-entity certificate however, the key
* EE -> CA_int -> CA_root, then the allowed curves for EE are * will be accepted only if it is allowed both by this list
* controlled by \c mbedtls_ssl_conf_curves() but for CA_int * and by the cert profile.
* and CA_root it's \c mbedtls_ssl_conf_cert_profile().
* *
* \note This list should be ordered by decreasing preference * \note This list should be ordered by decreasing preference
* (preferred curve first). * (preferred curve first).
@ -1659,6 +1718,29 @@ void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
void *p_sni ); void *p_sni );
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/**
* \brief Set the EC J-PAKE password for current handshake.
*
* \note An internal copy is made, and destroyed as soon as the
* handshake is completed, or when the SSL context is reset or
* freed.
*
* \note The SSL context needs to be already set up. The right place
* to call this function is between \c mbedtls_ssl_setup() or
* \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake().
*
* \param ssl SSL context
* \param pw EC J-PAKE password (pre-shared secret)
* \param pw_len length of pw in bytes
*
* \return 0 on success, or a negative error code.
*/
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw,
size_t pw_len );
#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
/** /**
* \brief Set the supported Application Layer Protocols. * \brief Set the supported Application Layer Protocols.

View file

@ -121,7 +121,7 @@ void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeou
#endif /* MBEDTLS_HAVE_TIME */ #endif /* MBEDTLS_HAVE_TIME */
/** /**
* \brief Set the cache timeout * \brief Set the maximum number of cache entries
* (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50))
* *
* \param cache SSL cache context * \param cache SSL cache context

View file

@ -229,6 +229,8 @@ extern "C" {
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */
#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */
/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. /* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange.
* Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below
*/ */
@ -244,6 +246,7 @@ typedef enum {
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_KEY_EXCHANGE_ECDH_RSA, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_KEY_EXCHANGE_ECJPAKE,
} mbedtls_key_exchange_type_t; } mbedtls_key_exchange_type_t;
/* Key exchanges using a certificate */ /* Key exchanges using a certificate */

View file

@ -41,6 +41,10 @@
#include "sha512.h" #include "sha512.h"
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#include "ecjpake.h"
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus) !defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
@ -147,6 +151,7 @@
* of state of the renegotiation flag, so no indicator is required) * of state of the renegotiation flag, so no indicator is required)
*/ */
#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) #define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0)
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -169,7 +174,15 @@ struct mbedtls_ssl_handshake_params
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_ECDH_C)
mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */
#endif #endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */
#if defined(MBEDTLS_SSL_CLI_C)
unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */
size_t ecjpake_cache_len; /*!< Length of cached data */
#endif
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)

View file

@ -301,8 +301,8 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
* security profile. * security profile.
* *
* \note The restrictions on keys (RSA minimum size, allowed curves * \note The restrictions on keys (RSA minimum size, allowed curves
* for ECDSA) only applys to (intermediate) CAs, not to the * for ECDSA) apply to all certificates: trusted root,
* end-entity certificate. * intermediate CAs if any, and end entity certificate.
* *
* \param crt a certificate to be verified * \param crt a certificate to be verified
* \param trust_ca the trusted CA chain * \param trust_ca the trusted CA chain

View file

@ -20,6 +20,7 @@ set(src_crypto
dhm.c dhm.c
ecdh.c ecdh.c
ecdsa.c ecdsa.c
ecjpake.c
ecp.c ecp.c
ecp_curves.c ecp_curves.c
entropy.c entropy.c

View file

@ -49,7 +49,8 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
bignum.o blowfish.o camellia.o \ bignum.o blowfish.o camellia.o \
ccm.o cipher.o cipher_wrap.o \ ccm.o cipher.o cipher_wrap.o \
ctr_drbg.o des.o dhm.o \ ctr_drbg.o des.o dhm.o \
ecdh.o ecdsa.o ecp.o \ ecdh.o ecdsa.o ecjpake.o \
ecp.o \
ecp_curves.o entropy.o entropy_poll.o \ ecp_curves.o entropy.o entropy_poll.o \
error.o gcm.o havege.o \ error.o gcm.o havege.o \
hmac_drbg.o md.o md2.o \ hmac_drbg.o md.o md2.o \

View file

@ -22,7 +22,7 @@
* This MPI implementation is based on: * This MPI implementation is based on:
* *
* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
* http://www.stillhq.com/extracted/gnupg-api/mbedtls_mpi/ * http://www.stillhq.com/extracted/gnupg-api/mpi/
* http://math.libtomcrypt.com/files/tommath.pdf * http://math.libtomcrypt.com/files/tommath.pdf
*/ */

1103
library/ecjpake.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -403,6 +403,22 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 );
} }
/*
* Compare two points lazyly
*/
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q )
{
if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 &&
mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 &&
mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 )
{
return( 0 );
}
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
/* /*
* Import a non-zero point from ASCII strings * Import a non-zero point from ASCII strings
*/ */
@ -1667,8 +1683,39 @@ cleanup:
} }
#endif /* ECP_SHORTWEIERSTRASS */ #endif /* ECP_SHORTWEIERSTRASS */
/*
* R = m * P with shortcuts for m == 1 and m == -1
* NOT constant-time - ONLY for short Weierstrass!
*/
static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
mbedtls_ecp_point *R,
const mbedtls_mpi *m,
const mbedtls_ecp_point *P )
{
int ret;
if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
{
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
}
else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
{
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 )
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) );
}
else
{
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
}
cleanup:
return( ret );
}
/* /*
* Linear combination * Linear combination
* NOT constant-time
*/ */
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P, const mbedtls_mpi *m, const mbedtls_ecp_point *P,
@ -1682,8 +1729,9 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_ecp_point_init( &mP ); mbedtls_ecp_point_init( &mP );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &mP, m, P, NULL, NULL ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, n, Q, NULL, NULL ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) );
MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) ); MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) );
MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) );
@ -1762,9 +1810,11 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *
} }
/* /*
* Generate a keypair * Generate a keypair with configurable base point
*/ */
int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng ) void *p_rng )
{ {
@ -1836,7 +1886,18 @@ cleanup:
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
return( mbedtls_ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) ); return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
}
/*
* Generate key pair, wrapper for conventional base point
*/
int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
} }
/* /*

View file

@ -1181,6 +1181,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
return( ret ); return( ret );
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
#else #else
((void) ret);
((void) pwd); ((void) pwd);
((void) pwdlen); ((void) pwdlen);
#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_PEM_PARSE_C */

View file

@ -40,7 +40,7 @@
* *
* Current rule (except rc4, weak and null which come last): * Current rule (except rc4, weak and null which come last):
* 1. By key exchange: * 1. By key exchange:
* Forward-secure non-PSK > forward-secure PSK > other non-PSK > other PSK * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
* 2. By key length and cipher: * 2. By key length and cipher:
* AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES * AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES
* 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8
@ -131,6 +131,9 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
/* The ECJPAKE suite */
MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
/* All AES-256 suites */ /* All AES-256 suites */
MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_RSA_WITH_AES_256_CCM, MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
@ -1510,6 +1513,18 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#endif /* MBEDTLS_ARC4_C */ #endif /* MBEDTLS_ARC4_C */
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_CCM_C)
{ MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8",
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_CIPHERSUITE_SHORT_TAG },
#endif /* MBEDTLS_CCM_C */
#endif /* MBEDTLS_AES_C */
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)

View file

@ -241,7 +241,8 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
size_t *olen ) size_t *olen )
@ -336,7 +337,86 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
*olen = 6; *olen = 6;
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
int ret;
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t kkpp_len;
*olen = 0;
/* Skip costly extension if we can't use EC J-PAKE anyway */
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
return;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
if( end - p < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
/*
* We may need to send ClientHello multiple times for Hello verification.
* We don't want to compute fresh values every time (both for performance
* and consistency reasons), so cache the extension content.
*/
if( ssl->handshake->ecjpake_cache == NULL ||
ssl->handshake->ecjpake_cache_len == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
return;
}
ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
if( ssl->handshake->ecjpake_cache == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
return;
}
memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
ssl->handshake->ecjpake_cache_len = kkpp_len;
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
kkpp_len = ssl->handshake->ecjpake_cache_len;
if( (size_t)( end - p - 2 ) < kkpp_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
}
*p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
*olen = kkpp_len + 4;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
@ -790,8 +870,14 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
continue; continue;
#endif #endif
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d", #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ciphersuites[i] ) ); if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
continue;
#endif
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
ciphersuites[i] ) );
n++; n++;
*p++ = (unsigned char)( ciphersuites[i] >> 8 ); *p++ = (unsigned char)( ciphersuites[i] >> 8 );
@ -881,7 +967,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
@ -889,6 +976,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
@ -1096,7 +1188,8 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf, const unsigned char *buf,
size_t len ) size_t len )
@ -1117,7 +1210,12 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
p[0] == MBEDTLS_ECP_PF_COMPRESSED ) p[0] == MBEDTLS_ECP_PF_COMPRESSED )
{ {
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
ssl->handshake->ecdh_ctx.point_format = p[0]; ssl->handshake->ecdh_ctx.point_format = p[0];
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl->handshake->ecjpake_ctx.point_format = p[0];
#endif
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
return( 0 ); return( 0 );
} }
@ -1129,7 +1227,38 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
int ret;
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
return( 0 );
}
/* If we got here, we no longer need our cached extension */
mbedtls_free( ssl->handshake->ecjpake_cache );
ssl->handshake->ecjpake_cache = NULL;
ssl->handshake->ecjpake_cache_len = 0;
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
buf, len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
return( ret );
}
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
@ -1479,7 +1608,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->handshake->resume ? "a" : "no" ) ); ssl->handshake->resume ? "a" : "no" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ); suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
@ -1494,6 +1623,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
i = 0; i = 0;
while( 1 ) while( 1 )
{ {
@ -1617,7 +1748,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break; break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
@ -1628,7 +1760,21 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
} }
break; break;
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) );
if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
ext + 4, ext_size ) ) != 0 )
{
return( ret );
}
break;
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
case MBEDTLS_TLS_EXT_ALPN: case MBEDTLS_TLS_EXT_ALPN:
@ -2151,6 +2297,19 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -2355,7 +2514,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++; ssl->state++;
@ -2379,7 +2539,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++; ssl->state++;
@ -2759,6 +2920,31 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
else else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
i = 4;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret );
}
ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
return( ret );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
{ {
((void) ciphersuite_info); ((void) ciphersuite_info);
@ -2803,7 +2989,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++; ssl->state++;
@ -2835,7 +3022,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++; ssl->state++;

View file

@ -232,7 +232,8 @@ have_sig_alg:
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
const unsigned char *buf, const unsigned char *buf,
size_t len ) size_t len )
@ -305,7 +306,12 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
p[0] == MBEDTLS_ECP_PF_COMPRESSED ) p[0] == MBEDTLS_ECP_PF_COMPRESSED )
{ {
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
ssl->handshake->ecdh_ctx.point_format = p[0]; ssl->handshake->ecdh_ctx.point_format = p[0];
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl->handshake->ecjpake_ctx.point_format = p[0];
#endif
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
return( 0 ); return( 0 );
} }
@ -316,7 +322,35 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
int ret;
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
return( 0 );
}
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
buf, len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
return( ret );
}
/* Only mark the extension as OK when we're sure it is */
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
@ -707,6 +741,17 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
} }
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake "
"not configured or ext missing" ) );
return( 0 );
}
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
( ssl->handshake->curves == NULL || ( ssl->handshake->curves == NULL ||
@ -1541,7 +1586,8 @@ read_record_header:
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
@ -1558,7 +1604,18 @@ read_record_header:
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) );
ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
@ -1976,7 +2033,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
size_t *olen ) size_t *olen )
@ -2004,7 +2062,51 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
*olen = 6; *olen = 6;
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
int ret;
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t kkpp_len;
*olen = 0;
/* Skip costly computation if not needed */
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
return;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) );
if( end - p < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
return;
}
*p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
*olen = kkpp_len + 4;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN ) #if defined(MBEDTLS_SSL_ALPN )
static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
@ -2290,11 +2392,17 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
@ -2333,7 +2441,8 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
ssl->state++; ssl->state++;
@ -2370,6 +2479,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
authmode == MBEDTLS_SSL_VERIFY_NONE ) authmode == MBEDTLS_SSL_VERIFY_NONE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
@ -2544,12 +2654,14 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
unsigned char *p = ssl->out_msg + 4; unsigned char *p = ssl->out_msg + 4;
unsigned char *dig_signed = p; unsigned char *dig_signed = p;
size_t dig_signed_len = 0, len; size_t dig_signed_len = 0, len;
((void) dig_signed); ((void) dig_signed);
((void) dig_signed_len); ((void) dig_signed_len);
((void) len);
#endif #endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
@ -2580,6 +2692,25 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
} }
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
size_t jlen;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p, &jlen, ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret );
}
p += jlen;
n += jlen;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
@ -3331,6 +3462,28 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
} }
else else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
return( ret );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -3362,7 +3515,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++; ssl->state++;
@ -3392,6 +3546,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
ssl->session_negotiate->peer_cert == NULL ) ssl->session_negotiate->peer_cert == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );

View file

@ -862,6 +862,16 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
} }
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( ssl->conf->f_export_keys != NULL )
{
ssl->conf->f_export_keys( ssl->conf->p_export_keys,
session->master, keyblk,
transform->maclen, transform->keylen,
iv_copy_len );
}
#endif
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
cipher_info ) ) != 0 ) cipher_info ) ) != 0 )
{ {
@ -3696,8 +3706,9 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
/* /*
* Read a record. * Read a record.
* *
* For DTLS, silently ignore invalid records (RFC 4.1.2.7.) * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
* and continue reading until a valid record is found. * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
*
*/ */
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ) int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
{ {
@ -3729,9 +3740,7 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
/* /*
* Read the record header and parse it * Read the record header and parse it
*/ */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
read_record_header: read_record_header:
#endif
if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
@ -3887,7 +3896,7 @@ read_record_header:
ssl->in_msg[0], ssl->in_msg[1] ) ); ssl->in_msg[0], ssl->in_msg[1] ) );
/* /*
* Ignore non-fatal alerts, except close_notify * Ignore non-fatal alerts, except close_notify and no_renegotiation
*/ */
if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
{ {
@ -3902,6 +3911,31 @@ read_record_header:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
} }
#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
/* Will be handled when trying to parse ServerHello */
return( 0 );
}
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
/* Will be handled in mbedtls_ssl_parse_certificate() */
return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
/* Silently ignore: fetch new message */
goto read_record_header;
} }
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
@ -3968,7 +4002,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++; ssl->state++;
@ -3987,7 +4022,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
ssl->state++; ssl->state++;
@ -4009,7 +4045,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++; ssl->state++;
@ -4124,7 +4161,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
ssl->state++; ssl->state++;
@ -5146,6 +5184,13 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_ECDH_C)
mbedtls_ecdh_init( &handshake->ecdh_ctx ); mbedtls_ecdh_init( &handshake->ecdh_ctx );
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
#if defined(MBEDTLS_SSL_CLI_C)
handshake->ecjpake_cache = NULL;
handshake->ecjpake_cache_len = 0;
#endif
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
@ -5679,6 +5724,32 @@ void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/*
* Set EC J-PAKE password for current handshake
*/
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw,
size_t pw_len )
{
mbedtls_ecjpake_role role;
if( ssl->handshake == NULL && ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
role = MBEDTLS_ECJPAKE_SERVER;
else
role = MBEDTLS_ECJPAKE_CLIENT;
return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx,
role,
MBEDTLS_MD_SHA256,
MBEDTLS_ECP_DP_SECP256R1,
pw, pw_len ) );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
const unsigned char *psk, size_t psk_len, const unsigned char *psk, size_t psk_len,
@ -5735,11 +5806,7 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
mbedtls_free( ssl->handshake->psk ); mbedtls_free( ssl->handshake->psk );
if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
{
mbedtls_free( ssl->handshake->psk );
ssl->handshake->psk = NULL;
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
}
ssl->handshake->psk_len = psk_len; ssl->handshake->psk_len = psk_len;
memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
@ -6006,6 +6073,16 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
#endif #endif
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_t *f_export_keys,
void *p_export_keys )
{
conf->f_export_keys = f_export_keys;
conf->p_export_keys = p_export_keys;
}
#endif
/* /*
* SSL get accessors * SSL get accessors
*/ */
@ -6826,6 +6903,14 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake )
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_ECDH_C)
mbedtls_ecdh_free( &handshake->ecdh_ctx ); mbedtls_ecdh_free( &handshake->ecdh_ctx );
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
#if defined(MBEDTLS_SSL_CLI_C)
mbedtls_free( handshake->ecjpake_cache );
handshake->ecjpake_cache = NULL;
handshake->ecjpake_cache_len = 0;
#endif
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
/* explicit void pointer cast for buggy MS compiler */ /* explicit void pointer cast for buggy MS compiler */
@ -7175,7 +7260,8 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) ); mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) );
} }
#if defined(MBEDTLS_PK_C) #if defined(MBEDTLS_PK_C) && \
( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) )
/* /*
* Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
*/ */
@ -7208,7 +7294,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
return( MBEDTLS_PK_NONE ); return( MBEDTLS_PK_NONE );
} }
} }
#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
/* /*
* Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
@ -7364,6 +7450,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
case MBEDTLS_KEY_EXCHANGE_PSK: case MBEDTLS_KEY_EXCHANGE_PSK:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK: case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
usage = 0; usage = 0;
} }
} }

View file

@ -264,6 +264,9 @@ static const char *features[] = {
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
"MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED",
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
"MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED",
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
"MBEDTLS_PK_PARSE_EC_EXTENDED", "MBEDTLS_PK_PARSE_EC_EXTENDED",
#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
@ -378,6 +381,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
"MBEDTLS_SSL_SESSION_TICKETS", "MBEDTLS_SSL_SESSION_TICKETS",
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
"MBEDTLS_SSL_EXPORT_KEYS",
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
"MBEDTLS_SSL_SERVER_NAME_INDICATION", "MBEDTLS_SSL_SERVER_NAME_INDICATION",
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
@ -465,6 +471,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDSA_C)
"MBEDTLS_ECDSA_C", "MBEDTLS_ECDSA_C",
#endif /* MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_ECJPAKE_C)
"MBEDTLS_ECJPAKE_C",
#endif /* MBEDTLS_ECJPAKE_C */
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
"MBEDTLS_ECP_C", "MBEDTLS_ECP_C",
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */

View file

@ -186,8 +186,10 @@ static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
} }
#endif #endif
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECP_C)
if( pk_alg == MBEDTLS_PK_ECDSA ) if( pk_alg == MBEDTLS_PK_ECDSA ||
pk_alg == MBEDTLS_PK_ECKEY ||
pk_alg == MBEDTLS_PK_ECKEY_DH )
{ {
mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
@ -2151,6 +2153,7 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
mbedtls_x509_crt *parent; mbedtls_x509_crt *parent;
mbedtls_x509_name *name; mbedtls_x509_name *name;
mbedtls_x509_sequence *cur = NULL; mbedtls_x509_sequence *cur = NULL;
mbedtls_pk_type_t pk_type;
if( profile == NULL ) if( profile == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
@ -2209,6 +2212,15 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
} }
} }
/* Check the type and size of the key */
pk_type = mbedtls_pk_get_type( &crt->pk );
if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
*flags |= MBEDTLS_X509_BADCERT_BAD_PK;
if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 )
*flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
/* Look for a parent in trusted CAs */ /* Look for a parent in trusted CAs */
for( parent = trust_ca; parent != NULL; parent = parent->next ) for( parent = trust_ca; parent != NULL; parent = parent->next )
{ {

View file

@ -209,7 +209,7 @@ int main( int argc, char *argv[] )
ret = 1; ret = 1;
mbedtls_printf( USAGE ); mbedtls_printf( USAGE );
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
mbedtls_printf( " availabled ec_curve values:\n" ); mbedtls_printf( " available ec_curve values:\n" );
curve_info = mbedtls_ecp_curve_list(); curve_info = mbedtls_ecp_curve_list();
mbedtls_printf( " %s (default)\n", curve_info->name ); mbedtls_printf( " %s (default)\n", curve_info->name );
while( ( ++curve_info )->name != NULL ) while( ( ++curve_info )->name != NULL )

View file

@ -75,6 +75,7 @@ int main( void )
#define DFL_KEY_FILE "" #define DFL_KEY_FILE ""
#define DFL_PSK "" #define DFL_PSK ""
#define DFL_PSK_IDENTITY "Client_identity" #define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
#define DFL_FORCE_CIPHER 0 #define DFL_FORCE_CIPHER 0
#define DFL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION_DISABLED #define DFL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION_DISABLED
#define DFL_ALLOW_LEGACY -2 #define DFL_ALLOW_LEGACY -2
@ -211,6 +212,13 @@ int main( void )
#define USAGE_RENEGO "" #define USAGE_RENEGO ""
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#define USAGE_ECJPAKE \
" ecjpake_pw=%%s default: none (disabled)\n"
#else
#define USAGE_ECJPAKE ""
#endif
#define USAGE \ #define USAGE \
"\n usage: ssl_client2 param=<>...\n" \ "\n usage: ssl_client2 param=<>...\n" \
"\n acceptable parameters:\n" \ "\n acceptable parameters:\n" \
@ -233,6 +241,7 @@ int main( void )
USAGE_IO \ USAGE_IO \
"\n" \ "\n" \
USAGE_PSK \ USAGE_PSK \
USAGE_ECJPAKE \
"\n" \ "\n" \
" allow_legacy=%%d default: (library default: no)\n" \ " allow_legacy=%%d default: (library default: no)\n" \
USAGE_RENEGO \ USAGE_RENEGO \
@ -279,6 +288,7 @@ struct options
const char *key_file; /* the file with the client key */ const char *key_file; /* the file with the client key */
const char *psk; /* the pre-shared key */ const char *psk; /* the pre-shared key */
const char *psk_identity; /* the pre-shared key identity */ const char *psk_identity; /* the pre-shared key identity */
const char *ecjpake_pw; /* the EC J-PAKE password */
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
int renegotiation; /* enable / disable renegotiation */ int renegotiation; /* enable / disable renegotiation */
int allow_legacy; /* allow legacy renegotiation */ int allow_legacy; /* allow legacy renegotiation */
@ -469,6 +479,7 @@ int main( int argc, char *argv[] )
opt.key_file = DFL_KEY_FILE; opt.key_file = DFL_KEY_FILE;
opt.psk = DFL_PSK; opt.psk = DFL_PSK;
opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_identity = DFL_PSK_IDENTITY;
opt.ecjpake_pw = DFL_ECJPAKE_PW;
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
opt.renegotiation = DFL_RENEGOTIATION; opt.renegotiation = DFL_RENEGOTIATION;
opt.allow_legacy = DFL_ALLOW_LEGACY; opt.allow_legacy = DFL_ALLOW_LEGACY;
@ -557,6 +568,8 @@ int main( int argc, char *argv[] )
opt.psk = q; opt.psk = q;
else if( strcmp( p, "psk_identity" ) == 0 ) else if( strcmp( p, "psk_identity" ) == 0 )
opt.psk_identity = q; opt.psk_identity = q;
else if( strcmp( p, "ecjpake_pw" ) == 0 )
opt.ecjpake_pw = q;
else if( strcmp( p, "force_ciphersuite" ) == 0 ) else if( strcmp( p, "force_ciphersuite" ) == 0 )
{ {
opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q ); opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q );
@ -1204,6 +1217,19 @@ int main( int argc, char *argv[] )
} }
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
{
if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
(const unsigned char *) opt.ecjpake_pw,
strlen( opt.ecjpake_pw ) ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
goto exit;
}
}
#endif
if( opt.nbio == 2 ) if( opt.nbio == 2 )
mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL ); mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL );
else else

View file

@ -102,6 +102,7 @@ int main( void )
#define DFL_KEY_FILE2 "" #define DFL_KEY_FILE2 ""
#define DFL_PSK "" #define DFL_PSK ""
#define DFL_PSK_IDENTITY "Client_identity" #define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
#define DFL_PSK_LIST NULL #define DFL_PSK_LIST NULL
#define DFL_FORCE_CIPHER 0 #define DFL_FORCE_CIPHER 0
#define DFL_VERSION_SUITES NULL #define DFL_VERSION_SUITES NULL
@ -293,6 +294,13 @@ int main( void )
#define USAGE_RENEGO "" #define USAGE_RENEGO ""
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#define USAGE_ECJPAKE \
" ecjpake_pw=%%s default: none (disabled)\n"
#else
#define USAGE_ECJPAKE ""
#endif
#define USAGE \ #define USAGE \
"\n usage: ssl_server2 param=<>...\n" \ "\n usage: ssl_server2 param=<>...\n" \
"\n acceptable parameters:\n" \ "\n acceptable parameters:\n" \
@ -314,6 +322,7 @@ int main( void )
USAGE_SNI \ USAGE_SNI \
"\n" \ "\n" \
USAGE_PSK \ USAGE_PSK \
USAGE_ECJPAKE \
"\n" \ "\n" \
" allow_legacy=%%d default: (library default: no)\n" \ " allow_legacy=%%d default: (library default: no)\n" \
USAGE_RENEGO \ USAGE_RENEGO \
@ -358,6 +367,7 @@ struct options
const char *psk; /* the pre-shared key */ const char *psk; /* the pre-shared key */
const char *psk_identity; /* the pre-shared key identity */ const char *psk_identity; /* the pre-shared key identity */
char *psk_list; /* list of PSK id/key pairs for callback */ char *psk_list; /* list of PSK id/key pairs for callback */
const char *ecjpake_pw; /* the EC J-PAKE password */
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
const char *version_suites; /* per-version ciphersuites */ const char *version_suites; /* per-version ciphersuites */
int renegotiation; /* enable / disable renegotiation */ int renegotiation; /* enable / disable renegotiation */
@ -900,6 +910,7 @@ int main( int argc, char *argv[] )
opt.psk = DFL_PSK; opt.psk = DFL_PSK;
opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_identity = DFL_PSK_IDENTITY;
opt.psk_list = DFL_PSK_LIST; opt.psk_list = DFL_PSK_LIST;
opt.ecjpake_pw = DFL_ECJPAKE_PW;
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
opt.version_suites = DFL_VERSION_SUITES; opt.version_suites = DFL_VERSION_SUITES;
opt.renegotiation = DFL_RENEGOTIATION; opt.renegotiation = DFL_RENEGOTIATION;
@ -985,6 +996,8 @@ int main( int argc, char *argv[] )
opt.psk_identity = q; opt.psk_identity = q;
else if( strcmp( p, "psk_list" ) == 0 ) else if( strcmp( p, "psk_list" ) == 0 )
opt.psk_list = q; opt.psk_list = q;
else if( strcmp( p, "ecjpake_pw" ) == 0 )
opt.ecjpake_pw = q;
else if( strcmp( p, "force_ciphersuite" ) == 0 ) else if( strcmp( p, "force_ciphersuite" ) == 0 )
{ {
opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q ); opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q );
@ -1904,6 +1917,19 @@ reset:
} }
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
{
if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
(const unsigned char *) opt.ecjpake_pw,
strlen( opt.ecjpake_pw ) ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
goto exit;
}
}
#endif
mbedtls_printf( " ok\n" ); mbedtls_printf( " ok\n" );
/* /*

View file

@ -49,6 +49,7 @@
#include "mbedtls/xtea.h" #include "mbedtls/xtea.h"
#include "mbedtls/pkcs5.h" #include "mbedtls/pkcs5.h"
#include "mbedtls/ecp.h" #include "mbedtls/ecp.h"
#include "mbedtls/ecjpake.h"
#include "mbedtls/timing.h" #include "mbedtls/timing.h"
#include <stdio.h> #include <stdio.h>
@ -244,6 +245,11 @@ int main( int argc, char *argv[] )
return( ret ); return( ret );
#endif #endif
#if defined(MBEDTLS_ECJPAKE_C)
if( ( ret = mbedtls_ecjpake_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_DHM_C) #if defined(MBEDTLS_DHM_C)
if( ( ret = mbedtls_dhm_self_test( v ) ) != 0 ) if( ( ret = mbedtls_dhm_self_test( v ) ) != 0 )
return( ret ); return( ret );

52
scripts/footprint.sh Executable file
View file

@ -0,0 +1,52 @@
#!/bin/sh
set -eu
CONFIG_H='include/mbedtls/config.h'
if [ -r $CONFIG_H ]; then :; else
echo "$CONFIG_H not found" >&2
exit 1
fi
if grep -i cmake Makefile >/dev/null; then
echo "Not compatible with CMake" >&2
exit 1
fi
doit()
{
NAME="$1"
FILE="$2"
echo "$NAME:"
cp $CONFIG_H ${CONFIG_H}.bak
cp "$FILE" include/mbedtls/config.h
{
scripts/config.pl unset MBEDTLS_NET_C || true
scripts/config.pl unset MBEDTLS_TIMING_C || true
scripts/config.pl unset MBEDTLS_FS_IO || true
} >/dev/null 2>&1
CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld \
CFLAGS='-Wa,--noexecstack -Os -march=armv7-m -mthumb' \
make clean lib >/dev/null
OUT="size-${NAME}.txt"
arm-none-eabi-size -t library/libmbed*.a > "$OUT"
head -n1 "$OUT"
tail -n1 "$OUT"
cp ${CONFIG_H}.bak $CONFIG_H
}
# creates the yotta config
yotta/create-module.sh >/dev/null
doit default include/mbedtls/config.h.bak
doit yotta yotta/module/mbedtls/config.h
doit thread configs/config-thread.h
doit ecc configs/config-suite-b.h
doit psk configs/config-ccm-psk-tls1_2.h

View file

@ -60,9 +60,10 @@ add_test_suite(ctr_drbg)
add_test_suite(debug) add_test_suite(debug)
add_test_suite(des) add_test_suite(des)
add_test_suite(dhm) add_test_suite(dhm)
add_test_suite(ecp)
add_test_suite(ecdh) add_test_suite(ecdh)
add_test_suite(ecdsa) add_test_suite(ecdsa)
add_test_suite(ecjpake)
add_test_suite(ecp)
add_test_suite(entropy) add_test_suite(entropy)
add_test_suite(error) add_test_suite(error)
add_test_suite(gcm gcm.aes128_en) add_test_suite(gcm gcm.aes128_en)

View file

@ -60,7 +60,7 @@ APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \
test_suite_ctr_drbg$(EXEXT) test_suite_debug$(EXEXT) \ test_suite_ctr_drbg$(EXEXT) test_suite_debug$(EXEXT) \
test_suite_des$(EXEXT) test_suite_dhm$(EXEXT) \ test_suite_des$(EXEXT) test_suite_dhm$(EXEXT) \
test_suite_ecdh$(EXEXT) test_suite_ecdsa$(EXEXT) \ test_suite_ecdh$(EXEXT) test_suite_ecdsa$(EXEXT) \
test_suite_ecp$(EXEXT) \ test_suite_ecjpake$(EXEXT) test_suite_ecp$(EXEXT) \
test_suite_error$(EXEXT) test_suite_entropy$(EXEXT) \ test_suite_error$(EXEXT) test_suite_entropy$(EXEXT) \
test_suite_gcm.aes128_de$(EXEXT) \ test_suite_gcm.aes128_de$(EXEXT) \
test_suite_gcm.aes192_de$(EXEXT) \ test_suite_gcm.aes192_de$(EXEXT) \
@ -292,6 +292,10 @@ test_suite_ecdsa$(EXEXT): test_suite_ecdsa.c $(DEP)
echo " CC $<" echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
test_suite_ecjpake$(EXEXT): test_suite_ecjpake.c $(DEP)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
test_suite_ecp$(EXEXT): test_suite_ecp.c $(DEP) test_suite_ecp$(EXEXT): test_suite_ecp.c $(DEP)
echo " CC $<" echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@

View file

@ -23,6 +23,8 @@ sub abort {
for my $curve (@curves) { for my $curve (@curves) {
system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n"; system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
# depends on a specific curve. Also, ignore error if it wasn't enabled
system( "scripts/config.pl unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED" );
system( "make clean" ) and die; system( "make clean" ) and die;
print "\n******************************************\n"; print "\n******************************************\n";

View file

@ -21,12 +21,12 @@ for my $suite (@suites)
my $result = `$prefix$suite`; my $result = `$prefix$suite`;
if( $result =~ /PASSED/ ) { if( $result =~ /PASSED/ ) {
print "PASS\n"; print "PASS\n";
my ($tests, $skipped) = $result =~ /([0-9]*) tests.*?([0-9]*) skipped/;
$total_tests_run += $tests - $skipped;
} else { } else {
$failed_suites++; $failed_suites++;
print "FAIL\n"; print "FAIL\n";
} }
my ($tests, $skipped) = $result =~ /([0-9]*) tests.*?([0-9]*) skipped/;
$total_tests_run += $tests - $skipped;
} }
print "-" x 72, "\n"; print "-" x 72, "\n";

View file

@ -11,14 +11,20 @@ use warnings;
use strict; use strict;
my %configs = ( my %configs = (
'config-mini-tls1_1.h' 'config-mini-tls1_1.h' => {
=> '-m tls1_1 -f \'^DES-CBC3-SHA$\|^TLS-RSA-WITH-3DES-EDE-CBC-SHA$\'', 'compat' => '-m tls1_1 -f \'^DES-CBC3-SHA$\|^TLS-RSA-WITH-3DES-EDE-CBC-SHA$\'',
'config-suite-b.h' },
=> "-m tls1_2 -f 'ECDHE-ECDSA.*AES.*GCM' -p mbedTLS", 'config-suite-b.h' => {
'config-picocoin.h' 'compat' => "-m tls1_2 -f 'ECDHE-ECDSA.*AES.*GCM' -p mbedTLS",
=> 0, },
'config-ccm-psk-tls1_2.h' 'config-picocoin.h' => {
=> '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'', },
'config-ccm-psk-tls1_2.h' => {
'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
},
'config-thread.h' => {
'opt' => '-f ECJPAKE.*nolog',
},
); );
# If no config-name is provided, use all known configs. # If no config-name is provided, use all known configs.
@ -46,7 +52,7 @@ sub abort {
die $_[0]; die $_[0];
} }
while( my ($conf, $args) = each %configs ) { while( my ($conf, $data) = each %configs ) {
system( "cp $config_h.bak $config_h" ) and die; system( "cp $config_h.bak $config_h" ) and die;
system( "make clean" ) and die; system( "make clean" ) and die;
@ -60,16 +66,29 @@ while( my ($conf, $args) = each %configs ) {
system( "make CFLAGS='-Os -Werror'" ) and abort "Failed to build: $conf\n"; system( "make CFLAGS='-Os -Werror'" ) and abort "Failed to build: $conf\n";
system( "make test" ) and abort "Failed test suite: $conf\n"; system( "make test" ) and abort "Failed test suite: $conf\n";
if( $args ) my $compat = $data->{'compat'};
if( $compat )
{ {
print "\nrunning compat.sh $args\n"; print "\nrunning compat.sh $compat\n";
system( "tests/compat.sh $args" ) system( "tests/compat.sh $compat" )
and abort "Failed compat.sh: $conf\n"; and abort "Failed compat.sh: $conf\n";
} }
else else
{ {
print "\nskipping compat.sh\n"; print "\nskipping compat.sh\n";
} }
my $opt = $data->{'opt'};
if( $opt )
{
print "\nrunning ssl-opt.sh $opt\n";
system( "tests/ssl-opt.sh $opt" )
and abort "Failed ssl-opt.sh: $conf\n";
}
else
{
print "\nskipping ssl-opt.sh\n";
}
} }
system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n"; system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";

View file

@ -2499,6 +2499,98 @@ run_test "PSK callback: wrong key" \
-S "SSL - Unknown identity received" \ -S "SSL - Unknown identity received" \
-s "SSL - Verification of the message MAC failed" -s "SSL - Verification of the message MAC failed"
# Tests for EC J-PAKE
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: client not configured" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3" \
0 \
-C "add ciphersuite: c0ff" \
-C "adding ecjpake_kkpp extension" \
-S "found ecjpake kkpp extension" \
-S "skip ecjpake kkpp extension" \
-S "ciphersuite mismatch: ecjpake not configured" \
-S "server hello, ecjpake kkpp extension" \
-C "found ecjpake_kkpp extension" \
-S "None of the common ciphersuites is usable"
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: server not configured" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3 ecjpake_pw=bla \
force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
1 \
-c "add ciphersuite: c0ff" \
-c "adding ecjpake_kkpp extension" \
-s "found ecjpake kkpp extension" \
-s "skip ecjpake kkpp extension" \
-s "ciphersuite mismatch: ecjpake not configured" \
-S "server hello, ecjpake kkpp extension" \
-C "found ecjpake_kkpp extension" \
-s "None of the common ciphersuites is usable"
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: working, TLS" \
"$P_SRV debug_level=3 ecjpake_pw=bla" \
"$P_CLI debug_level=3 ecjpake_pw=bla \
force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
0 \
-c "add ciphersuite: c0ff" \
-c "adding ecjpake_kkpp extension" \
-C "re-using cached ecjpake parameters" \
-s "found ecjpake kkpp extension" \
-S "skip ecjpake kkpp extension" \
-S "ciphersuite mismatch: ecjpake not configured" \
-s "server hello, ecjpake kkpp extension" \
-c "found ecjpake_kkpp extension" \
-S "None of the common ciphersuites is usable" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: password mismatch, TLS" \
"$P_SRV debug_level=3 ecjpake_pw=bla" \
"$P_CLI debug_level=3 ecjpake_pw=bad \
force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
1 \
-C "re-using cached ecjpake parameters" \
-s "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: working, DTLS" \
"$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
"$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
0 \
-c "re-using cached ecjpake parameters" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: working, DTLS, no cookie" \
"$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla cookies=0" \
"$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
0 \
-C "re-using cached ecjpake parameters" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: password mismatch, DTLS" \
"$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
"$P_CLI debug_level=3 dtls=1 ecjpake_pw=bad \
force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
1 \
-c "re-using cached ecjpake parameters" \
-s "SSL - Verification of the message MAC failed"
# for tests with configs/config-thread.h
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
run_test "ECJPAKE: working, DTLS, nolog" \
"$P_SRV dtls=1 ecjpake_pw=bla" \
"$P_CLI dtls=1 ecjpake_pw=bla \
force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
0
# Tests for ciphersuites per version # Tests for ciphersuites per version
run_test "Per-version suites: SSL3" \ run_test "Per-version suites: SSL3" \

View file

@ -0,0 +1,230 @@
ECJPAKE selftest
ecjpake_selftest:
ECJPAKE round one: client, valid
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d905193735144104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb12":0
ECJPAKE round one: server, valid
read_round_one:MBEDTLS_ECJPAKE_SERVER:"4104accf0106ef858fa2d919331346805a78b58bbad0b844e5c7892879146187dd2666ada781bb7f111372251a8910621f634df128ac48e381fd6ef9060731f694a441041dd0bd5d4566c9bed9ce7de701b5e82e08e84b730466018ab903c79eb982172236c0c1728ae4bf73610d34de44246ef3d9c05a2236fb66a6583d7449308babce2072fe16662992e9235c25002f11b15087b82738e03c945bf7a2995dda1e98345841047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b4104a49558d32ed1ebfc1816af4ff09b55fcb4ca47b2a02d1e7caf1179ea3fe1395b22b861964016fabaf72c975695d93d4df0e5197fe9f040634ed59764937787be20bc4deebbf9b8d60a335f046ca3aa941e45864c7cadef9cf75b3d8b010e443ef0":0
ECJPAKE round one: role mismatch
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104accf0106ef858fa2d919331346805a78b58bbad0b844e5c7892879146187dd2666ada781bb7f111372251a8910621f634df128ac48e381fd6ef9060731f694a441041dd0bd5d4566c9bed9ce7de701b5e82e08e84b730466018ab903c79eb982172236c0c1728ae4bf73610d34de44246ef3d9c05a2236fb66a6583d7449308babce2072fe16662992e9235c25002f11b15087b82738e03c945bf7a2995dda1e98345841047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b4104a49558d32ed1ebfc1816af4ff09b55fcb4ca47b2a02d1e7caf1179ea3fe1395b22b861964016fabaf72c975695d93d4df0e5197fe9f040634ed59764937787be20bc4deebbf9b8d60a335f046ca3aa941e45864c7cadef9cf75b3d8b010e443ef0":MBEDTLS_ERR_ECP_VERIFY_FAILED
ECJPAKE round one: trailing byte
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d905193735144104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1200":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: no data
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: length of first point too small
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: length of first point too big
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"01":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: no point data
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"0104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: first point is zero
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"0100":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round one: KKP1: unknown first point format
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41057ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round one: KKP1: nothing after first point
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: length of second point too small
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: length of second point too big
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b01":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: no second point data
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b0104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: unknow second point format
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410509f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb516":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round one: KKP1: nothing after second point
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb516":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: zero-length r
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51600":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round one: KKP1: no data for r
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51601":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP1: corrupted r
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d90519373515":MBEDTLS_ERR_ECP_VERIFY_FAILED
ECJPAKE round one: KKP1: X not on the curve
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2a410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d90519373514":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round one: KKP2: no data
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb12":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: length of first point too small
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1200":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: length of first point too big
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1201":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: no point data
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb120104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: first point is zero
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb120100":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round one: KKP2: unknown first point format
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241057ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round one: KKP2: nothing after first point
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: length of second point too small
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: length of second point too big
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b01":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: no second point data
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b0104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: unknow second point format
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410509f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb516":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round one: KKP2: nothing after second point
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb516":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: zero-length r
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51600":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round one: KKP2: no data for r
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51601":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round one: KKP2: corrupted r
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d90519373515":MBEDTLS_ERR_ECP_VERIFY_FAILED
ECJPAKE round one: KKP2: X not on the curve
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"4104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb1241047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2a410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d90519373514":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round two client: valid
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a641045516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c820ff724a9a70b88cb86f20b434c6865aa1cd7906dd7c9bce3525f508276f26836c":0
ECJPAKE round two client: trailing byte
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a641045516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c820ff724a9a70b88cb86f20b434c6865aa1cd7906dd7c9bce3525f508276f26836c00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: no data
read_round_two_cli:"":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: ECParams too short
read_round_two_cli:"0300":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: ECParams not named curve
read_round_two_cli:"010017":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: ECParams wrong curve
read_round_two_cli:"030016":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round two client: no data after ECParams
read_round_two_cli:"030017":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: length of first point too small
read_round_two_cli:"03001700":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: length of first point too big
read_round_two_cli:"03001701":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: no first point data
read_round_two_cli:"0300170104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: first point is zero
read_round_two_cli:"0300170100":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round two client: unknown first point format
read_round_two_cli:"03001741050fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a6":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round two client: nothing after first point
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a6":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: length of second point too small
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a600":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: length of second point too big
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a601":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: no second point data
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a60104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: unknown second point format
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a641055516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c8":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round two client: nothing after second point
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a641045516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c8":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: zero-length r
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a641045516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c800":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round two client: no data for r
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a641045516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c801":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two client: corrupted r
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a641045516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c820ff724a9a70b88cb86f20b434c6865aa1cd7906dd7c9bce3525f508276f26836d":MBEDTLS_ERR_ECP_VERIFY_FAILED
ECJPAKE round two client: X not on the curve
read_round_two_cli:"03001741040fb22b1d5d1123e0ef9feb9d8a2e590a1f4d7ced2c2b06586e8f2a16d4eb2fda4328a20b07d8fd667654ca18c54e32a333a0845451e926ee8804fd7af0aaa7a741045516ea3e54a0d5d8b2ce786b38d383370029a5dbe4459c9dd601b408a24ae6465c8ac905b9eb03b5d3691c139ef83f1cd4200f6c9cd4ec392218a59ed243d3c820ff724a9a70b88cb86f20b434c6865aa1cd7906dd7c9bce3525f508276f26836c":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round two server: valid
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d200f011f19483535a6e89a580c9b0003baf21462ece91a82cc38dbdcae60d9c54c":0
ECJPAKE round two server: trailing byte
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d200f011f19483535a6e89a580c9b0003baf21462ece91a82cc38dbdcae60d9c54c00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: no data
read_round_two_srv:"":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: length of forst point too small
read_round_two_srv:"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: length of first point too big
read_round_two_srv:"01":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: no first point data
read_round_two_srv:"0104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: first point is zero
read_round_two_srv:"0100":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round two server: unknown first point format
read_round_two_srv:"410569d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round two server: nothing after first point
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: length of second point too small
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: length of second point too big
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee01":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: no second point data
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee0104":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: unknown second point format
read_round_two_srv:"410569d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
ECJPAKE round two server: nothing after second point
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: zero-length r
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d00":MBEDTLS_ERR_ECP_INVALID_KEY
ECJPAKE round two server: no data for r
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d20":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECJPAKE round two server: corrupted r
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ee4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d200f011f19483535a6e89a580c9b0003baf21462ece91a82cc38dbdcae60d9c54d":MBEDTLS_ERR_ECP_VERIFY_FAILED
ECJPAKE round two server: X not on curve
read_round_two_srv:"410469d54ee85e90ce3f1246742de507e939e81d1dc1c5cb988b58c310c9fdd9524d93720b45541c83ee8841191da7ced86e3312d43623c1d63e74989aba4affd1ef4104077e8c31e20e6bedb760c13593e69f15be85c27d68cd09ccb8c4183608917c5c3d409fac39fefee82f7292d36f0d23e055913f45a52b85dd8a2052e9e129bb4d200f011f19483535a6e89a580c9b0003baf21462ece91a82cc38dbdcae60d9c54c":MBEDTLS_ERR_ECP_INVALID_KEY

View file

@ -0,0 +1,190 @@
/* BEGIN_HEADER */
#include "mbedtls/ecjpake.h"
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C)
static const unsigned char ecjpake_test_x1[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
};
static const unsigned char ecjpake_test_x2[] = {
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
};
static const unsigned char ecjpake_test_x3[] = {
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
};
static const unsigned char ecjpake_test_x4[] = {
0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
};
static const unsigned char ecjpake_test_X1[] = {
0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, 0x33,
0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, 0xe5,
0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, 0xa7,
0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, 0x1f,
0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, 0x06,
0x07, 0x31, 0xf6, 0x94, 0xa4
};
static const unsigned char ecjpake_test_X2[] = {
0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7,
0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40,
0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79,
0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1,
0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3,
0x2b, 0xb0, 0x13, 0xbb, 0x2b
};
static const unsigned char ecjpake_test_X3[] = {
0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7,
0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40,
0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79,
0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1,
0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3,
0x2b, 0xb0, 0x13, 0xbb, 0x2b
};
static const unsigned char ecjpake_test_X4[] = {
0x04, 0x19, 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79,
0xee, 0x0f, 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf,
0x70, 0xf8, 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb,
0xfe, 0xc7, 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f,
0xc4, 0xea, 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4,
0x1a, 0xc5, 0x6a, 0x56, 0x12
};
/* Load my private and public keys, and peer's public keys */
static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
const unsigned char *xm1, size_t len_xm1,
const unsigned char *xm2, size_t len_xm2,
const unsigned char *Xm1, size_t len_Xm1,
const unsigned char *Xm2, size_t len_Xm2,
const unsigned char *Xp1, size_t len_Xp1,
const unsigned char *Xp2, size_t len_Xp2 )
{
int ret;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len_xm1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len_xm2 ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ctx->grp,
&ctx->Xm1, Xm1, len_Xm1 ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ctx->grp,
&ctx->Xm2, Xm2, len_Xm2 ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ctx->grp,
&ctx->Xp1, Xp1, len_Xp1 ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ctx->grp,
&ctx->Xp2, Xp2, len_Xp2 ) );
cleanup:
return( ret );
}
#define ADD_SIZE( x ) x, sizeof( x )
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_ECJPAKE_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void ecjpake_selftest()
{
TEST_ASSERT( mbedtls_ecjpake_self_test( 0 ) == 0 );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
void read_round_one( int role, char *data, int ref_ret )
{
mbedtls_ecjpake_context ctx;
const unsigned char pw[] = {};
unsigned char *msg;
size_t len;
mbedtls_ecjpake_init( &ctx );
msg = unhexify_alloc( data, &len );
TEST_ASSERT( msg != NULL );
TEST_ASSERT( mbedtls_ecjpake_setup( &ctx, role,
MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, pw, 0 ) == 0 );
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &ctx, msg, len ) == ref_ret );
exit:
mbedtls_ecjpake_free( &ctx );
mbedtls_free( msg );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
void read_round_two_cli( char *data, int ref_ret )
{
mbedtls_ecjpake_context ctx;
const unsigned char pw[] = {};
unsigned char *msg;
size_t len;
mbedtls_ecjpake_init( &ctx );
msg = unhexify_alloc( data, &len );
TEST_ASSERT( msg != NULL );
TEST_ASSERT( mbedtls_ecjpake_setup( &ctx, MBEDTLS_ECJPAKE_CLIENT,
MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, pw, 0 ) == 0 );
TEST_ASSERT( ecjpake_test_load( &ctx,
ADD_SIZE( ecjpake_test_x1 ), ADD_SIZE( ecjpake_test_x2 ),
ADD_SIZE( ecjpake_test_X1 ), ADD_SIZE( ecjpake_test_X2 ),
ADD_SIZE( ecjpake_test_X3 ), ADD_SIZE( ecjpake_test_X4 ) )
== 0 );
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &ctx, msg, len ) == ref_ret );
exit:
mbedtls_ecjpake_free( &ctx );
mbedtls_free( msg );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
void read_round_two_srv( char *data, int ref_ret )
{
mbedtls_ecjpake_context ctx;
const unsigned char pw[] = {};
unsigned char *msg;
size_t len;
mbedtls_ecjpake_init( &ctx );
msg = unhexify_alloc( data, &len );
TEST_ASSERT( msg != NULL );
TEST_ASSERT( mbedtls_ecjpake_setup( &ctx, MBEDTLS_ECJPAKE_SERVER,
MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, pw, 0 ) == 0 );
TEST_ASSERT( ecjpake_test_load( &ctx,
ADD_SIZE( ecjpake_test_x3 ), ADD_SIZE( ecjpake_test_x4 ),
ADD_SIZE( ecjpake_test_X3 ), ADD_SIZE( ecjpake_test_X4 ),
ADD_SIZE( ecjpake_test_X1 ), ADD_SIZE( ecjpake_test_X2 ) )
== 0 );
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &ctx, msg, len ) == ref_ret );
exit:
mbedtls_ecjpake_free( &ctx );
mbedtls_free( msg );
}
/* END_CASE */

View file

@ -673,7 +673,7 @@ x509_verify:"data_files/server6-ss-child.crt":"data_files/server5-selfsigned.crt
X509 Certificate verification #75 (encoding mismatch) X509 Certificate verification #75 (encoding mismatch)
depends_on:MBEDTLS_PEM_PARSE_C depends_on:MBEDTLS_PEM_PARSE_C
x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_BAD_KEY:"NULL" x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl.pem":"NULL":0:0:"NULL"
X509 Certificate verification #76 (multiple CRLs, not revoked) X509 Certificate verification #76 (multiple CRLs, not revoked)
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
@ -697,7 +697,7 @@ x509_verify:"data_files/server1.crt":"data_files/test-ca_cat12.crt":"data_files/
X509 Certificate verification #81 (multiple CRLs, none relevant) X509 Certificate verification #81 (multiple CRLs, none relevant)
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_BAD_KEY:"NULL" x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":0:0:"NULL"
X509 Certificate verification callback: trusted EE cert X509 Certificate verification callback: trusted EE cert
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED

View file

@ -6,6 +6,19 @@
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#include "mbedtls/base64.h" #include "mbedtls/base64.h"
const mbedtls_x509_crt_profile compat_profile =
{
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
0xFFFFFFF, /* Any PK alg */
0xFFFFFFF, /* Any curve */
1024,
};
int verify_none( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags ) int verify_none( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
{ {
((void) data); ((void) data);
@ -191,7 +204,7 @@ void x509_verify( char *crt_file, char *ca_file, char *crl_file,
TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 ); TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == 0 ); TEST_ASSERT( mbedtls_x509_crl_parse_file( &crl, crl_file ) == 0 );
res = mbedtls_x509_crt_verify( &crt, &ca, &crl, cn_name, &flags, f_vrfy, NULL ); res = mbedtls_x509_crt_verify_with_profile( &crt, &ca, &crl, &compat_profile, cn_name, &flags, f_vrfy, NULL );
TEST_ASSERT( res == ( result ) ); TEST_ASSERT( res == ( result ) );
TEST_ASSERT( flags == (uint32_t)( flags_result ) ); TEST_ASSERT( flags == (uint32_t)( flags_result ) );

View file

@ -1,41 +1,88 @@
# mbed TLS # mbed TLS
mbed TLS (formerly known as PolarSSL) makes it trivially easy for developers to include cryptographic and SSL/TLS capabilities in their embedded products, with a minimal code footprint. It offers an SSL library with an intuitive API and readable source code. mbed TLS makes it trivially easy for developers to include cryptographic and SSL/TLS capabilities in their embedded products, with a minimal code footprint. It offers an SSL library with an intuitive API and readable source code.
The Beta release of mbed TLS integrates the mbed TLS library into mbed OS, mbed SDK and yotta. This is a preview release intended for evaluation only and is **not recommended for deployment**. It currently implements no secure source of random numbers, weakening its security. **Note:** The current release is beta, and implements no secure source of random numbers, weakening its security.
Currently the only supported yotta targets are:
- `frdm-k64f-gcc`
- `frdm-k64f-armcc`
- `x86-linux-native`
- `x86-osx-native`
## Sample programs ## Sample programs
This release includes the following examples: This release includes the following examples:
1. [**TLS client:**](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-tls-client) found in `test/example-tls-client`. Downloads a test file from an HTTPS server and looks for a specific string in that file. 1. [**Self test:**](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-selftest) Tests different basic functions in the mbed TLS library.
2. [**Self test:**](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-selftest) found in `test/example-selftest`. Tests different basic functions in the mbed TLS library. 2. [**Benchmark:**](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-benchmark) Measures the time taken to perform basic cryptographic functions used in the library.
3. [**Benchmark:**](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-benchmark) found in `test/example-benchmark`. Measures the time taken to perform basic cryptographic functions used in the library. 3. [**Hashing:**](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-hashing) Demonstrates the various APIs for computing hashes of data (also known as message digests) with SHA-256.
These examples are integrated as yotta tests, so that they are built automatically when you build mbed TLS. You'll find more examples in the various `test/example-*` directories. 4. [**Authenticated encryption:**](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-authcrypt) Demonstrates usage of the Cipher API for encrypting and authenticating data with AES-CCM.
## Running mbed TLS These examples are integrated as yotta tests, so that they are built automatically when you build mbed TLS. Each of them comes with complete usage instructions as a Readme file in the repository.
To build and run the example, please follow the instructions in the [TLS client example](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/example-tls-client) directory. These include a list of prerequisites and an explanation of building mbed TLS with yotta. ## Performing TLS and DTLS connections
A high-level API for performing TLS and DTLS connections with mbed TLS in mbed OS is provided in a separate yotta module: [mbed-tls-sockets](https://github.com/ARMmbed/mbed-tls-sockets). We recommend this API for TLS and DTLS connections. It is very similar to the API provided by the [sockets](https://github.com/ARMmbed/sockets) module for unencrypted TCP and UDP connections.
The `mbed-tls-sockets` module includes a complete [example TLS client](https://github.com/ARMmbed/mbed-tls-sockets/blob/master/test/tls-client/main.cpp) with [usage instructions](https://github.com/ARMmbed/mbed-tls-sockets/blob/master/test/tls-client/README.md).
## Configuring mbed TLS features ## Configuring mbed TLS features
mbed TLS makes it easy to disable any feature during compilation that isn't required for a particular project. The default configuration enables all modern and widely-used features, which should meet the needs of new projects, and disables all features that are older or less common, to minimize the code footprint. mbed TLS makes it easy to disable any feature during compilation, if that feature isn't required for a particular project. The default configuration enables all modern and widely-used features, which should meet the needs of new projects, and disables all features that are older or less common, to minimize the code footprint.
The list of available compilation flags is presented in the fully documented [config.h file](https://github.com/ARMmbed/mbedtls/blob/development/include/mbedtls/config.h), present in the `mbedtls` directory of the yotta module. The list of available compilation flags is available in the fully documented [config.h file](https://github.com/ARMmbed/mbedtls/blob/development/include/mbedtls/config.h).
If you need to adjust those flags, you can provide your own configuration file with suitable `#define` and `#undef` statements. These will be included between the default definitions and the sanity checks. Your configuration file should be in your application's `include` directory, and can be named freely; you just need to let mbed TLS know the file's name. To do that, use yotta's [configuration system](http://docs.yottabuild.org/reference/config.html). The file's name should be in your `config.json` file, under mbedtls, as the key `user-config-file`. For example: If you need to adjust those flags, you can provide your own configuration-adjustment file with suitable `#define` and `#undef` statements. These will be included between the default definitions and the sanity checks. Your configuration file should be in your application's include directory, and can be named freely; you just need to let mbed TLS know the file's name. To do that, use yotta's [configuration system](http://docs.yottabuild.org/reference/config.html). The file's name should be in your `config.json` file, under mbedtls, as the key `user-config-file`.
For example, in an application called `myapp`, if you want to enable the EC J-PAKE key exchange and disable the CBC cipher mode, you can create a file named `mbedtls-config-changes.h` in the `myapp` directory containing the following lines:
#define MBEDTLS_ECJPAKE_C
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
#undef MBEDTLS_CIPHER_MODE_CBC
And then create a file named `config.json` at the root of your application with the following contents:
{ {
"mbedtls": { "mbedtls": {
"user-config-file": "\"myapp/my_mbedtls_config_changes.h\"" "user-config-file": "\"myapp/mbedtls-config-changes.h\""
} }
} }
Please note: you need to provide the exact name that will be used in the `#include` directive, including the `<>` or quotes around the name. Please note: you need to provide the exact name that will be used in the `#include` directive, including the `<>` or quotes around the name.
## Getting mbed TLS from GitHub
Like most components of mbed OS, mbed TLS is developed in the open and its source can be found on GitHub: [ARMmbed/mbedtls](https://github.com/ARMmbed/mbedtls). Unlike most other mbed OS components, however, you cannot just clone the repository and run `yotta build` from its root. This is because mbed TLS also exists as an independent component, so its repository includes things that are not relevant for mbed OS, as well as other build systems.
The way to use mbed TLS from a clone of the GitHub repository is to run the following commands from the root of a checkout:
yotta/create-module.sh
cd yotta/module
You can then run any yotta command you would normally run, such as `yotta build` or `yotta link`.
## Differences between the standalone and mbed OS editions
While the two editions share the same code base, there are still a number of differences, mainly in configuration and integration. You should keep in mind those differences when reading some articles in our [knowledge base](https://tls.mbed.org/kb), as currently all the articles are about the standalone edition.
* The mbed OS edition has a smaller set of features enabled by default in `config.h`, in order to reduce footprint. While the default configuration of the standalone edition puts more emphasize on maintaining interoperability with old peers, the mbed OS edition only enables the most modern ciphers and the latest version of (D)TLS.
* The following components of mbed TLS are disabled in the mbed OS edition: `net.c` and `timing.c`. This is because mbed OS includes their equivalents.
* The mbed OS edition comes with a fully integrated API for (D)TLS connections in a companion module: [mbed-tls-sockets](https://github.com/ARMmbed/mbed-tls-sockets). See "Performing TLS and DTLS connections" above.
## Other resources
The [mbed TLS website](https://tls.mbed.org) contains many other useful
resources for the developer, such as [developer
documentation](https://tls.mbed.org/dev-corner), [knowledgebase
articles](https://tls.mbed.org/kb), and a [support forum](https://tls.mbed.org/discussions).
## Contributing ## Contributing
We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions: We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions:
@ -52,4 +99,5 @@ To contribute, please:
* Write a test that shows that the bug was fixed or that the feature works as expected. * Write a test that shows that the bug was fixed or that the feature works as expected.
* Send a pull request and bug us until it gets merged and published. We will include your name in the ChangeLog :) * Send a pull request and bug us until it gets merged and published. We will include your name in the ChangeLog.

View file

@ -171,7 +171,7 @@ static int example(void)
#if defined(TARGET_LIKE_MBED) #if defined(TARGET_LIKE_MBED)
#include "mbed/test_env.h" #include "mbed-drivers/test_env.h"
#include "minar/minar.h" #include "minar/minar.h"
static void run() { static void run() {

View file

@ -71,7 +71,7 @@ int main() {
#include "mbedtls/ecdh.h" #include "mbedtls/ecdh.h"
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "mbed.h" #include "mbed-drivers/mbed.h"
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#include "mbedtls/memory_buffer_alloc.h" #include "mbedtls/memory_buffer_alloc.h"
@ -931,7 +931,7 @@ int benchmark( int argc, char *argv[] )
return( 0 ); return( 0 );
} }
#include "mbed/test_env.h" #include "mbed-drivers/test_env.h"
#include "minar/minar.h" #include "minar/minar.h"
static void run() { static void run() {

View file

@ -27,7 +27,7 @@
#include "mbedtls/md.h" /* generic interface */ #include "mbedtls/md.h" /* generic interface */
#if defined(TARGET_LIKE_MBED) #if defined(TARGET_LIKE_MBED)
#include "mbed/mbed.h" #include "mbed-drivers/mbed.h"
#endif #endif
#include <cstdio> #include <cstdio>
@ -151,7 +151,7 @@ int example(void)
#if defined(TARGET_LIKE_MBED) #if defined(TARGET_LIKE_MBED)
#include "mbed/test_env.h" #include "mbed-drivers/test_env.h"
#include "minar/minar.h" #include "minar/minar.h"
static void run() { static void run() {

View file

@ -242,7 +242,7 @@ int selftest( int argc, char *argv[] )
#if defined(TARGET_LIKE_MBED) #if defined(TARGET_LIKE_MBED)
#include "mbed/test_env.h" #include "mbed-drivers/test_env.h"
#include "minar/minar.h" #include "minar/minar.h"
static void run() { static void run() {

View file

@ -1,136 +0,0 @@
# HTTPS File Download Example for TLS Client
This application downloads a file from an HTTPS server (developer.mbed.org) and looks for a specific string in that file.
This example is implemented as a logic class (HelloHTTPS) wrapping a TCP socket and a TLS context. The logic class handles all events, leaving the main loop to just check if the process has finished.
## Pre-requisites
To build and run this example you must have:
* A computer with the following software installed:
* [CMake](http://www.cmake.org/download/).
* [yotta](https://github.com/ARMmbed/yotta). Please note that **yotta has its own set of dependencies**, listed in the [installation instructions](http://armmbed.github.io/yotta/#installing-on-windows).
* [Python](https://www.python.org/downloads/).
* [The ARM GCC toolchain](https://launchpad.net/gcc-arm-embedded).
* A serial terminal emulator (Like screen, pySerial and cu).
* An [FRDM-K64F](http://developer.mbed.org/platforms/FRDM-K64F/) development board, or another board supported by mbed OS (in which case you'll have to substitute frdm-k64f-gcc with the appropriate target in the instructions below).
* A micro-USB cable.
* An Ethernet connection to the internet.
* An Ethernet cable.
* If your OS is Windows, please follow the installation instructions [for the serial port driver](https://developer.mbed.org/handbook/Windows-serial-configuration).
## Getting started
1. Connect the FRDM-K64F to the internet using the Ethernet cable.
2. Connect the FRDM-K64F to the computer with the micro-USB cable, being careful to use the "OpenSDA" connector on the target board.
3. Navigate to the mbedtls directory supplied with your release and open a terminal.
4. Set the yotta target:
```
yotta target frdm-k64f-gcc
```
5. Build mbedtls and the examples. This will take a long time if it is the first time:
```
$ yotta build
```
6. Copy `build/frdm-k64f-gcc/test/mbedtls-test-example-tls-client.bin` to your mbed board and wait until the LED next to the USB port stops blinking.
7. Start the serial terminal emulator and connect to the virtual serial port presented by FRDM-K64F.
Use the following settings:
* 115200 baud (not 9600).
* 8N1.
* No flow control.
8. Press the Reset button on the board.
9. The output in the terminal window should look similar to this:
```
{{timeout;120}}
{{host_test_name;default}}
{{description;mbed TLS example HTTPS client}}
{{test_id;MBEDTLS_EX_HTTPS_CLIENT}}
{{start}}
Client IP Address is 192.168.0.2
Starting DNS lookup for developer.mbed.org
DNS Response Received:
developer.mbed.org: 217.140.101.30
Connecting to 217.140.101.30:443
Connected to 217.140.101.30:443
Starting the TLS handshake...
TLS connection to developer.mbed.org established
Server certificate:
cert. version : 3
serial number : 11:21:4E:4B:13:27:F0:89:21:FB:70:EC:3B:B5:73:5C:FF:B9
issuer name : C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
subject name : C=GB, ST=Cambridgeshire, L=Cambridge, O=ARM Ltd, CN=*.mbed.com
issued on : 2015-03-05 10:31:02
expires on : 2016-03-05 10:31:02
signed using : RSA with SHA-256
RSA key size : 2048 bits
basic constraints : CA=false
subject alt name : *.mbed.com, *.mbed.org, mbed.org, mbed.com
key usage : Digital Signature, Key Encipherment
ext key usage : TLS Web Server Authentication, TLS Web Client Authentication
Certificate verification passed
HTTPS: Received 473 chars from server
HTTPS: Received 200 OK status ... [OK]
HTTPS: Received 'Hello world!' status ... [OK]
HTTPS: Received message:
HTTP/1.1 200 OK
Server: nginx/1.7.10
Date: Tue, 18 Aug 2015 18:34:04 GMT
Content-Type: text/plain
Content-Length: 14
Connection: keep-alive
Last-Modified: Fri, 27 Jul 2012 13:30:34 GMT
Accept-Ranges: bytes
Cache-Control: max-age=36000
Expires: Wed, 19 Aug 2015 04:34:04 GMT
X-Upstream-L3: 172.17.42.1:8080
X-Upstream-L2: developer-sjc-indigo-2-nginx
X-Upstream-L1-next-hop: 217.140.101.86:8001
X-Upstream-L1: developer-sjc-indigo-border-nginx
Hello world!
{{success}}
{{end}}
```
## Debugging the TLS connection
If you are experiencing problems with this example, you should first rule out network issues by making sure the [simple HTTP file downloader example](https://github.com/ARMmbed/mbed-example-network-private/tree/master/test/helloworld-tcpclient) for the TCP module works as expected. If not, please follow the debug instructions for the HTTP file example before proceeding with the instructions below.
To print out more debug information about the TLS connection, edit the file `source/main.cpp` and change the definition of `DEBUG_LEVEL` (near the top of the file) from 0 to a positive number:
* Level 1 only prints non-zero return codes from SSL functions and information about the full certificate chain being verified.
* Level 2 prints more information about internal state updates.
* Level 3 is intermediate.
* Level 4 (the maximum) includes full binary dumps of the packets.
If the TLS connection is failing with an error similar to:
```
mbedtls_ssl_write() failed: -0x2700 (-9984): X509 - Certificate verification failed, e.g. CRL, CA or signature check failed
Failed to fetch /media/uploads/mbed_official/hello.txt from developer.mbed.org:443
```
it probably means you need to update the contents of the `SSL_CA_PEM` constant (this can happen if you modify `HTTPS_SERVER_NAME`, or when `developer.mbed.org` switches to a new CA when updating its certificate).
Another reason for this error may be a proxy providing a different certificate. Proxies can be used in some network configurations or for performing man-in-the-middle attacks. If you choose to ignore this error and proceed with the connection anyway, you can change the definition of `UNSAFE` near the top of the file from 0 to 1. **Warning:** this removes all security against a possible active attacker, therefore use at your own risk, or for debugging only!

View file

@ -1,520 +0,0 @@
/*
* Hello world example of a TLS client: fetch an HTTPS page
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(TARGET_LIKE_MBED)
#include <stdio.h>
int main() {
printf("this program only works on mbed OS\n");
return 0;
}
#else
/** \file main.cpp
* \brief An example TLS Client application
* This application sends an HTTPS request to developer.mbed.org and searches for a string in
* the result.
*
* This example is implemented as a logic class (HelloHTTPS) wrapping a TCP socket.
* The logic class handles all events, leaving the main loop to just check if the process
* has finished.
*/
/* Change to a number between 1 and 4 to debug the TLS connection */
#define DEBUG_LEVEL 0
/* Change to 1 to skip certificate verification (UNSAFE, for debug only!) */
#define UNSAFE 0
#include "mbed.h"
#include "EthernetInterface.h"
#include "mbed-net-sockets/TCPStream.h"
#include "test_env.h"
#include "minar/minar.h"
#include "lwipv4_init.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
#if DEBUG_LEVEL > 0
#include "mbedtls/debug.h"
#endif
namespace {
const char *HTTPS_SERVER_NAME = "developer.mbed.org";
const int HTTPS_SERVER_PORT = 443;
const int RECV_BUFFER_SIZE = 600;
const char HTTPS_PATH[] = "/media/uploads/mbed_official/hello.txt";
const size_t HTTPS_PATH_LEN = sizeof(HTTPS_PATH) - 1;
/* Test related data */
const char *HTTPS_OK_STR = "200 OK";
const char *HTTPS_HELLO_STR = "Hello world!";
/* personalization string for the drbg */
const char *DRBG_PERS = "mbed TLS helloword client";
/* List of trusted root CA certificates
* currently only GlobalSign, the CA for developer.mbed.org
*
* To add more than one root, just concatenate them.
*/
const char SSL_CA_PEM[] =
/* GlobalSign Root R1 SHA1/RSA/2048
* Serial no. 04 00 00 00 00 01 15 4b 5a c3 94 */
"-----BEGIN CERTIFICATE-----\n"
"MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\n"
"A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n"
"b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\n"
"MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\n"
"YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\n"
"aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\n"
"jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\n"
"xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n"
"1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\n"
"snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\n"
"U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n"
"9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\n"
"BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\n"
"AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\n"
"yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n"
"38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\n"
"AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\n"
"DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\n"
"HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n"
"-----END CERTIFICATE-----\n";
}
using namespace mbed::Sockets::v0;
/**
* \brief HelloHTTPS implements the logic for fetching a file from a webserver
* using a TCP socket and parsing the result.
*/
class HelloHTTPS {
public:
/**
* HelloHTTPS Constructor
* Initializes the TCP socket, sets up event handlers and flags.
*
* @param[in] domain The domain name to fetch from
* @param[in] port The port of the HTTPS server
*/
HelloHTTPS(const char * domain, const uint16_t port) :
_stream(SOCKET_STACK_LWIP_IPV4), _domain(domain), _port(port)
{
_error = false;
_gothello = false;
_got200 = false;
_bpos = 0;
_request_sent = 0;
_stream.open(SOCKET_AF_INET4);
mbedtls_entropy_init(&_entropy);
mbedtls_ctr_drbg_init(&_ctr_drbg);
mbedtls_x509_crt_init(&_cacert);
mbedtls_ssl_init(&_ssl);
mbedtls_ssl_config_init(&_ssl_conf);
}
/**
* HelloHTTPS Desctructor
*/
~HelloHTTPS() {
mbedtls_entropy_free(&_entropy);
mbedtls_ctr_drbg_free(&_ctr_drbg);
mbedtls_x509_crt_free(&_cacert);
mbedtls_ssl_free(&_ssl);
mbedtls_ssl_config_free(&_ssl_conf);
}
/**
* Initiate the test.
*
* Starts by clearing test flags, then resolves the address with DNS.
*
* @param[in] path The path of the file to fetch from the HTTPS server
* @return SOCKET_ERROR_NONE on success, or an error code on failure
*/
void startTest(const char *path) {
/* Initialize the flags */
_got200 = false;
_gothello = false;
_error = false;
_disconnected = false;
_request_sent = false;
/* Fill the request buffer */
_bpos = snprintf(_buffer, sizeof(_buffer) - 1, "GET %s HTTP/1.1\nHost: %s\n\n", path, HTTPS_SERVER_NAME);
/*
* Initialize TLS-related stuf.
*/
int ret;
if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy,
(const unsigned char *) DRBG_PERS,
sizeof (DRBG_PERS))) != 0) {
print_mbedtls_error("mbedtls_crt_drbg_init", ret);
_error = true;
return;
}
if ((ret = mbedtls_x509_crt_parse(&_cacert, (const unsigned char *) SSL_CA_PEM,
sizeof (SSL_CA_PEM))) != 0) {
print_mbedtls_error("mbedtls_x509_crt_parse", ret);
_error = true;
return;
}
if ((ret = mbedtls_ssl_config_defaults(&_ssl_conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
_error = true;
return;
}
mbedtls_ssl_conf_ca_chain(&_ssl_conf, &_cacert, NULL);
mbedtls_ssl_conf_rng(&_ssl_conf, mbedtls_ctr_drbg_random, &_ctr_drbg);
#if UNSAFE
mbedtls_ssl_conf_authmode(&_ssl_conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
#endif
#if DEBUG_LEVEL > 0
mbedtls_ssl_conf_verify(&_ssl_conf, my_verify, NULL);
mbedtls_ssl_conf_dbg(&_ssl_conf, my_debug, NULL);
mbedtls_debug_set_threshold(DEBUG_LEVEL);
#endif
if ((ret = mbedtls_ssl_setup(&_ssl, &_ssl_conf)) != 0) {
print_mbedtls_error("mbedtls_ssl_setup", ret);
_error = true;
return;
}
mbedtls_ssl_set_hostname(&_ssl, HTTPS_SERVER_NAME);
mbedtls_ssl_set_bio(&_ssl, static_cast<void *>(&_stream),
ssl_send, ssl_recv, NULL );
/* Connect to the server */
printf("Starting DNS lookup for %s\r\n", _domain);
/* Resolve the domain name: */
socket_error_t err = _stream.resolve(_domain, TCPStream::DNSHandler_t(this, &HelloHTTPS::onDNS));
_stream.error_check(err);
}
/**
* Check if the test has completed.
* @return Returns true if done, false otherwise.
*/
bool done() {
return _error || (_got200 && _gothello);
}
/**
* Check if there was an error
* @return Returns true if there was an error, false otherwise.
*/
bool error() {
return _error;
}
/**
* Closes the TCP socket
*/
void close() {
_stream.close();
while (!_disconnected)
__WFI();
}
protected:
/**
* Helper for pretty-printing mbed TLS error codes
*/
static void print_mbedtls_error(const char *name, int err) {
char buf[128];
mbedtls_strerror(err, buf, sizeof (buf));
printf("%s() failed: -0x%04x (%d): %s\r\n", name, -err, err, buf);
}
#if DEBUG_LEVEL > 0
/**
* Debug callback for mbed TLS
* Just prints on the USB serial port
*/
static void my_debug(void *ctx, int level, const char *file, int line,
const char *str)
{
const char *p, *basename;
(void) ctx;
/* Extract basename from file */
for(p = basename = file; *p != '\0'; p++) {
if(*p == '/' || *p == '\\') {
basename = p + 1;
}
}
printf("%s:%04d: |%d| %s", basename, line, level, str);
}
/**
* Certificate verification callback for mbed TLS
* Here we only use it to display information on each cert in the chain
*/
static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
{
char buf[1024];
(void) data;
printf("\nVerifying certificate at depth %d:\n", depth);
mbedtls_x509_crt_info(buf, sizeof (buf) - 1, " ", crt);
printf("%s", buf);
if (*flags == 0)
printf("No verification issue for this certificate\n");
else
{
mbedtls_x509_crt_verify_info(buf, sizeof (buf), " ! ", *flags);
printf("%s\n", buf);
}
return 0;
}
#endif
/**
* Receive callback for mbed TLS
*/
static int ssl_recv(void *ctx, unsigned char *buf, size_t len) {
TCPStream *stream = static_cast<TCPStream *>(ctx);
socket_error_t err = stream->recv(buf, &len);
if (err == SOCKET_ERROR_NONE) {
return static_cast<int>(len);
} else if (err == SOCKET_ERROR_WOULD_BLOCK) {
return MBEDTLS_ERR_SSL_WANT_READ;
} else {
return -1;
}
}
/**
* Send callback for mbed TLS
*/
static int ssl_send(void *ctx, const unsigned char *buf, size_t len) {
TCPStream *stream = static_cast<TCPStream *>(ctx);
socket_error_t err = stream->send(buf, len);
if (err == SOCKET_ERROR_NONE) {
return static_cast<int>(len);
} else if (err == SOCKET_ERROR_WOULD_BLOCK) {
return MBEDTLS_ERR_SSL_WANT_WRITE;
} else {
return -1;
}
}
void onError(Socket *s, socket_error_t err) {
(void) s;
printf("MBED: Socket Error: %s (%d)\r\n", socket_strerror(err), err);
_stream.close();
_error = true;
MBED_HOSTTEST_RESULT(false);
}
/**
* On Connect handler
* Starts the TLS handshake
*/
void onConnect(TCPStream *s) {
char buf[16];
_remoteAddr.fmtIPv4(buf,sizeof(buf));
printf("Connected to %s:%d\r\n", buf, _port);
s->setOnReadable(TCPStream::ReadableHandler_t(this, &HelloHTTPS::onReceive));
s->setOnDisconnect(TCPStream::DisconnectHandler_t(this, &HelloHTTPS::onDisconnect));
/* Start the handshake, the rest will be done in onReceive() */
printf("Starting the TLS handshake...\r\n");
int ret = mbedtls_ssl_handshake(&_ssl);
if (ret < 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
print_mbedtls_error("mbedtls_ssl_handshake", ret);
onError(s, SOCKET_ERROR_UNKNOWN);
}
return;
}
}
/**
* On Receive handler
* Parses the response from the server, to check for the HTTPS 200 status code and the expected response ("Hello World!")
*/
void onReceive(Socket *s) {
/* Send request if not done yet */
if (!_request_sent) {
int ret = mbedtls_ssl_write(&_ssl, (const unsigned char *) _buffer, _bpos);
if (ret < 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
print_mbedtls_error("mbedtls_ssl_write", ret);
onError(s, SOCKET_ERROR_UNKNOWN);
}
return;
}
/* If we get here, the request was sent */
_request_sent = 1;
/* It also means the handshake is done, time to print info */
printf("TLS connection to %s established\r\n", HTTPS_SERVER_NAME);
{
char buf[1024];
mbedtls_x509_crt_info(buf, sizeof(buf), "\r ",
mbedtls_ssl_get_peer_cert(&_ssl));
printf("Server certificate:\r\n%s\r", buf);
#if defined(UNSAFE)
uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl);
if( flags != 0 )
{
mbedtls_x509_crt_verify_info(buf, sizeof (buf), "\r ! ", flags);
printf("Certificate verification failed:\r\n%s\r\r\n", buf);
}
else
#endif
printf("Certificate verification passed\r\n\r\n");
}
}
/* Read data out of the socket */
int ret = mbedtls_ssl_read(&_ssl, (unsigned char *) _buffer, sizeof(_buffer));
if (ret < 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
print_mbedtls_error("mbedtls_ssl_read", ret);
onError(s, SOCKET_ERROR_UNKNOWN);
}
return;
}
_bpos = static_cast<size_t>(ret);
_buffer[_bpos] = 0;
/* Check each of the flags */
_got200 = _got200 || strstr(_buffer, HTTPS_OK_STR) != NULL;
_gothello = _gothello || strstr(_buffer, HTTPS_HELLO_STR) != NULL;
/* Print status messages */
printf("HTTPS: Received %d chars from server\r\n", _bpos);
printf("HTTPS: Received 200 OK status ... %s\r\n", _got200 ? "[OK]" : "[FAIL]");
printf("HTTPS: Received '%s' status ... %s\r\n", HTTPS_HELLO_STR, _gothello ? "[OK]" : "[FAIL]");
printf("HTTPS: Received message:\r\n\r\n");
printf("%s", _buffer);
_error = !(_got200 && _gothello);
s->close();
}
/**
* On DNS Handler
* Reads the address returned by DNS, then starts the connect process.
*/
void onDNS(Socket *s, struct socket_addr addr, const char *domain) {
/* Check that the result is a valid DNS response */
if (socket_addr_is_any(&addr)) {
/* Could not find DNS entry */
printf("Could not find DNS entry for %s", HTTPS_SERVER_NAME);
onError(s, SOCKET_ERROR_DNS_FAILED);
} else {
/* Start connecting to the remote host */
char buf[16];
_remoteAddr.setAddr(&addr);
_remoteAddr.fmtIPv4(buf,sizeof(buf));
printf("DNS Response Received:\r\n%s: %s\r\n", domain, buf);
printf("Connecting to %s:%d\r\n", buf, _port);
socket_error_t err = _stream.connect(_remoteAddr, _port, TCPStream::ConnectHandler_t(this, &HelloHTTPS::onConnect));
if (err != SOCKET_ERROR_NONE) {
onError(s, err);
}
}
}
void onDisconnect(TCPStream *s) {
s->close();
MBED_HOSTTEST_RESULT(!error());
}
protected:
TCPStream _stream; /**< The TCP Socket */
const char *_domain; /**< The domain name of the HTTPS server */
const uint16_t _port; /**< The HTTPS server port */
char _buffer[RECV_BUFFER_SIZE]; /**< The response buffer */
size_t _bpos; /**< The current offset in the response buffer */
SocketAddr _remoteAddr; /**< The remote address */
volatile bool _got200; /**< Status flag for HTTPS 200 */
volatile bool _gothello; /**< Status flag for finding the test string */
volatile bool _error; /**< Status flag for an error */
volatile bool _disconnected;
volatile bool _request_sent;
mbedtls_entropy_context _entropy;
mbedtls_ctr_drbg_context _ctr_drbg;
mbedtls_x509_crt _cacert;
mbedtls_ssl_context _ssl;
mbedtls_ssl_config _ssl_conf;
};
/**
* The main loop of the HTTPS Hello World test
*/
EthernetInterface eth;
HelloHTTPS *hello;
void app_start(int, char*[]) {
/* The default 9600 bps is too slow to print full TLS debug info and could
* cause the other party to time out. Select a higher baud rate for
* printf(), regardless of debug level for the sake of uniformity. */
Serial pc(USBTX, USBRX);
pc.baud(115200);
MBED_HOSTTEST_TIMEOUT(120);
MBED_HOSTTEST_SELECT(default);
MBED_HOSTTEST_DESCRIPTION(mbed TLS example HTTPS client);
MBED_HOSTTEST_START("MBEDTLS_EX_HTTPS_CLIENT");
/* Initialise with DHCP, connect, and start up the stack */
eth.init();
eth.connect();
lwipv4_socket_init();
hello = new HelloHTTPS(HTTPS_SERVER_NAME, HTTPS_SERVER_PORT);
printf("Client IP Address is %s\r\n", eth.getIPAddress());
mbed::util::FunctionPointer1<void, const char*> fp(hello, &HelloHTTPS::startTest);
minar::Scheduler::postCallback(fp.bind(HTTPS_PATH));
}
#endif /* TARGET_LIKE_MBED */

View file

@ -1,6 +1,6 @@
{ {
"name": "mbedtls", "name": "mbedtls",
"version": "2.1.3", "version": "2.1.4",
"description": "The mbed TLS crypto/SSL/TLS library", "description": "The mbed TLS crypto/SSL/TLS library",
"licenses": [ "licenses": [
{ {
@ -10,9 +10,9 @@
], ],
"dependencies": {}, "dependencies": {},
"targetDependencies": { "targetDependencies": {
"mbed": { "cmsis-core": "~0.2.3" } "mbed": { "cmsis-core": "^1.0.0" }
}, },
"testTargetDependencies": { "testTargetDependencies": {
"mbed": { "sockets": "~0.5.0" } "mbed": { "mbed-drivers": "~0.11.0" }
} }
} }