diff --git a/src/internal.c b/src/internal.c index 3907ec130..58908517c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5501,6 +5501,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef HAVE_SECRET_CALLBACK ssl->sessionSecretCb = NULL; ssl->sessionSecretCtx = NULL; +#ifdef WOLFSSL_TLS13 + ssl->tls13SecretCb = NULL; + ssl->tls13SecretCtx = NULL; +#endif #endif #ifdef HAVE_SESSION_TICKET @@ -17414,6 +17418,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case SSL_SHUTDOWN_ALREADY_DONE_E: return "Shutdown has already occurred"; + case TLS13_SECRET_CB_E: + return "TLS1.3 Secret Callback Error"; + default : return "unknown error number"; } diff --git a/src/tls13.c b/src/tls13.c index f9cbf86b8..097c74c50 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -440,7 +440,6 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen, hash, hashOutSz, digestAlg); } - #ifndef NO_PSK #ifdef WOLFSSL_TLS13_DRAFT_18 /* The length of the binder key label. */ @@ -521,10 +520,21 @@ static const byte earlyTrafficLabel[EARLY_TRAFFIC_LABEL_SZ + 1] = */ static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Early Traffic Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->secret, - earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->secret, + earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, CLIENT_EARLY_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef TLS13_SUPPORTS_EXPORTERS @@ -549,10 +559,21 @@ static const byte earlyExporterLabel[EARLY_EXPORTER_LABEL_SZ + 1] = */ static int DeriveEarlyExporterSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Early Exporter Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->secret, - earlyExporterLabel, EARLY_EXPORTER_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->secret, + earlyExporterLabel, EARLY_EXPORTER_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, EARLY_EXPORTER_SECRET, key + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #endif #endif @@ -578,10 +599,21 @@ static const byte clientHandshakeLabel[CLIENT_HANDSHAKE_LABEL_SZ + 1] = */ static int DeriveClientHandshakeSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Client Handshake Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, - clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, + clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, CLIENT_HANDSHAKE_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef WOLFSSL_TLS13_DRAFT_18 @@ -605,10 +637,21 @@ static const byte serverHandshakeLabel[SERVER_HANDSHAKE_LABEL_SZ + 1] = */ static int DeriveServerHandshakeSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Server Handshake Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, - serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, + serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, SERVER_HANDSHAKE_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef WOLFSSL_TLS13_DRAFT_18 @@ -632,10 +675,21 @@ static const byte clientAppLabel[CLIENT_APP_LABEL_SZ + 1] = */ static int DeriveClientTrafficSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Client Traffic Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, - clientAppLabel, CLIENT_APP_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, + clientAppLabel, CLIENT_APP_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, CLIENT_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef WOLFSSL_TLS13_DRAFT_18 @@ -659,10 +713,21 @@ static const byte serverAppLabel[SERVER_APP_LABEL_SZ + 1] = */ static int DeriveServerTrafficSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Server Traffic Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, - serverAppLabel, SERVER_APP_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, + serverAppLabel, SERVER_APP_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, SERVER_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef TLS13_SUPPORTS_EXPORTERS @@ -687,10 +752,21 @@ static const byte exporterMasterLabel[EXPORTER_MASTER_LABEL_SZ + 1] = */ static int DeriveExporterSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Exporter Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, - exporterMasterLabel, EXPORTER_MASTER_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, + exporterMasterLabel, EXPORTER_MASTER_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, EXPORTER_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #endif @@ -3087,8 +3163,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int secretSz = SECRET_LEN; ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret, &secretSz, ssl->sessionSecretCtx); - if (ret != 0 || secretSz != SECRET_LEN) + if (ret != 0 || secretSz != SECRET_LEN) { return SESSION_SECRET_CB_E; + } } #endif /* HAVE_SECRET_CALLBACK */ @@ -8844,6 +8921,20 @@ int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz) } #endif +#ifdef HAVE_SECRET_CALLBACK +int wolfSSL_set_tls13_secret_cb(WOLFSSL* ssl, Tls13SecretCb cb, void* ctx) +{ + WOLFSSL_ENTER("wolfSSL_set_tls13_secret_cb"); + if (ssl == NULL) + return WOLFSSL_FATAL_ERROR; + + ssl->tls13SecretCb = cb; + ssl->tls13SecretCtx = ctx; + + return WOLFSSL_SUCCESS; +} +#endif + #undef ERROR_OUT #endif /* !WOLFCRYPT_ONLY */ diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 2327eab3d..9b44326e7 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -166,6 +166,7 @@ enum wolfSSL_ErrorCodes { TSIP_MAC_DIGSZ_E = -435, /* Invalid MAC size for TSIP */ CLIENT_CERT_CB_ERROR = -436, /* Client cert callback error */ SSL_SHUTDOWN_ALREADY_DONE_E = -437, /* Shutdown called redundantly */ + TLS13_SECRET_CB_E = -438, /* TLS1.3 secret Cb fcn failure */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a586184d7..5f47ff767 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4107,6 +4107,10 @@ struct WOLFSSL { #ifdef HAVE_SECRET_CALLBACK SessionSecretCb sessionSecretCb; void* sessionSecretCtx; + #ifdef WOLFSSL_TLS13 + Tls13SecretCb tls13SecretCb; + void* tls13SecretCtx; + #endif #endif /* HAVE_SECRET_CALLBACK */ #ifdef WOLFSSL_JNI void* jObjectRef; /* reference to WolfSSLSession in JNI wrapper */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 236d2d797..9767e4d1f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -643,6 +643,19 @@ enum AlertLevel { /* Maximum number of groups that can be set */ #define WOLFSSL_MAX_GROUP_COUNT 10 +#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) +enum Tls13Secret { + CLIENT_EARLY_TRAFFIC_SECRET, + CLIENT_HANDSHAKE_TRAFFIC_SECRET, + SERVER_HANDSHAKE_TRAFFIC_SECRET, + CLIENT_TRAFFIC_SECRET, + SERVER_TRAFFIC_SECRET, + EARLY_EXPORTER_SECRET, + EXPORTER_SECRET +}; +#endif + + typedef WOLFSSL_METHOD* (*wolfSSL_method_func)(void* heap); /* CTX Method EX Constructor Functions */ @@ -957,9 +970,15 @@ WOLFSSL_ABI WOLFSSL_API long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX*, long); #ifdef HAVE_SECRET_CALLBACK -typedef int (*SessionSecretCb)(WOLFSSL* ssl, - void* secret, int* secretSz, void* ctx); -WOLFSSL_API int wolfSSL_set_session_secret_cb(WOLFSSL*, SessionSecretCb, void*); +typedef int (*SessionSecretCb)(WOLFSSL* ssl, void* secret, int* secretSz, + void* ctx); +WOLFSSL_API int wolfSSL_set_session_secret_cb(WOLFSSL*, SessionSecretCb, + void*); +#ifdef WOLFSSL_TLS13 +typedef int (*Tls13SecretCb)(WOLFSSL* ssl, int id, const unsigned char* secret, + int secretSz, void* ctx); +WOLFSSL_API int wolfSSL_set_tls13_secret_cb(WOLFSSL*, Tls13SecretCb, void*); +#endif #endif /* HAVE_SECRET_CALLBACK */ /* session cache persistence */