mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-10-30 19:20:40 -04:00 
			
		
		
		
	Add helper function for calculation of TLS 1.3 PSK binder
Signed-off-by: Hanno Becker <hanno.becker@arm.com>
This commit is contained in:
		
							parent
							
								
									a4f40a0f48
								
							
						
					
					
						commit
						b7d9bad6be
					
				| @ -565,4 +565,136 @@ int mbedtls_ssl_tls1_3_derive_resumption_master_secret( | |||||||
|     return( 0 ); |     return( 0 ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int ssl_tls1_3_calc_finished_core( mbedtls_md_type_t md_type, | ||||||
|  |                                           unsigned char const *base_key, | ||||||
|  |                                           unsigned char const *transcript, | ||||||
|  |                                           unsigned char *dst ) | ||||||
|  | { | ||||||
|  |     const mbedtls_md_info_t* const md_info = mbedtls_md_info_from_type( md_type ); | ||||||
|  |     size_t const md_size = mbedtls_md_get_size( md_info ); | ||||||
|  |     unsigned char finished_key[MBEDTLS_MD_MAX_SIZE]; | ||||||
|  |     int ret; | ||||||
|  | 
 | ||||||
|  |     /* We should never call this function with an unknown hash,
 | ||||||
|  |      * but add an assertion anyway. */ | ||||||
|  |     if( md_info == 0 ) | ||||||
|  |         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); | ||||||
|  | 
 | ||||||
|  |     /* TLS 1.3 Finished message
 | ||||||
|  |      * | ||||||
|  |      * struct { | ||||||
|  |      *     opaque verify_data[Hash.length]; | ||||||
|  |      * } Finished; | ||||||
|  |      * | ||||||
|  |      * verify_data = | ||||||
|  |      *     HMAC( finished_key, | ||||||
|  |      *            Hash( Handshake Context + | ||||||
|  |      *                  Certificate*      + | ||||||
|  |      *                  CertificateVerify* ) | ||||||
|  |      *    ) | ||||||
|  |      * | ||||||
|  |      * finished_key = | ||||||
|  |      *    HKDF-Expand-Label( BaseKey, "finished", "", Hash.length ) | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     ret = mbedtls_ssl_tls1_3_hkdf_expand_label( | ||||||
|  |                                  md_type, base_key, md_size, | ||||||
|  |                                  MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( finished ), | ||||||
|  |                                  NULL, 0, | ||||||
|  |                                  finished_key, md_size ); | ||||||
|  |     if( ret != 0 ) | ||||||
|  |         goto exit; | ||||||
|  | 
 | ||||||
|  |     ret = mbedtls_md_hmac( md_info, finished_key, md_size, transcript, md_size, dst ); | ||||||
|  |     if( ret != 0 ) | ||||||
|  |         goto exit; | ||||||
|  | 
 | ||||||
|  | exit: | ||||||
|  | 
 | ||||||
|  |     mbedtls_platform_zeroize( finished_key, sizeof( finished_key ) ); | ||||||
|  |     return( ret ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl, | ||||||
|  |                                const mbedtls_md_type_t md_type, | ||||||
|  |                                unsigned char const *psk, size_t psk_len, | ||||||
|  |                                int psk_type, | ||||||
|  |                                unsigned char const *transcript, | ||||||
|  |                                unsigned char *result ) | ||||||
|  | { | ||||||
|  |     int ret = 0; | ||||||
|  |     unsigned char binder_key[MBEDTLS_MD_MAX_SIZE]; | ||||||
|  |     unsigned char early_secret[MBEDTLS_MD_MAX_SIZE]; | ||||||
|  |     mbedtls_md_info_t const *md_info = mbedtls_md_info_from_type( md_type ); | ||||||
|  |     size_t const md_size = mbedtls_md_get_size( md_info ); | ||||||
|  | 
 | ||||||
|  |     /* We should never call this function with an unknown hash,
 | ||||||
|  |      * but add an assertion anyway. */ | ||||||
|  |     if( md_info == 0 ) | ||||||
|  |         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      *            0 | ||||||
|  |      *            | | ||||||
|  |      *            v | ||||||
|  |      *  PSK ->  HKDF-Extract = Early Secret | ||||||
|  |      *            | | ||||||
|  |      *            +-----> Derive-Secret(., "ext binder" | "res binder", "") | ||||||
|  |      *            |                     = binder_key | ||||||
|  |      *            v | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     ret = mbedtls_ssl_tls1_3_evolve_secret( md_type, | ||||||
|  |                                             NULL,          /* Old secret */ | ||||||
|  |                                             psk, psk_len,  /* Input      */ | ||||||
|  |                                             early_secret ); | ||||||
|  |     if( ret != 0 ) | ||||||
|  |     { | ||||||
|  |         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret ); | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION ) | ||||||
|  |     { | ||||||
|  |         ret = mbedtls_ssl_tls1_3_derive_secret( md_type, | ||||||
|  |                             early_secret, md_size, | ||||||
|  |                             MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( res_binder ), | ||||||
|  |                             NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, | ||||||
|  |                             binder_key, md_size ); | ||||||
|  |         MBEDTLS_SSL_DEBUG_MSG( 4, ( "Derive Early Secret with 'res binder'" ) ); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         ret = mbedtls_ssl_tls1_3_derive_secret( md_type, | ||||||
|  |                             early_secret, md_size, | ||||||
|  |                             MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( ext_binder ), | ||||||
|  |                             NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, | ||||||
|  |                             binder_key, md_size ); | ||||||
|  |         MBEDTLS_SSL_DEBUG_MSG( 4, ( "Derive Early Secret with 'ext binder'" ) ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if( ret != 0 ) | ||||||
|  |     { | ||||||
|  |         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_derive_secret", ret ); | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * The binding_value is computed in the same way as the Finished message | ||||||
|  |      * but with the BaseKey being the binder_key. | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     ret = ssl_tls1_3_calc_finished_core( md_type, binder_key, transcript, result ); | ||||||
|  |     if( ret != 0 ) | ||||||
|  |         goto exit; | ||||||
|  | 
 | ||||||
|  |     MBEDTLS_SSL_DEBUG_BUF( 3, "psk binder", result, md_size ); | ||||||
|  | 
 | ||||||
|  | exit: | ||||||
|  | 
 | ||||||
|  |     mbedtls_platform_zeroize( early_secret, sizeof( early_secret ) ); | ||||||
|  |     mbedtls_platform_zeroize( binder_key,   sizeof( binder_key ) ); | ||||||
|  |     return( ret ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ | #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ | ||||||
|  | |||||||
| @ -465,4 +465,37 @@ int mbedtls_ssl_tls1_3_evolve_secret( | |||||||
|                    const unsigned char *input, size_t input_len, |                    const unsigned char *input, size_t input_len, | ||||||
|                    unsigned char *secret_new ); |                    unsigned char *secret_new ); | ||||||
| 
 | 
 | ||||||
|  | #define MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL   0 | ||||||
|  | #define MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION 1 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief             Calculate a TLS 1.3 PSK binder. | ||||||
|  |  * | ||||||
|  |  * \param ssl         The SSL context. This is used for debugging only and may | ||||||
|  |  *                    be \c NULL if MBEDTLS_DEBUG_C is disabled. | ||||||
|  |  * \param md_type     The hash algorithm associated to the PSK \p psk. | ||||||
|  |  * \param psk         The buffer holding the PSK for which to create a binder. | ||||||
|  |  * \param psk_len     The size of \p psk in bytes. | ||||||
|  |  * \param is_external This indicates whether the PSK \p psk is externally | ||||||
|  |  *                    provisioned (#MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL) or a | ||||||
|  |  *                    resumption PSK (#MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION). | ||||||
|  |  * \param transcript  The handshake transcript up to the point where the | ||||||
|  |  *                    PSK binder calculation happens. This must be readable, | ||||||
|  |  *                    and its size must be equal to the digest size of | ||||||
|  |  *                    the hash algorithm represented by \p md_type. | ||||||
|  |  * \param result      The address at which to store the PSK binder on success. | ||||||
|  |  *                    This must be writable, and its size must be equal to the | ||||||
|  |  *                    digest size of  the hash algorithm represented by | ||||||
|  |  *                    \p md_type. | ||||||
|  |  * | ||||||
|  |  * \returns           \c 0 on success. | ||||||
|  |  * \returns           A negative error code on failure. | ||||||
|  |  */ | ||||||
|  | int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl, | ||||||
|  |                                const mbedtls_md_type_t md_type, | ||||||
|  |                                unsigned char const *psk, size_t psk_len, | ||||||
|  |                                int psk_type, | ||||||
|  |                                unsigned char const *transcript, | ||||||
|  |                                unsigned char *result ); | ||||||
|  | 
 | ||||||
| #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ | #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Hanno Becker
						Hanno Becker