From a950938ff0d7301cf25da9c7242d6ab3b607462d Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Wed, 2 Feb 2022 23:32:18 -0500 Subject: [PATCH] Add mbedtls_ssl_ticket_rotate for ticket rotation. Signed-off-by: Glenn Strauss --- ChangeLog.d/mbedtls_ssl_ticket_rotate.txt | 2 ++ include/mbedtls/ssl_ticket.h | 39 ++++++++++++++++++++++- library/ssl_ticket.c | 29 +++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.d/mbedtls_ssl_ticket_rotate.txt diff --git a/ChangeLog.d/mbedtls_ssl_ticket_rotate.txt b/ChangeLog.d/mbedtls_ssl_ticket_rotate.txt new file mode 100644 index 0000000000..b843bfd5d5 --- /dev/null +++ b/ChangeLog.d/mbedtls_ssl_ticket_rotate.txt @@ -0,0 +1,2 @@ +Features + * Add mbedtls_ssl_ticket_rotate() for external ticket rotation. diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h index 0f4117d343..4d48806bb1 100644 --- a/include/mbedtls/ssl_ticket.h +++ b/include/mbedtls/ssl_ticket.h @@ -98,7 +98,7 @@ void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ); * supported. Usually that means a 256-bit key. * * \note The lifetime of the keys is twice the lifetime of tickets. - * It is recommended to pick a reasonnable lifetime so as not + * It is recommended to pick a reasonable lifetime so as not * to negate the benefits of forward secrecy. * * \return 0 if successful, @@ -109,6 +109,43 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, mbedtls_cipher_type_t cipher, uint32_t lifetime ); +/** + * \brief Rotate session ticket encryption key to new specified key. + * Provides for external control of session ticket encryption + * key rotation, e.g. for synchronization between different + * machines. If this function is not used, or if not called + * before ticket lifetime expires, then a new session ticket + * encryption key is generated internally in order to avoid + * unbounded session ticket encryption key lifetimes. + * + * \param ctx Context to be set up + * \param name Session ticket encryption key name + * \param nlength Session ticket encryption key name length in bytes + * \param k Session ticket encryption key + * \param klength Session ticket encryption key length in bytes + * \param lifetime Tickets lifetime in seconds + * Recommended value: 86400 (one day). + * + * \note \c name and \c k are recommended to be cryptographically + * random data. + * + * \note \c nlength must match sizeof( ctx->name ) + * + * \note \c klength must be sufficient for use by cipher specified + * to \c mbedtls_ssl_ticket_setup + * + * \note The lifetime of the keys is twice the lifetime of tickets. + * It is recommended to pick a reasonable lifetime so as not + * to negate the benefits of forward secrecy. + * + * \return 0 if successful, + * or a specific MBEDTLS_ERR_XXX error code + */ +int mbedtls_ssl_ticket_rotate( mbedtls_ssl_ticket_context *ctx, + const unsigned char *name, size_t nlength, + const unsigned char *k, size_t klength, + uint32_t lifetime ); + /** * \brief Implementation of the ticket write callback * diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c index e998111d93..e410b6b909 100644 --- a/library/ssl_ticket.c +++ b/library/ssl_ticket.c @@ -121,6 +121,35 @@ static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx ) return( 0 ); } +/* + * Rotate active session ticket encryption key + */ +int mbedtls_ssl_ticket_rotate( mbedtls_ssl_ticket_context *ctx, + const unsigned char *name, size_t nlength, + const unsigned char *k, size_t klength, + uint32_t lifetime ) +{ + const unsigned char idx = 1 - ctx->active; + mbedtls_ssl_ticket_key * const key = ctx->keys + idx; + const int bitlen = mbedtls_cipher_get_key_bitlen( &key->ctx ); + int ret; + if( nlength < TICKET_KEY_NAME_BYTES || klength * 8 < (size_t)bitlen ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* With GCM and CCM, same context can encrypt & decrypt */ + ret = mbedtls_cipher_setkey( &key->ctx, k, bitlen, MBEDTLS_ENCRYPT ); + if( ret != 0 ) + return( ret ); + + ctx->active = idx; + ctx->ticket_lifetime = lifetime; + memcpy( key->name, name, TICKET_KEY_NAME_BYTES ); +#if defined(MBEDTLS_HAVE_TIME) + key->generation_time = (uint32_t) mbedtls_time( NULL ); +#endif + return 0; +} + /* * Setup context for actual use */