diff --git a/cyassl/internal.h b/cyassl/internal.h index ccd7c8138..6f53ba0b0 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1969,6 +1969,9 @@ struct CYASSL { byte hsInfoOn; /* track handshake info */ byte toInfoOn; /* track timeout info */ #endif +#ifdef HAVE_FUZZER + CallbackFuzzer fuzzerCb; /* for testing with using fuzzer */ +#endif #ifdef KEEP_PEER_CERT CYASSL_X509 peerCert; /* X509 peer cert */ #endif diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 7109b0726..33f7a3f71 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -930,6 +930,20 @@ CYASSL_API int CyaSSL_set_group_messages(CYASSL*); typedef int (*CallbackIORecv)(CYASSL *ssl, char *buf, int sz, void *ctx); typedef int (*CallbackIOSend)(CYASSL *ssl, char *buf, int sz, void *ctx); +#ifdef HAVE_FUZZER +enum fuzzer_type { + FUZZ_HMAC = 0, + FUZZ_ENCRYPT = 1, + FUZZ_SIGNATURE = 2, + FUZZ_HASH = 3 +}; + +typedef int (*CallbackFuzzer)(const unsigned char* buf, int sz, int type, + void* ctx); + +CYASSL_API void CyaSSL_SetFuzzerCb(CYASSL* ssl, CallbackFuzzer cbf); +#endif + CYASSL_API void CyaSSL_SetIORecv(CYASSL_CTX*, CallbackIORecv); CYASSL_API void CyaSSL_SetIOSend(CYASSL_CTX*, CallbackIOSend); diff --git a/src/internal.c b/src/internal.c index eb7baccb5..1819b4e0e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1752,6 +1752,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->MacEncryptCtx = NULL; ssl->DecryptVerifyCtx = NULL; #endif +#ifdef HAVE_FUZZER + ssl->fuzzerCb = NULL; +#endif #ifdef HAVE_PK_CALLBACKS #ifdef HAVE_ECC ssl->EccSignCtx = NULL; @@ -2527,6 +2530,10 @@ static int HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz) const byte* adj = output + RECORD_HEADER_SZ + ivSz; sz -= RECORD_HEADER_SZ; +#ifdef HAVE_FUZZER + if (ssl->fuzzerCb) + ssl->fuzzerCb(output, sz, FUZZ_HASH, ssl->ctx); +#endif #ifdef CYASSL_DTLS if (ssl->options.dtls) { adj += DTLS_RECORD_EXTRA; @@ -5113,6 +5120,11 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) return ENCRYPT_ERROR; } +#ifdef HAVE_FUZZER + if (ssl->fuzzerCb) + ssl->fuzzerCb(input, sz, FUZZ_ENCRYPT, ssl->ctx); +#endif + switch (ssl->specs.bulk_cipher_algorithm) { #ifdef BUILD_ARC4 case cyassl_rc4: @@ -6390,6 +6402,11 @@ static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */ const byte* macSecret = CyaSSL_GetMacSecret(ssl, verify); +#ifdef HAVE_FUZZER + if (ssl->fuzzerCb) + ssl->fuzzerCb(in, sz, FUZZ_HMAC, ssl->ctx); +#endif + XMEMSET(seq, 0, SEQ_SZ); conLen[0] = (byte)content; c16toa((word16)sz, &conLen[ENUM_LEN]); @@ -10543,6 +10560,11 @@ static void PickHashSigAlgo(CYASSL* ssl, /* Signtaure length will be written later, when we're sure what it is */ +#ifdef HAVE_FUZZER + if (ssl->fuzzerCb) + ssl->fuzzerCb(output + preSigIdx, preSigSz, FUZZ_SIGNATURE, ssl->ctx); +#endif + /* do signature */ { #ifndef NO_OLD_TLS @@ -10895,6 +10917,11 @@ static void PickHashSigAlgo(CYASSL* ssl, c16toa((word16)sigSz, output + idx); idx += LENGTH_SZ; +#ifdef HAVE_FUZZER + if (ssl->fuzzerCb) + ssl->fuzzerCb(output + preSigIdx, preSigSz, FUZZ_SIGNATURE, ssl->ctx); +#endif + /* do signature */ { #ifndef NO_OLD_TLS diff --git a/src/ssl.c b/src/ssl.c index 1b99e98fd..93d52c8d3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11501,6 +11501,13 @@ const byte* CyaSSL_get_sessionID(const CYASSL_SESSION* session) #endif /* SESSION_CERTS */ +#ifdef HAVE_FUZZER +void CyaSSL_SetFuzzerCb(CYASSL* ssl, CallbackFuzzer cbf) +{ + if (ssl) + ssl->fuzzerCb = cbf; +} +#endif #ifndef NO_CERTS #ifdef HAVE_PK_CALLBACKS diff --git a/src/tls.c b/src/tls.c index a569f064e..f52160df6 100644 --- a/src/tls.c +++ b/src/tls.c @@ -677,6 +677,11 @@ int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, if (ssl == NULL) return BAD_FUNC_ARG; +#ifdef HAVE_FUZZER + if (ssl->fuzzerCb) + ssl->fuzzerCb(in, sz, FUZZ_HMAC, ssl->ctx); +#endif + CyaSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify); ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl),