Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build with only montgomery curves (+ DJB configuration) #2013

2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Bugfix
* Remove redundant else statement, which is not readable, and the positive
path in the if statement results in exiting the funciton. Raised by irwir
in #1776.
* Fix build errors when the only enabled elliptic curves are Montgomery
curves. Raised by signpainter in #941 and by Taiki-San in #1412.

Changes
* Copy headers preserving timestamps when doing a "make install".
Expand Down
111 changes: 111 additions & 0 deletions configs/config-montgomery.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* \file config-montgomery.h
*
* \brief Minimal configuration for TLS with ChaCha/Poly and Curve25519
*/
/*
* Copyright (C) 2018, 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 TLS with ChaCha/Poly and Curve25519
*
* Distinguishing features:
* - no RSA or classic DH, fully based on ECC
* - no NIST curves
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also:

  • no AES (I think that's worth pointing out)
  • currently not usable, while waiting for some level of support of RFC 8422 (using X25519 and X448 in ECDH in TLS).

* See README.txt for usage instructions.
*/

#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H

/* System support */
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME

/* mbed TLS feature support */
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_2

/* mbed TLS modules */
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CHACHA20_C
#define MBEDTLS_CHACHAPOLY_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_NET_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_POLY1305_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C

/* For test certificates */
#define MBEDTLS_BASE64_C
#define MBEDTLS_CERTS_C
#define MBEDTLS_PEM_PARSE_C

/* Save RAM at the expense of ROM */
#define MBEDTLS_AES_ROM_TABLES
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't really make sense in an AES-less config, does it? While it technically doesn't hurt, I think it's confusing, if we assume these config files are not just for testing but also examples for users.


/* 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 RAM at the expense of speed, see ecp.h */
#define MBEDTLS_ECP_WINDOW_SIZE 2
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only applicable to short-Weierstrass curves. Again, not technically relevant, but could be confusing for humans.


/*
* You should adjust this to the exact number of sources you're using: default
* is the "mbedtls_platform_entropy_poll" source, but you may want to add other ones.
* Minimum is 2 for the entropy test suite.
*/
#define MBEDTLS_ENTROPY_MAX_SOURCES 2

/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
#define MBEDTLS_SSL_CIPHERSUITES \
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this one will need more complete support of RFC 8422 (EdDSA), and also support of https://tools.ietf.org/html/draft-ietf-curdle-pkix-10 for the certificate chain if I'm not mistaken (unless of course one only uses explicitly-trusted self-signed certificates, in which case one would be better off using raw public keys, but we don't support that yet).

MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, \
MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256

/*
* Save RAM at the expense of interoperability: do this only if you control
* both ends of the connection! (See coments in "mbedtls/ssl.h".)
* The minimum size here depends on the certificate chain used as well as the
* typical size of records.
*/
// #define MBEDTLS_SSL_MAX_CONTENT_LEN 1024

#include "mbedtls/check_config.h"

#endif /* MBEDTLS_CONFIG_H */
4 changes: 3 additions & 1 deletion include/mbedtls/check_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@
!defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif

Expand Down
5 changes: 5 additions & 0 deletions include/mbedtls/ecp.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* \note In contrast to mbedtls_ecp_mul(), this function does not
* guarantee a constant execution flow and timing.
*
* \note This function is currently only implemented for
* Short Weierstrass groups.
*
* \param grp The ECP group.
* \param R The destination point.
* \param m The integer by which to multiply \p P.
Expand All @@ -618,6 +621,8 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp is not a
* Short Weierstrass group.
*/
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
Expand Down
17 changes: 15 additions & 2 deletions library/ecp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1769,7 +1769,6 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_

return( ret );
}
#endif /* ECP_SHORTWEIERSTRASS */

/*
* R = m * P with shortcuts for m == 1 and m == -1
Expand Down Expand Up @@ -1800,15 +1799,19 @@ static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
cleanup:
return( ret );
}
#endif /* ECP_SHORTWEIERSTRASS */

/*
* Linear combination
* NOT constant-time
* NOT constant-time.
* Only implemented for Short Weierstrass, but unconditionally part of the
* public API.
*/
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
{
#if defined(ECP_SHORTWEIERSTRASS)
int ret;
mbedtls_ecp_point mP;
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
Expand Down Expand Up @@ -1845,6 +1848,16 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_ecp_point_free( &mP );

return( ret );

#else /* ECP_SHORTWEIERSTRASS */
(void) grp;
(void) R;
(void) m;
(void) P;
(void) n;
(void) Q;
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we prefer a run-time error in this case to a link-time error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the function existed and I don't want to remove a function in a minor version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm don't think compatibility considerations apply here, as they would only matter for a non-default configuration that was simply not possible before (and never was). Prior to that change, with only Mongomery curves, you couldn't build ecp.c, so you didn't have that function either. After that change, with only Montgomery curves, you would start having the rest of the module but no that function, which you didn't have anyway. So I think I would prefer compile-time exclusion here.

Note that removing this function at compile-time also means making ECDSA dependent on at least one ECDSA-capable curve (currently, only Short Weierstrass curves) to be defined, because ECDSA uses muladd().

#endif /* ECP_SHORTWEIERSTRASS */
}


Expand Down
19 changes: 19 additions & 0 deletions library/ecp_curves.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,22 @@ static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
};
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */

#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
/* For these curves, we build the group parameters dynamically. */
#define ECP_LOAD_GROUP
#endif

#if defined(ECP_LOAD_GROUP)
/*
* Create an MPI from embedded constants
* (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Expand Down Expand Up @@ -599,6 +615,7 @@ static int ecp_group_load( mbedtls_ecp_group *grp,

return( 0 );
}
#endif /* ECP_LOAD_GROUP */

#if defined(MBEDTLS_ECP_NIST_OPTIM)
/* Forward declarations */
Expand Down Expand Up @@ -640,6 +657,7 @@ static int ecp_mod_p224k1( mbedtls_mpi * );
static int ecp_mod_p256k1( mbedtls_mpi * );
#endif

#if defined(ECP_LOAD_GROUP)
#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
G ## _p, sizeof( G ## _p ), \
G ## _a, sizeof( G ## _a ), \
Expand All @@ -655,6 +673,7 @@ static int ecp_mod_p256k1( mbedtls_mpi * );
G ## _gx, sizeof( G ## _gx ), \
G ## _gy, sizeof( G ## _gy ), \
G ## _n, sizeof( G ## _n ) )
#endif /* ECP_LOAD_GROUP */

#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
/*
Expand Down
53 changes: 47 additions & 6 deletions programs/ssl/ssl_client2.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,22 @@

#if !defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
!defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C)
!defined(MBEDTLS_NET_C)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does Support HMAC_DRBG in the TLS test programs have to do with Build with only montgomery curves? Shouldn't this commit be in a different PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to enable the SSL test programs to at least build in the “DJB-only” configuration. DJB-only means no AES and therefore no CTR_DRBG.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

int main( void )
{
mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
"MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined.\n");
"MBEDTLS_NET_C not defined.\n");
return( 0 );
}
#elif !( defined(MBEDTLS_CTR_DRBG_C) || \
( defined(MBEDTLS_HMAC_DRBG_C) && ( defined(MBEDTLS_SHA256_C) || \
defined(MBEDTLS_SHA512_C) ) ) )
int main( void )
{
mbedtls_printf("MBEDTLS_CTR_DRBG_C and MBEDTLS_HMAC_DRBG_C not defined, "
"or MBEDTLS_HMAC_DRBG_C defined without "
"MBEDTLS_SHA256_C or MBEDTLS_512_C.\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: SHA512

return( 0 );
}
#else
Expand All @@ -53,6 +63,7 @@ int main( void )
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/hmac_drbg.h"
#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/error.h"
Expand Down Expand Up @@ -530,7 +541,11 @@ int main( int argc, char *argv[] )
mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
#endif
mbedtls_entropy_context entropy;
#if defined(MBEDTLS_CTR_DRBG_C)
mbedtls_ctr_drbg_context ctr_drbg;
#else
mbedtls_hmac_drbg_context hmac_drbg;
#endif
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_ssl_session saved_session;
Expand All @@ -553,7 +568,11 @@ int main( int argc, char *argv[] )
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) );
#if defined(MBEDTLS_CTR_DRBG_C)
mbedtls_ctr_drbg_init( &ctr_drbg );
#else
mbedtls_hmac_drbg_init( &hmac_drbg );
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_init( &cacert );
mbedtls_x509_crt_init( &clicert );
Expand Down Expand Up @@ -1165,11 +1184,24 @@ int main( int argc, char *argv[] )
fflush( stdout );

mbedtls_entropy_init( &entropy );
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
&entropy, (const unsigned char *) pers,
strlen( pers ) ) ) != 0 )
#if defined(MBEDTLS_CTR_DRBG_C)
ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
&entropy, (const unsigned char *) pers,
strlen( pers ) );
#else
ret = mbedtls_hmac_drbg_seed( &hmac_drbg,
#if defined(MBEDTLS_SHA256_C)
mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
#else
mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ),
#endif
mbedtls_entropy_func,
&entropy, (const unsigned char *) pers,
strlen( pers ) );
#endif
if( ret != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n",
mbedtls_printf( " failed\n ! mbedtls_xxx_drbg_seed returned -0x%x\n",
-ret );
goto exit;
}
Expand Down Expand Up @@ -1403,7 +1435,12 @@ int main( int argc, char *argv[] )
}
#endif

#if defined(MBEDTLS_CTR_DRBG_C)
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
#else
mbedtls_ssl_conf_rng( &conf, mbedtls_hmac_drbg_random, &hmac_drbg );
#endif

mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );

mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
Expand Down Expand Up @@ -2054,7 +2091,11 @@ int main( int argc, char *argv[] )
mbedtls_ssl_session_free( &saved_session );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
#if defined(MBEDTLS_CTR_DRBG_C)
mbedtls_ctr_drbg_free( &ctr_drbg );
#else
mbedtls_hmac_drbg_free( &hmac_drbg );
#endif
mbedtls_entropy_free( &entropy );

#if defined(_WIN32)
Expand Down
Loading