-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Implement modified key export API for Mbed TLS 3.0 #4552
Changes from all commits
78ba2af
2d6e6f8
457d616
c4c38ca
d5c9cc7
5a234e8
11a4c1a
ddc739c
22b34f7
a7991f2
7e6c178
e0dad72
1e1c23d
d8f32e7
296fefe
5ec5003
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
API changes | ||
* mbedtls_ssl_conf_export_keys_ext_cb() and | ||
mbedtls_ssl_conf_export_keys_cb() have been removed and | ||
replaced by a new API mbedtls_ssl_set_export_keys_cb(). | ||
Raw keys and IVs are no longer passed to the callback. | ||
Further, callbacks now receive an additional parameter | ||
indicating the type of secret that's being exported, | ||
paving the way for the larger number of secrets | ||
in TLS 1.3. Finally, the key export callback and | ||
context are now connection-specific. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
SSL key export interface change | ||
------------------------------- | ||
|
||
This affects users of the SSL key export APIs: | ||
``` | ||
mbedtls_ssl_conf_export_keys_cb() | ||
mbedtls_ssl_conf_export_keys_ext_cb() | ||
``` | ||
|
||
Those APIs have been removed and replaced by the new API | ||
`mbedtls_ssl_set_export_keys_cb()`. This API differs from | ||
the previous key export API in the following ways: | ||
|
||
- It is no longer bound to an SSL configuration, but to an | ||
SSL context. This allows users to more easily identify the | ||
connection an exported key belongs to. | ||
- It no longer exports raw keys and IV. | ||
- A secret type parameter has been added to identify which key | ||
is being exported. For TLS 1.2, only the master secret is | ||
exported, but upcoming TLS 1.3 support will add other kinds of keys. | ||
- The callback now specifies a void return type, rather than | ||
returning an error code. It is the responsibility of the application | ||
to handle failures in the key export callback, for example by | ||
shutting down the TLS connection. | ||
|
||
For users which do not rely on raw keys and IV, adjusting to the new | ||
callback type should be straightforward - see the example programs | ||
programs/ssl/ssl_client2 and programs/ssl/ssl_server2 for callbacks | ||
for NSSKeylog, EAP-TLS and DTLS-SRTP. | ||
|
||
Users which require access to the raw keys used to secure application | ||
traffic may derive those by hand based on the master secret and the | ||
handshake transcript hashes which can be obtained from the raw data | ||
on the wire. Such users are also encouraged to reach out to the | ||
Mbed TLS team on the mailing list, to let the team know about their | ||
use case. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -458,18 +458,6 @@ typedef enum | |
} | ||
mbedtls_ssl_states; | ||
|
||
/* | ||
* The tls_prf function types. | ||
*/ | ||
typedef enum | ||
{ | ||
MBEDTLS_SSL_TLS_PRF_NONE, | ||
MBEDTLS_SSL_TLS_PRF_TLS1, | ||
MBEDTLS_SSL_TLS_PRF_SHA384, | ||
MBEDTLS_SSL_TLS_PRF_SHA256 | ||
} | ||
mbedtls_tls_prf_types; | ||
|
||
/** | ||
* \brief Callback type: send data on the network. | ||
* | ||
|
@@ -967,6 +955,57 @@ struct mbedtls_ssl_session | |
#endif | ||
}; | ||
|
||
/* | ||
* Identifiers for PRFs used in various versions of TLS. | ||
*/ | ||
typedef enum | ||
{ | ||
MBEDTLS_SSL_TLS_PRF_NONE, | ||
MBEDTLS_SSL_TLS_PRF_SHA384, | ||
MBEDTLS_SSL_TLS_PRF_SHA256, | ||
MBEDTLS_SSL_HKDF_EXPAND_SHA384, | ||
MBEDTLS_SSL_HKDF_EXPAND_SHA256 | ||
} | ||
mbedtls_tls_prf_types; | ||
|
||
#if defined(MBEDTLS_SSL_EXPORT_KEYS) | ||
gilles-peskine-arm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
typedef enum | ||
{ | ||
MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET = 0, | ||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) | ||
MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_EARLY_SECRET, | ||
MBEDTLS_SSL_KEY_EXPORT_TLS13_EARLY_EXPORTER_SECRET, | ||
MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_HANDSHAKE_TRAFFIC_SECRET, | ||
MBEDTLS_SSL_KEY_EXPORT_TLS13_SERVER_HANDSHAKE_TRAFFIC_SECRET, | ||
MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_APPLICATION_TRAFFIC_SECRET, | ||
MBEDTLS_SSL_KEY_EXPORT_TLS13_SERVER_APPLICATION_TRAFFIC_SECRET, | ||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ | ||
} mbedtls_ssl_key_export_type; | ||
|
||
/** | ||
* \brief Callback type: Export key alongside random values for | ||
* session identification, and PRF for | ||
* implementation of TLS key exporters. | ||
* | ||
gilles-peskine-arm marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Doesn't necessarily need to be answered now, but it may matter to the design of the API.) With There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the answer might be "don't call it", should we document now that under some circumstances (that we don't need to define at this point), the callback may not be called? |
||
* \param p_expkey Context for the callback. | ||
* \param type The type of the key that is being exported. | ||
* \param secret The address of the buffer holding the secret | ||
* that's being exporterd. | ||
* \param secret_len The length of \p secret in bytes. | ||
* \param client_random The client random bytes. | ||
* \param server_random The server random bytes. | ||
* \param tls_prf_type The identifier for the PRF used in the handshake | ||
* to which the key belongs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing docs for secret and secret_len There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixing |
||
*/ | ||
typedef void mbedtls_ssl_export_keys_t( void *p_expkey, | ||
mbedtls_ssl_key_export_type type, | ||
const unsigned char *secret, | ||
size_t secret_len, | ||
const unsigned char client_random[32], | ||
const unsigned char server_random[32], | ||
mbedtls_tls_prf_types tls_prf_type ); | ||
#endif /* MBEDTLS_SSL_EXPORT_KEYS */ | ||
|
||
/** | ||
* SSL/TLS configuration to be shared between mbedtls_ssl_context structures. | ||
*/ | ||
|
@@ -1032,19 +1071,6 @@ struct mbedtls_ssl_config | |
void *MBEDTLS_PRIVATE(p_ticket); /*!< context for the ticket callbacks */ | ||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ | ||
|
||
#if defined(MBEDTLS_SSL_EXPORT_KEYS) | ||
/** Callback to export key block and master secret */ | ||
int (*MBEDTLS_PRIVATE(f_export_keys))( void *, const unsigned char *, | ||
const unsigned char *, size_t, size_t, size_t ); | ||
/** Callback to export key block, master secret, | ||
* tls_prf and random bytes. Should replace f_export_keys */ | ||
int (*MBEDTLS_PRIVATE(f_export_keys_ext))( void *, const unsigned char *, | ||
const unsigned char *, size_t, size_t, size_t, | ||
const unsigned char[32], const unsigned char[32], | ||
mbedtls_tls_prf_types ); | ||
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ | ||
#endif | ||
|
||
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) | ||
size_t MBEDTLS_PRIVATE(cid_len); /*!< The length of CIDs for incoming DTLS records. */ | ||
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ | ||
|
@@ -1395,6 +1421,12 @@ struct mbedtls_ssl_context | |
* Possible values are #MBEDTLS_SSL_CID_ENABLED | ||
* and #MBEDTLS_SSL_CID_DISABLED. */ | ||
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ | ||
|
||
#if defined(MBEDTLS_SSL_EXPORT_KEYS) | ||
/** Callback to export key block and master secret */ | ||
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); | ||
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ | ||
#endif | ||
}; | ||
|
||
/** | ||
|
@@ -1918,70 +1950,6 @@ typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, | |
size_t *tlen, | ||
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 ); | ||
|
||
/** | ||
* \brief Callback type: Export key block, master secret, | ||
* handshake randbytes and the tls_prf function | ||
* used to derive keys. | ||
* | ||
* \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. | ||
* \param client_random The client random bytes. | ||
* \param server_random The server random bytes. | ||
* \param tls_prf_type The tls_prf enum type. | ||
* | ||
* \return 0 if successful, or | ||
* a specific MBEDTLS_ERR_XXX code. | ||
*/ | ||
typedef int mbedtls_ssl_export_keys_ext_t( void *p_expkey, | ||
const unsigned char *ms, | ||
const unsigned char *kb, | ||
size_t maclen, | ||
size_t keylen, | ||
size_t ivlen, | ||
const unsigned char client_random[32], | ||
const unsigned char server_random[32], | ||
mbedtls_tls_prf_types tls_prf_type ); | ||
#endif /* MBEDTLS_SSL_EXPORT_KEYS */ | ||
|
||
/** | ||
* \brief Callback type: parse and load session ticket | ||
* | ||
|
@@ -2033,34 +2001,26 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, | |
|
||
#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 ); | ||
|
||
/** | ||
* \brief Configure extended key export callback. | ||
* (Default: none.) | ||
* | ||
* \note See \c mbedtls_ssl_export_keys_ext_t. | ||
* \warning Exported key material must not be used for any purpose | ||
* before the (D)TLS handshake is completed | ||
* | ||
* \param conf SSL configuration context | ||
* \param f_export_keys_ext Callback for exporting keys | ||
* \param p_export_keys Context for the callback | ||
*/ | ||
void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf, | ||
mbedtls_ssl_export_keys_ext_t *f_export_keys_ext, | ||
void *p_export_keys ); | ||
* \brief Configure a key export callback. | ||
* (Default: none.) | ||
* | ||
* This API can be used for two purposes: | ||
* - Debugging: Use this API to e.g. generate an NSSKeylog | ||
* file and use it to inspect encrypted traffic in tools | ||
* such as Wireshark. | ||
* - Application-specific export: Use this API to implement | ||
* key exporters, e.g. for EAP-TLS or DTLS-SRTP. | ||
* | ||
* | ||
* \param ssl The SSL context to which the export | ||
* callback should be attached. | ||
* \param f_export_keys The callback for the key export. | ||
* \param p_export_keys The opaque context pointer to be passed to the | ||
gilles-peskine-arm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* callback \p f_export_keys. | ||
*/ | ||
void mbedtls_ssl_set_export_keys_cb( mbedtls_ssl_context *ssl, | ||
mbedtls_ssl_export_keys_t *f_export_keys, | ||
void *p_export_keys ); | ||
#endif /* MBEDTLS_SSL_EXPORT_KEYS */ | ||
|
||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way is that the new callback returns void, whereas the old callbacks returned an int value that was ignored. Since the old value was ignored, that's minor enough not to be mentioned in the changelog which is a high-level semantic overview, but I think it should be listed in the migration guide, because I'd expect the list here to be a complete list of steps to migrate existing code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point, I've discussed wording with @hanno-arm & pushed a commit with the addition to the migration guide.