From 90f5882e8bbd7aae2616538b52e33434da5f4ea8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 14 Dec 2023 10:54:06 -0800 Subject: [PATCH 1/9] Fix typo with HMAC determination of update/final. --- tls/client-tls-cryptocb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index 566f386c..383c3ea9 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -358,13 +358,13 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hmac.hmac->devId = INVALID_DEVID; - if (info->hash.in != NULL) { + if (info->hmac.in != NULL) { ret = wc_HmacUpdate( info->hmac.hmac, info->hmac.in, info->hmac.inSz); } - else if (info->hash.digest != NULL) { + else if (info->hmac.digest != NULL) { ret = wc_HmacFinal( info->hmac.hmac, info->hmac.digest); From 124998fb8b16006238c7df5deba98822b3eda310 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 18 Dec 2023 11:25:40 -0800 Subject: [PATCH 2/9] Add example for TLS server with crypto callbacks. --- tls/client-tls-cryptocb.c | 76 ++--- tls/server-tls-cryptocb.c | 580 ++++++++++++++++++++++++++++++++++++++ tls/server-tls.c | 11 +- 3 files changed, 631 insertions(+), 36 deletions(-) create mode 100644 tls/server-tls-cryptocb.c diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index 383c3ea9..e9d2f0bd 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -47,12 +47,6 @@ typedef struct { int exampleVar; /* example, not used */ } myCryptoCbCtx; -static void error_out(char* msg, int err) -{ - printf("Failed at %s with code %d\n", msg, err); - exit(1); -} - /* Example crypto dev callback function that calls software version */ /* This is where you would plug-in calls to your own hardware crypto */ @@ -386,19 +380,21 @@ int main(int argc, char** argv) { int ret = 0; #ifdef WOLF_CRYPTO_CB - int sockfd; + int sockfd = SOCKET_INVALID; struct sockaddr_in servAddr; char buff[256]; size_t len; /* declare wolfSSL objects */ - WOLFSSL_CTX* ctx; - WOLFSSL* ssl; + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + WOLFSSL_CIPHER* cipher; int devId = 1; /* anything besides -2 (INVALID_DEVID) */ myCryptoCbCtx myCtx; /* example data for callback */ + memset(&myCtx, 0, sizeof(myCtx)); myCtx.exampleVar = 1; /* Check for proper calling convention */ @@ -413,7 +409,7 @@ int main(int argc, char** argv) if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "ERROR: failed to create the socket\n"); ret = -1; - goto end; + goto exit; } /* Initialize the server address struct with zeros */ @@ -427,36 +423,46 @@ int main(int argc, char** argv) if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) != 1) { fprintf(stderr, "ERROR: invalid address\n"); ret = -1; - goto end; + goto exit; } /* Connect to the server */ if ((ret = connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr))) == -1) { fprintf(stderr, "ERROR: failed to connect\n"); - goto end; + goto exit; } +#if 0 + wolfSSL_Debugging_ON(); +#endif + /*---------------------------------*/ /* Start of wolfSSL initialization and configuration */ /*---------------------------------*/ /* Initialize wolfSSL */ if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: Failed to initialize the library\n"); - goto socket_cleanup; + goto exit; } /* Create and initialize WOLFSSL_CTX */ - if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) { + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method())) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); ret = -1; - goto socket_cleanup; + goto exit; } +#if 0 + wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); +#endif + /* register a devID for crypto callbacks */ ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); - if (ret != 0) - error_out("wc_CryptoCb_RegisterDevice", ret); + if (ret != 0) { + fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); + goto exit; + } /* register a devID for crypto callbacks */ wolfSSL_CTX_SetDevId(ctx, devId); @@ -466,35 +472,38 @@ int main(int argc, char** argv) != SSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CA_FILE); - goto ctx_cleanup; + goto exit; } /* Create a WOLFSSL object */ if ((ssl = wolfSSL_new(ctx)) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); ret = -1; - goto ctx_cleanup; + goto exit; } /* Attach wolfSSL to the socket */ if ((ret = wolfSSL_set_fd(ssl, sockfd)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: Failed to set the file descriptor\n"); - goto cleanup; + goto exit; } /* Connect to wolfSSL on the server side */ if ((ret = wolfSSL_connect(ssl)) != SSL_SUCCESS) { fprintf(stderr, "ERROR: failed to connect to wolfSSL\n"); - goto cleanup; + goto exit; } + cipher = wolfSSL_get_current_cipher(ssl); + printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); + /* Get a message for the server from stdin */ printf("Message for server: "); memset(buff, 0, sizeof(buff)); if (fgets(buff, sizeof(buff), stdin) == NULL) { fprintf(stderr, "ERROR: failed to get message for server\n"); ret = -1; - goto cleanup; + goto exit; } len = strnlen(buff, sizeof(buff)); @@ -502,33 +511,34 @@ int main(int argc, char** argv) if ((ret = wolfSSL_write(ssl, buff, len)) != len) { fprintf(stderr, "ERROR: failed to write entire message\n"); fprintf(stderr, "%d bytes of %d bytes were sent", ret, (int) len); - goto cleanup; + goto exit; } /* Read the server data into our buff array */ memset(buff, 0, sizeof(buff)); if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) == -1) { fprintf(stderr, "ERROR: failed to read\n"); - goto cleanup; + goto exit; } /* Print to stdout any data the server sends */ printf("Server: %s\n", buff); - ret = 0; + ret = 0; /* return success */ +exit: /* Cleanup and return */ -cleanup: - wolfSSL_free(ssl); /* Free the wolfSSL object */ -ctx_cleanup: - wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + if (sockfd != SOCKET_INVALID) + close(sockfd); /* Close the connection to the server */ + if (ssl != NULL) + wolfSSL_free(ssl); /* Free the wolfSSL object */ + if (ctx != NULL) + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ -socket_cleanup: - close(sockfd); /* Close the connection to the server */ -end: #else printf("Please configure wolfSSL with --enable-cryptocb and try again\n"); #endif /* WOLF_CRYPTO_CB */ - return ret; /* Return reporting a success */ + + return ret; } diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c new file mode 100644 index 00000000..a9c07961 --- /dev/null +++ b/tls/server-tls-cryptocb.c @@ -0,0 +1,580 @@ +/* server-tls-cryptocb.c + * + * Copyright (C) 2006-2020 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* the usual suspects */ +#include +#include +#include + +/* socket includes */ +#include +#include +#include +#include + +/* wolfSSL */ +#include +#include + +#define DEFAULT_PORT 11111 + +#define CERT_FILE "../certs/server-cert.pem" +#define KEY_FILE "../certs/server-key.pem" + +#ifdef WOLF_CRYPTO_CB +/* Example custom context for crypto callback */ +typedef struct { + int exampleVar; /* example, not used */ +} myCryptoCbCtx; + +/* Example crypto dev callback function that calls software version */ +/* This is where you would plug-in calls to your own hardware crypto */ +static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */ + myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx; + + if (info == NULL) + return BAD_FUNC_ARG; + +#ifdef DEBUG_CRYPTOCB + wc_CryptoCb_InfoString(info); +#endif + + if (info->algo_type == WC_ALGO_TYPE_RNG) { + #ifndef WC_NO_RNG + /* set devId to invalid, so software is used */ + info->rng.rng->devId = INVALID_DEVID; + + ret = wc_RNG_GenerateBlock(info->rng.rng, + info->rng.out, info->rng.sz); + + /* reset devId */ + info->rng.rng->devId = devIdArg; + #endif + } + else if (info->algo_type == WC_ALGO_TYPE_SEED) { + #ifndef WC_NO_RNG + static byte seed[sizeof(word32)] = { 0x00, 0x00, 0x00, 0x01 }; + word32* seedWord32 = (word32*)seed; + word32 len; + + /* wc_GenerateSeed is a local symbol so we need to fake the entropy. */ + while (info->seed.sz > 0) { + len = (word32)sizeof(seed); + if (info->seed.sz < len) + len = info->seed.sz; + XMEMCPY(info->seed.seed, seed, sizeof(seed)); + info->seed.seed += len; + info->seed.sz -= len; + (*seedWord32)++; + } + + ret = 0; + #endif + } + else if (info->algo_type == WC_ALGO_TYPE_PK) { + #ifndef NO_RSA + if (info->pk.type == WC_PK_TYPE_RSA) { + /* set devId to invalid, so software is used */ + info->pk.rsa.key->devId = INVALID_DEVID; + + switch (info->pk.rsa.type) { + case RSA_PUBLIC_ENCRYPT: + case RSA_PUBLIC_DECRYPT: + /* perform software based RSA public op */ + ret = wc_RsaFunction( + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, info->pk.rsa.outLen, + info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); + break; + case RSA_PRIVATE_ENCRYPT: + case RSA_PRIVATE_DECRYPT: + /* perform software based RSA private op */ + ret = wc_RsaFunction( + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, info->pk.rsa.outLen, + info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); + break; + } + + /* reset devId */ + info->pk.rsa.key->devId = devIdArg; + } + #ifdef WOLFSSL_KEY_GEN + else if (info->pk.type == WC_PK_TYPE_RSA_KEYGEN) { + info->pk.rsakg.key->devId = INVALID_DEVID; + + ret = wc_MakeRsaKey(info->pk.rsakg.key, info->pk.rsakg.size, + info->pk.rsakg.e, info->pk.rsakg.rng); + + /* reset devId */ + info->pk.rsakg.key->devId = devIdArg; + } + #endif + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) { + /* set devId to invalid, so software is used */ + info->pk.eckg.key->devId = INVALID_DEVID; + + ret = wc_ecc_make_key_ex(info->pk.eckg.rng, info->pk.eckg.size, + info->pk.eckg.key, info->pk.eckg.curveId); + + /* reset devId */ + info->pk.eckg.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + /* set devId to invalid, so software is used */ + info->pk.eccsign.key->devId = INVALID_DEVID; + + ret = wc_ecc_sign_hash( + info->pk.eccsign.in, info->pk.eccsign.inlen, + info->pk.eccsign.out, info->pk.eccsign.outlen, + info->pk.eccsign.rng, info->pk.eccsign.key); + + /* reset devId */ + info->pk.eccsign.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + /* set devId to invalid, so software is used */ + info->pk.eccverify.key->devId = INVALID_DEVID; + + ret = wc_ecc_verify_hash( + info->pk.eccverify.sig, info->pk.eccverify.siglen, + info->pk.eccverify.hash, info->pk.eccverify.hashlen, + info->pk.eccverify.res, info->pk.eccverify.key); + + /* reset devId */ + info->pk.eccverify.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDH) { + /* set devId to invalid, so software is used */ + info->pk.ecdh.private_key->devId = INVALID_DEVID; + + ret = wc_ecc_shared_secret( + info->pk.ecdh.private_key, info->pk.ecdh.public_key, + info->pk.ecdh.out, info->pk.ecdh.outlen); + + /* reset devId */ + info->pk.ecdh.private_key->devId = devIdArg; + } + #endif /* HAVE_ECC */ + } + else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { +#if !defined(NO_AES) || !defined(NO_DES3) + #ifdef HAVE_AESGCM + if (info->cipher.type == WC_CIPHER_AES_GCM) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.aesgcm_enc.aes->devId = INVALID_DEVID; + + ret = wc_AesGcmEncrypt( + info->cipher.aesgcm_enc.aes, + info->cipher.aesgcm_enc.out, + info->cipher.aesgcm_enc.in, + info->cipher.aesgcm_enc.sz, + info->cipher.aesgcm_enc.iv, + info->cipher.aesgcm_enc.ivSz, + info->cipher.aesgcm_enc.authTag, + info->cipher.aesgcm_enc.authTagSz, + info->cipher.aesgcm_enc.authIn, + info->cipher.aesgcm_enc.authInSz); + + /* reset devId */ + info->cipher.aesgcm_enc.aes->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.aesgcm_dec.aes->devId = INVALID_DEVID; + + ret = wc_AesGcmDecrypt( + info->cipher.aesgcm_dec.aes, + info->cipher.aesgcm_dec.out, + info->cipher.aesgcm_dec.in, + info->cipher.aesgcm_dec.sz, + info->cipher.aesgcm_dec.iv, + info->cipher.aesgcm_dec.ivSz, + info->cipher.aesgcm_dec.authTag, + info->cipher.aesgcm_dec.authTagSz, + info->cipher.aesgcm_dec.authIn, + info->cipher.aesgcm_dec.authInSz); + + /* reset devId */ + info->cipher.aesgcm_dec.aes->devId = devIdArg; + } + } + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AES_CBC + if (info->cipher.type == WC_CIPHER_AES_CBC) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.aescbc.aes->devId = INVALID_DEVID; + + ret = wc_AesCbcEncrypt( + info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + + /* reset devId */ + info->cipher.aescbc.aes->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.aescbc.aes->devId = INVALID_DEVID; + + ret = wc_AesCbcDecrypt( + info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + + /* reset devId */ + info->cipher.aescbc.aes->devId = devIdArg; + } + } + #endif /* HAVE_AES_CBC */ + #ifndef NO_DES3 + if (info->cipher.type == WC_CIPHER_DES3) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.des3.des->devId = INVALID_DEVID; + + ret = wc_Des3_CbcEncrypt( + info->cipher.des3.des, + info->cipher.des3.out, + info->cipher.des3.in, + info->cipher.des3.sz); + + /* reset devId */ + info->cipher.des3.des->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.des3.des->devId = INVALID_DEVID; + + ret = wc_Des3_CbcDecrypt( + info->cipher.des3.des, + info->cipher.des3.out, + info->cipher.des3.in, + info->cipher.des3.sz); + + /* reset devId */ + info->cipher.des3.des->devId = devIdArg; + } + } + #endif /* !NO_DES3 */ +#endif /* !NO_AES || !NO_DES3 */ + } + else if (info->algo_type == WC_ALGO_TYPE_HASH) { +#if !defined(NO_SHA) || !defined(NO_SHA256) + #if !defined(NO_SHA) + if (info->hash.type == WC_HASH_TYPE_SHA) { + if (info->hash.sha1 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha1->devId = INVALID_DEVID; + + if (info->hash.in != NULL) { + ret = wc_ShaUpdate( + info->hash.sha1, + info->hash.in, + info->hash.inSz); + } + if (info->hash.digest != NULL) { + ret = wc_ShaFinal( + info->hash.sha1, + info->hash.digest); + } + + /* reset devId */ + info->hash.sha1->devId = devIdArg; + } + else + #endif + #if !defined(NO_SHA256) + if (info->hash.type == WC_HASH_TYPE_SHA256) { + if (info->hash.sha256 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha256->devId = INVALID_DEVID; + + if (info->hash.in != NULL) { + ret = wc_Sha256Update( + info->hash.sha256, + info->hash.in, + info->hash.inSz); + } + if (info->hash.digest != NULL) { + ret = wc_Sha256Final( + info->hash.sha256, + info->hash.digest); + } + + /* reset devId */ + info->hash.sha256->devId = devIdArg; + } + else + #endif + { + } +#endif /* !NO_SHA || !NO_SHA256 */ + } + else if (info->algo_type == WC_ALGO_TYPE_HMAC) { +#ifndef NO_HMAC + if (info->hmac.hmac == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hmac.hmac->devId = INVALID_DEVID; + + if (info->hmac.in != NULL) { + ret = wc_HmacUpdate( + info->hmac.hmac, + info->hmac.in, + info->hmac.inSz); + } + else if (info->hmac.digest != NULL) { + ret = wc_HmacFinal( + info->hmac.hmac, + info->hmac.digest); + } + + /* reset devId */ + info->hmac.hmac->devId = devIdArg; +#endif + } + + (void)devIdArg; + (void)myCtx; + + return ret; +} +#endif /* WOLF_CRYPTO_CB */ + + +int main(int argc, char** argv) +{ + int ret = 0; +#ifdef WOLF_CRYPTO_CB + int sockfd = SOCKET_INVALID; + int connd = SOCKET_INVALID; + struct sockaddr_in servAddr; + struct sockaddr_in clientAddr; + socklen_t size = sizeof(clientAddr); + char buff[256]; + size_t len; + int shutdown = 0; + const char* reply = "I hear ya fa shizzle!\n"; + + /* declare wolfSSL objects */ + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + WOLFSSL_CIPHER* cipher; + + int devId = 1; /* anything besides -2 (INVALID_DEVID) */ + myCryptoCbCtx myCtx; + +#if 0 + wolfSSL_Debugging_ON(); +#endif + + /* Initialize wolfSSL */ + wolfSSL_Init(); + + /* example data for callback */ + memset(&myCtx, 0, sizeof(myCtx)); + myCtx.exampleVar = 1; + + + /* Create and initialize WOLFSSL_CTX */ + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); + ret = -1; + goto exit; + } + + /* Load server certificates into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CERT_FILE); + goto exit; + } + + /* Load server key into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + KEY_FILE); + goto exit; + } + +#if 0 + wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); +#endif + + /* register a devID for crypto callbacks */ + ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); + if (ret != 0) { + fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); + goto exit; + } + + /* register a devID for crypto callbacks */ + wolfSSL_CTX_SetDevId(ctx, devId); + + + /* Create a socket that uses an internet IPv4 address, + * Sets the socket to be stream based (TCP), + * 0 means choose the default protocol. */ + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + fprintf(stderr, "ERROR: failed to create the socket\n"); + ret = -1; + goto exit; + } + + + /* Initialize the server address struct with zeros */ + memset(&servAddr, 0, sizeof(servAddr)); + + /* Fill in the server address */ + servAddr.sin_family = AF_INET; /* using IPv4 */ + servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */ + servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */ + + + /* Bind the server socket to our port */ + if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { + fprintf(stderr, "ERROR: failed to bind\n"); + ret = -1; + goto exit; + } + + /* Listen for a new connection, allow 5 pending connections */ + if (listen(sockfd, 5) == -1) { + fprintf(stderr, "ERROR: failed to listen\n"); + ret = -1; + goto exit; + } + + + /* Continue to accept clients until shutdown is issued */ + while (!shutdown) { + printf("Waiting for a connection...\n"); + + /* Accept client connections */ + if ((connd = accept(sockfd, (struct sockaddr*)&clientAddr, &size)) + == -1) { + fprintf(stderr, "ERROR: failed to accept the connection\n\n"); + ret = -1; + goto exit; + } + + /* Create a WOLFSSL object */ + if ((ssl = wolfSSL_new(ctx)) == NULL) { + fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); + ret = -1; + goto exit; + } + + /* Attach wolfSSL to the socket */ + wolfSSL_set_fd(ssl, connd); + + /* Establish TLS connection */ + ret = wolfSSL_accept(ssl); + if (ret != WOLFSSL_SUCCESS) { + fprintf(stderr, "wolfSSL_accept error = %d\n", + wolfSSL_get_error(ssl, ret)); + goto exit; + } + + + printf("Client connected successfully\n"); + + cipher = wolfSSL_get_current_cipher(ssl); + printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); + + + /* Read the client data into our buff array */ + memset(buff, 0, sizeof(buff)); + if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) == -1) { + fprintf(stderr, "ERROR: failed to read\n"); + goto exit; + } + + /* Print to stdout any data the client sends */ + printf("Client: %s\n", buff); + + /* Check for server shutdown command */ + if (strncmp(buff, "shutdown", 8) == 0) { + printf("Shutdown command issued!\n"); + shutdown = 1; + } + + + + /* Write our reply into buff */ + memset(buff, 0, sizeof(buff)); + memcpy(buff, reply, strlen(reply)); + len = strnlen(buff, sizeof(buff)); + + /* Reply back to the client */ + if ((ret = wolfSSL_write(ssl, buff, len)) != len) { + fprintf(stderr, "ERROR: failed to write\n"); + goto exit; + } + + /* Notify the client that the connection is ending */ + wolfSSL_shutdown(ssl); + printf("Shutdown complete\n"); + + /* Cleanup after this connection */ + wolfSSL_free(ssl); /* Free the wolfSSL object */ + ssl = NULL; + close(connd); /* Close the connection to the client */ + } + + ret = 0; + +exit: + /* Cleanup and return */ + if (ssl) + wolfSSL_free(ssl); /* Free the wolfSSL object */ + if (connd != SOCKET_INVALID) + close(connd); /* Close the connection to the client */ + if (sockfd != SOCKET_INVALID) + close(sockfd); /* Close the socket listening for clients */ + if (ctx) + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ +#else + printf("Please configure wolfSSL with --enable-cryptocb and try again\n"); +#endif /* WOLF_CRYPTO_CB */ + + (void)argc; + (void)argv; + + return ret; /* Return reporting a success */ +} diff --git a/tls/server-tls.c b/tls/server-tls.c index fa79a4d2..e8488289 100644 --- a/tls/server-tls.c +++ b/tls/server-tls.c @@ -57,8 +57,11 @@ int main() /* declare wolfSSL objects */ WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; + WOLFSSL_CIPHER* cipher; - +#if 0 + wolfSSL_Debugging_ON(); +#endif /* Initialize wolfSSL */ wolfSSL_Init(); @@ -77,7 +80,7 @@ int main() /* Create and initialize WOLFSSL_CTX */ - if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) { + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); ret = -1; goto exit; @@ -114,7 +117,7 @@ int main() /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); - ret = -1; + ret = -1; goto exit; } @@ -160,6 +163,8 @@ int main() printf("Client connected successfully\n"); + cipher = wolfSSL_get_current_cipher(ssl); + printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); /* Read the client data into our buff array */ From 1e5f87b32f22ae32ce6685253de0d5dfac86b99c Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 18 Dec 2023 15:44:35 -0800 Subject: [PATCH 3/9] Better example for crypto callback hashing. --- tls/client-tls-cryptocb.c | 111 ++++++++++++++++++++++++++++-------- tls/server-tls-cryptocb.c | 117 ++++++++++++++++++++++++++++++-------- 2 files changed, 180 insertions(+), 48 deletions(-) diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index e9d2f0bd..d9f19b86 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -47,6 +47,54 @@ typedef struct { int exampleVar; /* example, not used */ } myCryptoCbCtx; +typedef struct { + word32 bufSz; +} hash_ctx_t; + +/* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ +/* in: Update (when not NULL) / Final (when NULL) */ +static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, + void* shactx, void** devCtx) +{ + int ret = 0; + enum wc_HashType hash_type = (enum wc_HashType)type; + hash_ctx_t* ctx = (hash_ctx_t*)*devCtx; + byte* hashBuf = NULL; + word32 hashBufSz = 0; + + /* for updates alloc/realloc and copy */ + if (in != NULL) { + if (ctx == NULL) { + ctx = (hash_ctx_t*)malloc(sizeof(hash_ctx_t) + hashBufSz + inSz); + } + else { + hashBufSz = ctx->bufSz; + ctx = (hash_ctx_t*)realloc(ctx, sizeof(hash_ctx_t) + hashBufSz + inSz); + } + if (ctx == NULL) { + return MEMORY_E; + } + hashBuf = (byte*)ctx + sizeof(hash_ctx_t); + memcpy(&hashBuf[hashBufSz], in, inSz); + ctx->bufSz = hashBufSz + inSz; + *devCtx = ctx; + } + /* final */ + else if (digest != NULL) { + if (ctx == NULL) { + /* valid case of empty hash (0 len hash) */ + } + else { + hashBuf = (byte*)ctx + sizeof(hash_ctx_t); + hashBufSz = ctx->bufSz; + } + ret = wc_Hash_ex(hash_type, + hashBuf, hashBufSz, + digest, wc_HashGetDigestSize(hash_type), + NULL, INVALID_DEVID); + } + return ret; +} /* Example crypto dev callback function that calls software version */ /* This is where you would plug-in calls to your own hardware crypto */ @@ -289,7 +337,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) #endif /* !NO_AES || !NO_DES3 */ } else if (info->algo_type == WC_ALGO_TYPE_HASH) { -#if !defined(NO_SHA) || !defined(NO_SHA256) +#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \ + defined(WOLFSSL_SHA512) #if !defined(NO_SHA) if (info->hash.type == WC_HASH_TYPE_SHA) { if (info->hash.sha1 == NULL) @@ -298,17 +347,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hash.sha1->devId = INVALID_DEVID; - if (info->hash.in != NULL) { - ret = wc_ShaUpdate( - info->hash.sha1, - info->hash.in, - info->hash.inSz); - } - if (info->hash.digest != NULL) { - ret = wc_ShaFinal( - info->hash.sha1, - info->hash.digest); - } + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx); /* reset devId */ info->hash.sha1->devId = devIdArg; @@ -323,26 +363,49 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hash.sha256->devId = INVALID_DEVID; - if (info->hash.in != NULL) { - ret = wc_Sha256Update( - info->hash.sha256, - info->hash.in, - info->hash.inSz); - } - if (info->hash.digest != NULL) { - ret = wc_Sha256Final( - info->hash.sha256, - info->hash.digest); - } + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx); /* reset devId */ info->hash.sha256->devId = devIdArg; } else + #endif + #ifdef WOLFSSL_SHA384 + if (info->hash.type == WC_HASH_TYPE_SHA384) { + if (info->hash.sha384 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha384->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx); + + /* reset devId */ + info->hash.sha384->devId = devIdArg; + } + else + #endif + #ifdef WOLFSSL_SHA512 + if (info->hash.type == WC_HASH_TYPE_SHA512) { + if (info->hash.sha512 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha512->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx); + + /* reset devId */ + info->hash.sha512->devId = devIdArg; + } + else #endif { } -#endif /* !NO_SHA || !NO_SHA256 */ +#endif /* !NO_SHA || !NO_SHA256 || WOLFSSL_SHA384 || WOLFSSL_SHA512 */ } else if (info->algo_type == WC_ALGO_TYPE_HMAC) { #ifndef NO_HMAC diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c index a9c07961..46baa811 100644 --- a/tls/server-tls-cryptocb.c +++ b/tls/server-tls-cryptocb.c @@ -45,6 +45,55 @@ typedef struct { int exampleVar; /* example, not used */ } myCryptoCbCtx; +typedef struct { + word32 bufSz; +} hash_ctx_t; + +/* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ +/* in: Update (when not NULL) / Final (when NULL) */ +static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, + void* shactx, void** devCtx) +{ + int ret = 0; + enum wc_HashType hash_type = (enum wc_HashType)type; + hash_ctx_t* ctx = (hash_ctx_t*)*devCtx; + byte* hashBuf = NULL; + word32 hashBufSz = 0; + + /* for updates alloc/realloc and copy */ + if (in != NULL) { + if (ctx == NULL) { + ctx = (hash_ctx_t*)malloc(sizeof(hash_ctx_t) + hashBufSz + inSz); + } + else { + hashBufSz = ctx->bufSz; + ctx = (hash_ctx_t*)realloc(ctx, sizeof(hash_ctx_t) + hashBufSz + inSz); + } + if (ctx == NULL) { + return MEMORY_E; + } + hashBuf = (byte*)ctx + sizeof(hash_ctx_t); + memcpy(&hashBuf[hashBufSz], in, inSz); + ctx->bufSz = hashBufSz + inSz; + *devCtx = ctx; + } + /* final */ + else if (digest != NULL) { + if (ctx == NULL) { + /* valid case of empty hash (0 len hash) */ + } + else { + hashBuf = (byte*)ctx + sizeof(hash_ctx_t); + hashBufSz = ctx->bufSz; + } + ret = wc_Hash_ex(hash_type, + hashBuf, hashBufSz, + digest, wc_HashGetDigestSize(hash_type), + NULL, INVALID_DEVID); + } + return ret; +} + /* Example crypto dev callback function that calls software version */ /* This is where you would plug-in calls to your own hardware crypto */ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) @@ -286,7 +335,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) #endif /* !NO_AES || !NO_DES3 */ } else if (info->algo_type == WC_ALGO_TYPE_HASH) { -#if !defined(NO_SHA) || !defined(NO_SHA256) +#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \ + defined(WOLFSSL_SHA512) #if !defined(NO_SHA) if (info->hash.type == WC_HASH_TYPE_SHA) { if (info->hash.sha1 == NULL) @@ -295,17 +345,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hash.sha1->devId = INVALID_DEVID; - if (info->hash.in != NULL) { - ret = wc_ShaUpdate( - info->hash.sha1, - info->hash.in, - info->hash.inSz); - } - if (info->hash.digest != NULL) { - ret = wc_ShaFinal( - info->hash.sha1, - info->hash.digest); - } + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx); /* reset devId */ info->hash.sha1->devId = devIdArg; @@ -320,26 +361,49 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hash.sha256->devId = INVALID_DEVID; - if (info->hash.in != NULL) { - ret = wc_Sha256Update( - info->hash.sha256, - info->hash.in, - info->hash.inSz); - } - if (info->hash.digest != NULL) { - ret = wc_Sha256Final( - info->hash.sha256, - info->hash.digest); - } + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx); /* reset devId */ info->hash.sha256->devId = devIdArg; } else + #endif + #ifdef WOLFSSL_SHA384 + if (info->hash.type == WC_HASH_TYPE_SHA384) { + if (info->hash.sha384 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha384->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx); + + /* reset devId */ + info->hash.sha384->devId = devIdArg; + } + else + #endif + #ifdef WOLFSSL_SHA512 + if (info->hash.type == WC_HASH_TYPE_SHA512) { + if (info->hash.sha512 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha512->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx); + + /* reset devId */ + info->hash.sha512->devId = devIdArg; + } + else #endif { } -#endif /* !NO_SHA || !NO_SHA256 */ +#endif /* !NO_SHA || !NO_SHA256 || WOLFSSL_SHA384 || WOLFSSL_SHA512 */ } else if (info->algo_type == WC_ALGO_TYPE_HMAC) { #ifndef NO_HMAC @@ -387,6 +451,7 @@ int main(int argc, char** argv) size_t len; int shutdown = 0; const char* reply = "I hear ya fa shizzle!\n"; + int on; /* declare wolfSSL objects */ WOLFSSL_CTX* ctx = NULL; @@ -455,6 +520,10 @@ int main(int argc, char** argv) goto exit; } + on = 1; + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&on, (socklen_t)sizeof(on)); + /* Initialize the server address struct with zeros */ memset(&servAddr, 0, sizeof(servAddr)); From 005e08db5a40a122beed9531f93296674676d200 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Dec 2023 08:03:36 -0800 Subject: [PATCH 4/9] For crypto cb TLS examples do free if not a copy. --- tls/client-tls-cryptocb.c | 19 ++++++++++++++----- tls/server-tls-cryptocb.c | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index d9f19b86..7c479ebc 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -54,7 +54,7 @@ typedef struct { /* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ /* in: Update (when not NULL) / Final (when NULL) */ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, - void* shactx, void** devCtx) + void* shactx, void** devCtx, word32 flags) { int ret = 0; enum wc_HashType hash_type = (enum wc_HashType)type; @@ -92,6 +92,11 @@ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, hashBuf, hashBufSz, digest, wc_HashGetDigestSize(hash_type), NULL, INVALID_DEVID); + + if (!(flags & WC_HASH_FLAG_ISCOPY)) { + free(ctx); + *devCtx = NULL; + } } return ret; } @@ -348,7 +353,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha1->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx); + info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx, + info->hash.sha1->flags); /* reset devId */ info->hash.sha1->devId = devIdArg; @@ -364,7 +370,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha256->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx); + info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx, + info->hash.sha256->flags); /* reset devId */ info->hash.sha256->devId = devIdArg; @@ -380,7 +387,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha384->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx); + info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx, + info->hash.sha384->flags); /* reset devId */ info->hash.sha384->devId = devIdArg; @@ -396,7 +404,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha512->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx); + info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx, + info->hash.sha512->flags); /* reset devId */ info->hash.sha512->devId = devIdArg; diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c index 46baa811..cc052e97 100644 --- a/tls/server-tls-cryptocb.c +++ b/tls/server-tls-cryptocb.c @@ -52,7 +52,7 @@ typedef struct { /* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ /* in: Update (when not NULL) / Final (when NULL) */ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, - void* shactx, void** devCtx) + void* shactx, void** devCtx, word32 flags) { int ret = 0; enum wc_HashType hash_type = (enum wc_HashType)type; @@ -90,6 +90,11 @@ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, hashBuf, hashBufSz, digest, wc_HashGetDigestSize(hash_type), NULL, INVALID_DEVID); + + if (!(flags & WC_HASH_FLAG_ISCOPY)) { + free(ctx); + *devCtx = NULL; + } } return ret; } @@ -346,7 +351,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha1->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx); + info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx, + info->hash.sha1->flags); /* reset devId */ info->hash.sha1->devId = devIdArg; @@ -362,7 +368,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha256->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx); + info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx, + info->hash.sha256->flags); /* reset devId */ info->hash.sha256->devId = devIdArg; @@ -378,7 +385,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha384->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx); + info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx, + info->hash.sha384->flags); /* reset devId */ info->hash.sha384->devId = devIdArg; @@ -394,7 +402,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) info->hash.sha512->devId = INVALID_DEVID; ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx); + info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx, + info->hash.sha512->flags); /* reset devId */ info->hash.sha512->devId = devIdArg; From ed2549cfbe203669871d3830dd4b3b3a3a5ff72a Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Dec 2023 10:35:55 -0800 Subject: [PATCH 5/9] Support building TLS examples with `--disable-oldnames`. --- tls/client-tls-cacb.c | 12 ++++++------ tls/client-tls-cryptocb.c | 4 ++-- tls/client-tls-ecdhe.c | 18 +++++++++--------- tls/client-tls-uart.c | 2 +- tls/client-tls.c | 6 +++--- tls/memory-tls.c | 14 +++++++------- tls/server-tls-callback.c | 12 ++++++------ tls/server-tls-cryptocb.c | 4 ++-- tls/server-tls-ecdhe.c | 4 ++-- tls/server-tls-nonblocking.c | 18 +++++++++--------- tls/server-tls-threaded.c | 14 +++++++------- tls/server-tls-uart.c | 6 +++--- tls/server-tls.c | 4 ++-- 13 files changed, 59 insertions(+), 59 deletions(-) diff --git a/tls/client-tls-cacb.c b/tls/client-tls-cacb.c index f17015a1..5ecbd70b 100644 --- a/tls/client-tls-cacb.c +++ b/tls/client-tls-cacb.c @@ -97,7 +97,7 @@ static void CaCb(unsigned char* der, int sz, int type) } ret = wolfSSL_X509_get_serial_number(x509, serial, &sz); - if (ret == SSL_SUCCESS) { + if (ret == WOLFSSL_SUCCESS) { int i; int strLen; char serialMsg[80]; @@ -134,7 +134,7 @@ int Security(int sock) /* create and initialize WOLFSSL_CTX structure */ if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) { printf("SSL_CTX_new error.\n"); - ret = EXIT_FAILURE; + ret = EXIT_FAILURE; goto exit; } @@ -142,20 +142,20 @@ int Security(int sock) wolfSSL_CTX_SetCACb(ctx, CaCb); /* load CA certificates into wolfSSL_CTX. which will verify the server */ - if ((ret = wolfSSL_CTX_load_verify_locations(ctx, cert, 0)) + if ((ret = wolfSSL_CTX_load_verify_locations(ctx, cert, 0)) != WOLFSSL_SUCCESS) { printf("Error loading %s. Please check the file.\n", cert); goto exit; } if ((ssl = wolfSSL_new(ctx)) == NULL) { printf("wolfSSL_new error.\n"); - ret = EXIT_FAILURE; + ret = EXIT_FAILURE; goto exit; } wolfSSL_set_fd(ssl, sock); ret = wolfSSL_connect(ssl); - if (ret == SSL_SUCCESS) { + if (ret == WOLFSSL_SUCCESS) { ret = ClientGreet(sock, ssl); } @@ -190,7 +190,7 @@ int main(int argc, char** argv) if (sockfd < 0) { printf("Failed to create socket. Error: %i\n", errno); - ret = EXIT_FAILURE; + ret = EXIT_FAILURE; goto exit; } diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index 7c479ebc..5c8c13b7 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -541,7 +541,7 @@ int main(int argc, char** argv) /* Load client certificates into WOLFSSL_CTX */ if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL)) - != SSL_SUCCESS) { + != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CA_FILE); goto exit; @@ -561,7 +561,7 @@ int main(int argc, char** argv) } /* Connect to wolfSSL on the server side */ - if ((ret = wolfSSL_connect(ssl)) != SSL_SUCCESS) { + if ((ret = wolfSSL_connect(ssl)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to connect to wolfSSL\n"); goto exit; } diff --git a/tls/client-tls-ecdhe.c b/tls/client-tls-ecdhe.c index 3773ae58..e8073623 100644 --- a/tls/client-tls-ecdhe.c +++ b/tls/client-tls-ecdhe.c @@ -46,7 +46,7 @@ int main(int argc, char** argv) { - int ret; + int ret; int sockfd = SOCKET_INVALID; struct sockaddr_in servAddr; char buff[256]; @@ -76,7 +76,7 @@ int main(int argc, char** argv) * 0 means choose the default protocol. */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "ERROR: failed to create the socket\n"); - ret = -1; + ret = -1; goto exit; } @@ -85,7 +85,7 @@ int main(int argc, char** argv) /* Create and initialize WOLFSSL_CTX */ if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); - ret = -1; + ret = -1; goto exit; } @@ -98,7 +98,7 @@ int main(int argc, char** argv) } /* Load client ecc certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_certificate_chain_file(ctx, ECC_FILE)) != + if ((ret = wolfSSL_CTX_use_certificate_chain_file(ctx, ECC_FILE)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", ECC_FILE); @@ -106,7 +106,7 @@ int main(int argc, char** argv) } /* Load client ecc key into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); @@ -132,7 +132,7 @@ int main(int argc, char** argv) /* Get the server IPv4 address from the command line call */ if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) != 1) { fprintf(stderr, "ERROR: invalid address\n"); - ret = -1; + ret = -1; goto exit; } @@ -142,7 +142,7 @@ int main(int argc, char** argv) if (connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to connect\n"); - ret = -1; + ret = -1; goto exit; } @@ -151,7 +151,7 @@ int main(int argc, char** argv) /* Create a WOLFSSL object */ if ((ssl = wolfSSL_new(ctx)) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); - ret = -1; + ret = -1; goto exit; } @@ -171,7 +171,7 @@ int main(int argc, char** argv) memset(buff, 0, sizeof(buff)); if (fgets(buff, sizeof(buff), stdin) == NULL) { fprintf(stderr, "ERROR: failed to get message for server\n"); - ret = -1; + ret = -1; goto exit; } len = strnlen(buff, sizeof(buff)); diff --git a/tls/client-tls-uart.c b/tls/client-tls-uart.c index c67618b8..8e58eacf 100644 --- a/tls/client-tls-uart.c +++ b/tls/client-tls-uart.c @@ -206,7 +206,7 @@ int main(int argc, char** argv) wolfSSL_CTX_SetIORecv(ctx, uartIORx); /* For testing disable peer cert verification */ - wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL); ssl = wolfSSL_new(ctx); if (ssl == NULL) { diff --git a/tls/client-tls.c b/tls/client-tls.c index d1e06be6..b3a6a421 100644 --- a/tls/client-tls.c +++ b/tls/client-tls.c @@ -108,7 +108,7 @@ int main(int argc, char** argv) /* Load client certificates into WOLFSSL_CTX */ if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CERT_FILE, NULL)) - != SSL_SUCCESS) { + != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); goto ctx_cleanup; @@ -128,7 +128,7 @@ int main(int argc, char** argv) } /* Connect to wolfSSL on the server side */ - if ((ret = wolfSSL_connect(ssl)) != SSL_SUCCESS) { + if ((ret = wolfSSL_connect(ssl)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to connect to wolfSSL\n"); goto cleanup; } @@ -161,7 +161,7 @@ int main(int argc, char** argv) printf("Server: %s\n", buff); /* Bidirectional shutdown */ - while (wolfSSL_shutdown(ssl) == SSL_SHUTDOWN_NOT_DONE) { + while (wolfSSL_shutdown(ssl) == WOLFSSL_SHUTDOWN_NOT_DONE) { printf("Shutdown not complete\n"); } diff --git a/tls/memory-tls.c b/tls/memory-tls.c index b50457fd..663ac855 100644 --- a/tls/memory-tls.c +++ b/tls/memory-tls.c @@ -147,7 +147,7 @@ static void* client_thread(void* args) if (cli_ctx == NULL) err_sys("bad client ctx new"); int ret = wolfSSL_CTX_load_verify_locations(cli_ctx, cacert, NULL); - if (ret != SSL_SUCCESS) err_sys("bad ca load"); + if (ret != WOLFSSL_SUCCESS) err_sys("bad ca load"); wolfSSL_SetIOSend(cli_ctx, ClientSend); wolfSSL_SetIORecv(cli_ctx, ClientRecv); @@ -156,7 +156,7 @@ static void* client_thread(void* args) if (cli_ctx == NULL) err_sys("bad client new"); ret = wolfSSL_connect(cli_ssl); - if (ret != SSL_SUCCESS) err_sys("bad client tls connect"); + if (ret != WOLFSSL_SUCCESS) err_sys("bad client tls connect"); printf("wolfSSL client success!\n"); ret = wolfSSL_write(cli_ssl, "hello memory wolfSSL!", 21); @@ -175,11 +175,11 @@ int main() WOLFSSL_CTX* srv_ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()); if (srv_ctx == NULL) err_sys("bad server ctx new"); - int ret = wolfSSL_CTX_use_PrivateKey_file(srv_ctx, key, SSL_FILETYPE_PEM); - if (ret != SSL_SUCCESS) err_sys("bad server key file load"); + int ret = wolfSSL_CTX_use_PrivateKey_file(srv_ctx, key, WOLFSSL_FILETYPE_PEM); + if (ret != WOLFSSL_SUCCESS) err_sys("bad server key file load"); - ret = wolfSSL_CTX_use_certificate_file(srv_ctx, cert, SSL_FILETYPE_PEM); - if (ret != SSL_SUCCESS) err_sys("bad server cert file load"); + ret = wolfSSL_CTX_use_certificate_file(srv_ctx, cert, WOLFSSL_FILETYPE_PEM); + if (ret != WOLFSSL_SUCCESS) err_sys("bad server cert file load"); wolfSSL_SetIOSend(srv_ctx, ServerSend); wolfSSL_SetIORecv(srv_ctx, ServerRecv); @@ -193,7 +193,7 @@ int main() /* accept tls connection without tcp sockets */ ret = wolfSSL_accept(srv_ssl); - if (ret != SSL_SUCCESS) err_sys("bad server tls accept"); + if (ret != WOLFSSL_SUCCESS) err_sys("bad server tls accept"); printf("wolfSSL accept success!\n"); /* read msg post handshake from client */ diff --git a/tls/server-tls-callback.c b/tls/server-tls-callback.c index c3d9bd73..a53d1235 100644 --- a/tls/server-tls-callback.c +++ b/tls/server-tls-callback.c @@ -170,7 +170,7 @@ int main() * 0 means choose the default protocol. */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "ERROR: failed to create the socket\n"); - ret = -1; + ret = -1; goto exit; } @@ -184,7 +184,7 @@ int main() } /* Load server certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); @@ -192,7 +192,7 @@ int main() } /* Load server key into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); @@ -220,7 +220,7 @@ int main() /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); - ret = -1; + ret = -1; goto exit; } @@ -248,7 +248,7 @@ int main() /* Create a WOLFSSL object */ if ((ssl = wolfSSL_new(ctx)) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); - ret = -1; + ret = -1; goto exit; } @@ -308,7 +308,7 @@ int main() } ret = 0; - + exit: /* Cleanup and return */ if (ssl) diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c index cc052e97..599f0c68 100644 --- a/tls/server-tls-cryptocb.c +++ b/tls/server-tls-cryptocb.c @@ -490,7 +490,7 @@ int main(int argc, char** argv) } /* Load server certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); @@ -498,7 +498,7 @@ int main(int argc, char** argv) } /* Load server key into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); diff --git a/tls/server-tls-ecdhe.c b/tls/server-tls-ecdhe.c index d870466c..679ea15d 100644 --- a/tls/server-tls-ecdhe.c +++ b/tls/server-tls-ecdhe.c @@ -86,7 +86,7 @@ int main() } /* Load server certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); @@ -94,7 +94,7 @@ int main() } /* Load server key into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); diff --git a/tls/server-tls-nonblocking.c b/tls/server-tls-nonblocking.c index 7201186e..c863a0cd 100644 --- a/tls/server-tls-nonblocking.c +++ b/tls/server-tls-nonblocking.c @@ -125,7 +125,7 @@ int main() if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) { fprintf(stderr, "ERROR: failed to set socket options\n"); ret = -1; - goto exit; + goto exit; } @@ -138,7 +138,7 @@ int main() } /* Load server certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); @@ -146,12 +146,12 @@ int main() } /* Load server key into WOLFSSL_CTX */ - if (wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM) + if (wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); ret = -1; - goto exit; + goto exit; } @@ -191,7 +191,7 @@ int main() /* non-blocking, wait for read activity on socket */ tcp_select(sockfd, SELECT_WAIT_SEC, 1); continue; - } + } else if (errno == EINPROGRESS || errno == EALREADY) { break; } @@ -212,10 +212,10 @@ int main() fprintf(stderr, "ERROR: Failed to set the file descriptor\n"); goto exit; } - + /* Establish TLS connection */ printf("wolfSSL_accepting\n"); - + do { ret = wolfSSL_accept(ssl); err = wolfSSL_get_error(ssl, ret); @@ -234,7 +234,7 @@ int main() do { ret = wolfSSL_read(ssl, buff, sizeof(buff)-1); err = wolfSSL_get_error(ssl, ret); - + if (err == WOLFSSL_ERROR_WANT_READ) tcp_select(sockfd, SELECT_WAIT_SEC, 1); } @@ -302,6 +302,6 @@ exit: if (ctx) wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ - + return ret; } diff --git a/tls/server-tls-threaded.c b/tls/server-tls-threaded.c index 94ea9ccd..810746e7 100644 --- a/tls/server-tls-threaded.c +++ b/tls/server-tls-threaded.c @@ -86,7 +86,7 @@ void* ClientHandler(void* args) ret = wolfSSL_accept(ssl); } while(wolfSSL_want_read(ssl)); - if (ret != SSL_SUCCESS) { + if (ret != WOLFSSL_SUCCESS) { printf("ret = %d\n", ret); fprintf(stderr, "wolfSSL_accept error = %d\n", wolfSSL_get_error(ssl, ret)); @@ -159,7 +159,7 @@ void* ClientHandler(void* args) int main() { - int ret; + int ret; int sockfd = SOCKET_INVALID; int connd; struct sockaddr_in servAddr; @@ -186,7 +186,7 @@ int main() * 0 means choose the default protocol. */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "ERROR: failed to create the socket\n"); - ret = -1; + ret = -1; goto exit; } @@ -207,7 +207,7 @@ int main() } /* Load server certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); @@ -215,7 +215,7 @@ int main() } /* Load server key into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); @@ -237,14 +237,14 @@ int main() /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); - ret = -1; + ret = -1; goto exit; } /* Listen for a new connection, allow 5 pending connections */ if (listen(sockfd, 5) == -1) { fprintf(stderr, "ERROR: failed to listen\n"); - ret = -1; + ret = -1; goto exit; } diff --git a/tls/server-tls-uart.c b/tls/server-tls-uart.c index b52f9841..bacf99f1 100644 --- a/tls/server-tls-uart.c +++ b/tls/server-tls-uart.c @@ -207,16 +207,16 @@ int main(int argc, char** argv) wolfSSL_CTX_SetIORecv(ctx, uartIORx); /* For testing disable peer cert verification */ - wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL); /* Set server key and certificate (required) */ - if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); goto done; } /* Load server key into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); goto done; } diff --git a/tls/server-tls.c b/tls/server-tls.c index e8488289..09cd0ea0 100644 --- a/tls/server-tls.c +++ b/tls/server-tls.c @@ -87,7 +87,7 @@ int main() } /* Load server certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); @@ -95,7 +95,7 @@ int main() } /* Load server key into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)) + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", KEY_FILE); From d505779dfe5257b9605f87046f4ad6b3dfa06b84 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Dec 2023 11:26:44 -0800 Subject: [PATCH 6/9] Improved TLS cryptocb test cases. --- tls/Makefile | 4 +++ tls/client-tls-cryptocb.c | 54 ++++++++++++++++++++++++++++++--------- tls/server-tls-cryptocb.c | 52 ++++++++++++++++++++++++++++--------- 3 files changed, 86 insertions(+), 24 deletions(-) diff --git a/tls/Makefile b/tls/Makefile index 0cbce682..c2df6639 100644 --- a/tls/Makefile +++ b/tls/Makefile @@ -19,6 +19,10 @@ CFLAGS+=$(OPTIMIZE) #LIBS+=$(STATIC_LIB) LIBS+=$(DYN_LIB) +# Openssl Option +#CFLAGS+=-DUSE_OPENSSL +#LIBS+=-lcrypto + # build targets SRC=$(wildcard *.c) TARGETS=$(patsubst %.c, %, $(SRC)) diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index 5c8c13b7..bf98badb 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -51,6 +51,10 @@ typedef struct { word32 bufSz; } hash_ctx_t; +#ifdef USE_OPENSSL +#include +#endif + /* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ /* in: Update (when not NULL) / Final (when NULL) */ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, @@ -88,11 +92,34 @@ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, hashBuf = (byte*)ctx + sizeof(hash_ctx_t); hashBufSz = ctx->bufSz; } + +#ifdef USE_OPENSSL + switch (hash_type) { + case WC_HASH_TYPE_SHA: + SHA1(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA224: + SHA224(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA256: + SHA256(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA384: + SHA384(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA512: + SHA512(hashBuf, hashBufSz, digest); + break; + default: + ret = NOT_COMPILED_IN; + break; + } +#else ret = wc_Hash_ex(hash_type, hashBuf, hashBufSz, digest, wc_HashGetDigestSize(hash_type), NULL, INVALID_DEVID); - +#endif if (!(flags & WC_HASH_FLAG_ISCOPY)) { free(ctx); *devCtx = NULL; @@ -518,6 +545,15 @@ int main(int argc, char** argv) goto exit; } +#if 1 + /* register a devID for crypto callbacks */ + ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); + if (ret != 0) { + fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); + goto exit; + } +#endif + /* Create and initialize WOLFSSL_CTX */ if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method())) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); @@ -525,20 +561,14 @@ int main(int argc, char** argv) goto exit; } -#if 0 - wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); -#endif - - /* register a devID for crypto callbacks */ - ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); - if (ret != 0) { - fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); - goto exit; - } - /* register a devID for crypto callbacks */ wolfSSL_CTX_SetDevId(ctx, devId); +#if 0 + /* Example: "TLS13-AES256-GCM-SHA384", "TLS13-AES128-GCM-SHA256" or "TLS13-CHACHA20-POLY1305-SHA256" */ + wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); +#endif + /* Load client certificates into WOLFSSL_CTX */ if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL)) != WOLFSSL_SUCCESS) { diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c index 599f0c68..6ca4f079 100644 --- a/tls/server-tls-cryptocb.c +++ b/tls/server-tls-cryptocb.c @@ -49,6 +49,10 @@ typedef struct { word32 bufSz; } hash_ctx_t; +#ifdef USE_OPENSSL +#include +#endif + /* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ /* in: Update (when not NULL) / Final (when NULL) */ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, @@ -86,11 +90,34 @@ static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, hashBuf = (byte*)ctx + sizeof(hash_ctx_t); hashBufSz = ctx->bufSz; } + +#ifdef USE_OPENSSL + switch (hash_type) { + case WC_HASH_TYPE_SHA: + SHA1(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA224: + SHA224(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA256: + SHA256(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA384: + SHA384(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA512: + SHA512(hashBuf, hashBufSz, digest); + break; + default: + ret = NOT_COMPILED_IN; + break; + } +#else ret = wc_Hash_ex(hash_type, hashBuf, hashBufSz, digest, wc_HashGetDigestSize(hash_type), NULL, INVALID_DEVID); - +#endif if (!(flags & WC_HASH_FLAG_ISCOPY)) { free(ctx); *devCtx = NULL; @@ -481,6 +508,14 @@ int main(int argc, char** argv) memset(&myCtx, 0, sizeof(myCtx)); myCtx.exampleVar = 1; +#if 1 + /* register a devID for crypto callbacks */ + ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); + if (ret != 0) { + fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); + goto exit; + } +#endif /* Create and initialize WOLFSSL_CTX */ if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) { @@ -489,6 +524,9 @@ int main(int argc, char** argv) goto exit; } + /* register a devID for crypto callbacks */ + wolfSSL_CTX_SetDevId(ctx, devId); + /* Load server certificates into WOLFSSL_CTX */ if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { @@ -506,20 +544,10 @@ int main(int argc, char** argv) } #if 0 + /* Example: "TLS13-AES256-GCM-SHA384", "TLS13-AES128-GCM-SHA256" or "TLS13-CHACHA20-POLY1305-SHA256" */ wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); #endif - /* register a devID for crypto callbacks */ - ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); - if (ret != 0) { - fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); - goto exit; - } - - /* register a devID for crypto callbacks */ - wolfSSL_CTX_SetDevId(ctx, devId); - - /* Create a socket that uses an internet IPv4 address, * Sets the socket to be stream based (TCP), * 0 means choose the default protocol. */ From 1c6e1c4c9ac7a2547ab38e411ffaa30111b0dbe7 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Dec 2023 12:31:28 -0800 Subject: [PATCH 7/9] Add mutual auth, RSA/ECC and TLS v1.2/v1.3 support to TLS crypto callback examples. --- tls/client-tls-cryptocb.c | 52 ++++++++++++++++++++++++++++++++++++--- tls/server-tls-cryptocb.c | 40 +++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index bf98badb..27a7bdfc 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -31,7 +31,9 @@ #include /* wolfSSL */ -#include +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif #include #include #include @@ -39,7 +41,18 @@ #define DEFAULT_PORT 11111 -#define CA_FILE "../certs/ca-cert.pem" +#define USE_ECDHE_ECDSA +#define USE_TLSV13 + +#ifdef USE_ECDHE_ECDSA +#define CERT_FILE "../certs/client-ecc-cert.pem" +#define KEY_FILE "../certs/ecc-client-key.pem" +#define CA_FILE "../certs/ca-ecc-cert.pem" +#else +#define CERT_FILE "../certs/client-cert.pem" +#define KEY_FILE "../certs/client-key.pem" +#define CA_FILE "../certs/ca-cert.pem" +#endif #ifdef WOLF_CRYPTO_CB /* Example custom context for crypto callback */ @@ -555,12 +568,45 @@ int main(int argc, char** argv) #endif /* Create and initialize WOLFSSL_CTX */ - if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method())) == NULL) { +#ifdef USE_TLSV13 + ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); +#else + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); +#endif + if (ctx == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); ret = -1; goto exit; } + /* Mutual Authentication */ + /* Load client certificate into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CERT_FILE); + goto exit; + } + + /* Load client key into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + KEY_FILE); + goto exit; + } + + /* Load CA certificate into WOLFSSL_CTX for validating peer */ + if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL)) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CA_FILE); + goto exit; + } + + /* validate peer certificate */ + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL); + /* register a devID for crypto callbacks */ wolfSSL_CTX_SetDevId(ctx, devId); diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c index 6ca4f079..50d0ecc5 100644 --- a/tls/server-tls-cryptocb.c +++ b/tls/server-tls-cryptocb.c @@ -31,13 +31,28 @@ #include /* wolfSSL */ -#include +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif #include +#include +#include +#include #define DEFAULT_PORT 11111 -#define CERT_FILE "../certs/server-cert.pem" -#define KEY_FILE "../certs/server-key.pem" +#define USE_ECDHE_ECDSA +#define USE_TLSV13 + +#ifdef USE_ECDHE_ECDSA +#define CERT_FILE "../certs/server-ecc.pem" +#define KEY_FILE "../certs/ecc-key.pem" +#define CA_FILE "../certs/client-ecc-cert.pem" +#else +#define CERT_FILE "../certs/server-cert.pem" +#define KEY_FILE "../certs/server-key.pem" +#define CA_FILE "../certs/client-cert.pem" +#endif #ifdef WOLF_CRYPTO_CB /* Example custom context for crypto callback */ @@ -518,7 +533,12 @@ int main(int argc, char** argv) #endif /* Create and initialize WOLFSSL_CTX */ - if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) { +#ifdef USE_TLSV13 + ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()); +#else + ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()); +#endif + if (ctx == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); ret = -1; goto exit; @@ -543,6 +563,18 @@ int main(int argc, char** argv) goto exit; } + /* Load CA certificate into WOLFSSL_CTX for validating peer */ + if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL)) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CA_FILE); + goto exit; + } + + /* enable mutual authentication */ + wolfSSL_CTX_set_verify(ctx, + WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); + #if 0 /* Example: "TLS13-AES256-GCM-SHA384", "TLS13-AES128-GCM-SHA256" or "TLS13-CHACHA20-POLY1305-SHA256" */ wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); From f808600853be4ba25b48c2dec11579658786e6d4 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 10 Jan 2024 15:05:48 -0800 Subject: [PATCH 8/9] Peer review feedback. --- .gitignore | 4 + tls/Makefile | 8 +- tls/client-tls-cryptocb.c | 437 +----------------------------------- tls/cryptocb-common.c | 452 ++++++++++++++++++++++++++++++++++++++ tls/cryptocb-common.h | 45 ++++ tls/server-tls-cryptocb.c | 438 +----------------------------------- tls/server-tls.c | 2 +- 7 files changed, 512 insertions(+), 874 deletions(-) create mode 100644 tls/cryptocb-common.c create mode 100644 tls/cryptocb-common.h diff --git a/.gitignore b/.gitignore index a1182ade..f3b34ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,7 @@ android/wolfssljni-ndk-sample/proguard-project.txt /psk/server-psk /psk/server-tcp +/tls/client-async /tls/client-tcp /tls/client-tls /tls/client-tls13 @@ -80,6 +81,7 @@ android/wolfssljni-ndk-sample/proguard-project.txt /tls/client-tls-bio /tls/client-tls-cacb /tls/client-tls-callback +/tls/client-tls-cryptocb /tls/client-tls-ecdhe /tls/client-tls-nonblocking /tls/client-tls-perf @@ -89,10 +91,12 @@ android/wolfssljni-ndk-sample/proguard-project.txt /tls/memory-tls +/tls/server-async /tls/server-tcp /tls/server-tls /tls/server-tls13 /tls/server-tls-callback +/tls/server-tls-cryptocb /tls/server-tls-ecdhe /tls/server-tls-epoll-perf /tls/server-tls-epoll-threaded diff --git a/tls/Makefile b/tls/Makefile index c2df6639..b46d9802 100644 --- a/tls/Makefile +++ b/tls/Makefile @@ -10,6 +10,7 @@ STATIC_LIB = $(LIB_PATH)/lib/libwolfssl.a DEBUG_FLAGS = -g -DDEBUG DEBUG_INC_PATHS = -MD OPTIMIZE = -Os +DEPS = # Options #CFLAGS+=$(DEBUG_FLAGS) @@ -25,7 +26,8 @@ LIBS+=$(DYN_LIB) # build targets SRC=$(wildcard *.c) -TARGETS=$(patsubst %.c, %, $(SRC)) +IGNORE_FILES=cryptocb-common +TARGETS=$(filter-out $(IGNORE_FILES), $(patsubst %.c, %, $(SRC))) LINUX_SPECIFIC=client-tls-perf \ server-tls-poll-perf \ server-tls-epoll-perf \ @@ -101,9 +103,11 @@ memory-tls: CFLAGS+=-pthread # compile tcp examples without the LIBS variable %-tcp: LIBS= +%-cryptocb: DEPS+=cryptocb-common.c + # build template %: %.c - $(CC) -o $@ $< $(CFLAGS) $(LIBS) + $(CC) -o $@ $(DEPS) $< $(CFLAGS) $(LIBS) clean: rm -f $(TARGETS) diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index 27a7bdfc..e835c4c2 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -39,6 +39,8 @@ #include #include +#include "cryptocb-common.h" + #define DEFAULT_PORT 11111 #define USE_ECDHE_ECDSA @@ -54,439 +56,6 @@ #define CA_FILE "../certs/ca-cert.pem" #endif -#ifdef WOLF_CRYPTO_CB -/* Example custom context for crypto callback */ -typedef struct { - int exampleVar; /* example, not used */ -} myCryptoCbCtx; - -typedef struct { - word32 bufSz; -} hash_ctx_t; - -#ifdef USE_OPENSSL -#include -#endif - -/* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ -/* in: Update (when not NULL) / Final (when NULL) */ -static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, - void* shactx, void** devCtx, word32 flags) -{ - int ret = 0; - enum wc_HashType hash_type = (enum wc_HashType)type; - hash_ctx_t* ctx = (hash_ctx_t*)*devCtx; - byte* hashBuf = NULL; - word32 hashBufSz = 0; - - /* for updates alloc/realloc and copy */ - if (in != NULL) { - if (ctx == NULL) { - ctx = (hash_ctx_t*)malloc(sizeof(hash_ctx_t) + hashBufSz + inSz); - } - else { - hashBufSz = ctx->bufSz; - ctx = (hash_ctx_t*)realloc(ctx, sizeof(hash_ctx_t) + hashBufSz + inSz); - } - if (ctx == NULL) { - return MEMORY_E; - } - hashBuf = (byte*)ctx + sizeof(hash_ctx_t); - memcpy(&hashBuf[hashBufSz], in, inSz); - ctx->bufSz = hashBufSz + inSz; - *devCtx = ctx; - } - /* final */ - else if (digest != NULL) { - if (ctx == NULL) { - /* valid case of empty hash (0 len hash) */ - } - else { - hashBuf = (byte*)ctx + sizeof(hash_ctx_t); - hashBufSz = ctx->bufSz; - } - -#ifdef USE_OPENSSL - switch (hash_type) { - case WC_HASH_TYPE_SHA: - SHA1(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA224: - SHA224(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA256: - SHA256(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA384: - SHA384(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA512: - SHA512(hashBuf, hashBufSz, digest); - break; - default: - ret = NOT_COMPILED_IN; - break; - } -#else - ret = wc_Hash_ex(hash_type, - hashBuf, hashBufSz, - digest, wc_HashGetDigestSize(hash_type), - NULL, INVALID_DEVID); -#endif - if (!(flags & WC_HASH_FLAG_ISCOPY)) { - free(ctx); - *devCtx = NULL; - } - } - return ret; -} - -/* Example crypto dev callback function that calls software version */ -/* This is where you would plug-in calls to your own hardware crypto */ -static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) -{ - int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */ - myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx; - - if (info == NULL) - return BAD_FUNC_ARG; - -#ifdef DEBUG_CRYPTOCB - wc_CryptoCb_InfoString(info); -#endif - - if (info->algo_type == WC_ALGO_TYPE_RNG) { - #ifndef WC_NO_RNG - /* set devId to invalid, so software is used */ - info->rng.rng->devId = INVALID_DEVID; - - ret = wc_RNG_GenerateBlock(info->rng.rng, - info->rng.out, info->rng.sz); - - /* reset devId */ - info->rng.rng->devId = devIdArg; - #endif - } - else if (info->algo_type == WC_ALGO_TYPE_SEED) { - #ifndef WC_NO_RNG - static byte seed[sizeof(word32)] = { 0x00, 0x00, 0x00, 0x01 }; - word32* seedWord32 = (word32*)seed; - word32 len; - - /* wc_GenerateSeed is a local symbol so we need to fake the entropy. */ - while (info->seed.sz > 0) { - len = (word32)sizeof(seed); - if (info->seed.sz < len) - len = info->seed.sz; - XMEMCPY(info->seed.seed, seed, sizeof(seed)); - info->seed.seed += len; - info->seed.sz -= len; - (*seedWord32)++; - } - - ret = 0; - #endif - } - else if (info->algo_type == WC_ALGO_TYPE_PK) { - #ifndef NO_RSA - if (info->pk.type == WC_PK_TYPE_RSA) { - /* set devId to invalid, so software is used */ - info->pk.rsa.key->devId = INVALID_DEVID; - - switch (info->pk.rsa.type) { - case RSA_PUBLIC_ENCRYPT: - case RSA_PUBLIC_DECRYPT: - /* perform software based RSA public op */ - ret = wc_RsaFunction( - info->pk.rsa.in, info->pk.rsa.inLen, - info->pk.rsa.out, info->pk.rsa.outLen, - info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); - break; - case RSA_PRIVATE_ENCRYPT: - case RSA_PRIVATE_DECRYPT: - /* perform software based RSA private op */ - ret = wc_RsaFunction( - info->pk.rsa.in, info->pk.rsa.inLen, - info->pk.rsa.out, info->pk.rsa.outLen, - info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); - break; - } - - /* reset devId */ - info->pk.rsa.key->devId = devIdArg; - } - #ifdef WOLFSSL_KEY_GEN - else if (info->pk.type == WC_PK_TYPE_RSA_KEYGEN) { - info->pk.rsakg.key->devId = INVALID_DEVID; - - ret = wc_MakeRsaKey(info->pk.rsakg.key, info->pk.rsakg.size, - info->pk.rsakg.e, info->pk.rsakg.rng); - - /* reset devId */ - info->pk.rsakg.key->devId = devIdArg; - } - #endif - #endif /* !NO_RSA */ - #ifdef HAVE_ECC - if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) { - /* set devId to invalid, so software is used */ - info->pk.eckg.key->devId = INVALID_DEVID; - - ret = wc_ecc_make_key_ex(info->pk.eckg.rng, info->pk.eckg.size, - info->pk.eckg.key, info->pk.eckg.curveId); - - /* reset devId */ - info->pk.eckg.key->devId = devIdArg; - } - else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { - /* set devId to invalid, so software is used */ - info->pk.eccsign.key->devId = INVALID_DEVID; - - ret = wc_ecc_sign_hash( - info->pk.eccsign.in, info->pk.eccsign.inlen, - info->pk.eccsign.out, info->pk.eccsign.outlen, - info->pk.eccsign.rng, info->pk.eccsign.key); - - /* reset devId */ - info->pk.eccsign.key->devId = devIdArg; - } - else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { - /* set devId to invalid, so software is used */ - info->pk.eccverify.key->devId = INVALID_DEVID; - - ret = wc_ecc_verify_hash( - info->pk.eccverify.sig, info->pk.eccverify.siglen, - info->pk.eccverify.hash, info->pk.eccverify.hashlen, - info->pk.eccverify.res, info->pk.eccverify.key); - - /* reset devId */ - info->pk.eccverify.key->devId = devIdArg; - } - else if (info->pk.type == WC_PK_TYPE_ECDH) { - /* set devId to invalid, so software is used */ - info->pk.ecdh.private_key->devId = INVALID_DEVID; - - ret = wc_ecc_shared_secret( - info->pk.ecdh.private_key, info->pk.ecdh.public_key, - info->pk.ecdh.out, info->pk.ecdh.outlen); - - /* reset devId */ - info->pk.ecdh.private_key->devId = devIdArg; - } - #endif /* HAVE_ECC */ - } - else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { -#if !defined(NO_AES) || !defined(NO_DES3) - #ifdef HAVE_AESGCM - if (info->cipher.type == WC_CIPHER_AES_GCM) { - if (info->cipher.enc) { - /* set devId to invalid, so software is used */ - info->cipher.aesgcm_enc.aes->devId = INVALID_DEVID; - - ret = wc_AesGcmEncrypt( - info->cipher.aesgcm_enc.aes, - info->cipher.aesgcm_enc.out, - info->cipher.aesgcm_enc.in, - info->cipher.aesgcm_enc.sz, - info->cipher.aesgcm_enc.iv, - info->cipher.aesgcm_enc.ivSz, - info->cipher.aesgcm_enc.authTag, - info->cipher.aesgcm_enc.authTagSz, - info->cipher.aesgcm_enc.authIn, - info->cipher.aesgcm_enc.authInSz); - - /* reset devId */ - info->cipher.aesgcm_enc.aes->devId = devIdArg; - } - else { - /* set devId to invalid, so software is used */ - info->cipher.aesgcm_dec.aes->devId = INVALID_DEVID; - - ret = wc_AesGcmDecrypt( - info->cipher.aesgcm_dec.aes, - info->cipher.aesgcm_dec.out, - info->cipher.aesgcm_dec.in, - info->cipher.aesgcm_dec.sz, - info->cipher.aesgcm_dec.iv, - info->cipher.aesgcm_dec.ivSz, - info->cipher.aesgcm_dec.authTag, - info->cipher.aesgcm_dec.authTagSz, - info->cipher.aesgcm_dec.authIn, - info->cipher.aesgcm_dec.authInSz); - - /* reset devId */ - info->cipher.aesgcm_dec.aes->devId = devIdArg; - } - } - #endif /* HAVE_AESGCM */ - #ifdef HAVE_AES_CBC - if (info->cipher.type == WC_CIPHER_AES_CBC) { - if (info->cipher.enc) { - /* set devId to invalid, so software is used */ - info->cipher.aescbc.aes->devId = INVALID_DEVID; - - ret = wc_AesCbcEncrypt( - info->cipher.aescbc.aes, - info->cipher.aescbc.out, - info->cipher.aescbc.in, - info->cipher.aescbc.sz); - - /* reset devId */ - info->cipher.aescbc.aes->devId = devIdArg; - } - else { - /* set devId to invalid, so software is used */ - info->cipher.aescbc.aes->devId = INVALID_DEVID; - - ret = wc_AesCbcDecrypt( - info->cipher.aescbc.aes, - info->cipher.aescbc.out, - info->cipher.aescbc.in, - info->cipher.aescbc.sz); - - /* reset devId */ - info->cipher.aescbc.aes->devId = devIdArg; - } - } - #endif /* HAVE_AES_CBC */ - #ifndef NO_DES3 - if (info->cipher.type == WC_CIPHER_DES3) { - if (info->cipher.enc) { - /* set devId to invalid, so software is used */ - info->cipher.des3.des->devId = INVALID_DEVID; - - ret = wc_Des3_CbcEncrypt( - info->cipher.des3.des, - info->cipher.des3.out, - info->cipher.des3.in, - info->cipher.des3.sz); - - /* reset devId */ - info->cipher.des3.des->devId = devIdArg; - } - else { - /* set devId to invalid, so software is used */ - info->cipher.des3.des->devId = INVALID_DEVID; - - ret = wc_Des3_CbcDecrypt( - info->cipher.des3.des, - info->cipher.des3.out, - info->cipher.des3.in, - info->cipher.des3.sz); - - /* reset devId */ - info->cipher.des3.des->devId = devIdArg; - } - } - #endif /* !NO_DES3 */ -#endif /* !NO_AES || !NO_DES3 */ - } - else if (info->algo_type == WC_ALGO_TYPE_HASH) { -#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \ - defined(WOLFSSL_SHA512) - #if !defined(NO_SHA) - if (info->hash.type == WC_HASH_TYPE_SHA) { - if (info->hash.sha1 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha1->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx, - info->hash.sha1->flags); - - /* reset devId */ - info->hash.sha1->devId = devIdArg; - } - else - #endif - #if !defined(NO_SHA256) - if (info->hash.type == WC_HASH_TYPE_SHA256) { - if (info->hash.sha256 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha256->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx, - info->hash.sha256->flags); - - /* reset devId */ - info->hash.sha256->devId = devIdArg; - } - else - #endif - #ifdef WOLFSSL_SHA384 - if (info->hash.type == WC_HASH_TYPE_SHA384) { - if (info->hash.sha384 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha384->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx, - info->hash.sha384->flags); - - /* reset devId */ - info->hash.sha384->devId = devIdArg; - } - else - #endif - #ifdef WOLFSSL_SHA512 - if (info->hash.type == WC_HASH_TYPE_SHA512) { - if (info->hash.sha512 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha512->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx, - info->hash.sha512->flags); - - /* reset devId */ - info->hash.sha512->devId = devIdArg; - } - else - #endif - { - } -#endif /* !NO_SHA || !NO_SHA256 || WOLFSSL_SHA384 || WOLFSSL_SHA512 */ - } - else if (info->algo_type == WC_ALGO_TYPE_HMAC) { -#ifndef NO_HMAC - if (info->hmac.hmac == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hmac.hmac->devId = INVALID_DEVID; - - if (info->hmac.in != NULL) { - ret = wc_HmacUpdate( - info->hmac.hmac, - info->hmac.in, - info->hmac.inSz); - } - else if (info->hmac.digest != NULL) { - ret = wc_HmacFinal( - info->hmac.hmac, - info->hmac.digest); - } - - /* reset devId */ - info->hmac.hmac->devId = devIdArg; -#endif - } - - (void)devIdArg; - (void)myCtx; - - return ret; -} -#endif /* WOLF_CRYPTO_CB */ int main(int argc, char** argv) { @@ -558,14 +127,12 @@ int main(int argc, char** argv) goto exit; } -#if 1 /* register a devID for crypto callbacks */ ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); if (ret != 0) { fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); goto exit; } -#endif /* Create and initialize WOLFSSL_CTX */ #ifdef USE_TLSV13 diff --git a/tls/cryptocb-common.c b/tls/cryptocb-common.c new file mode 100644 index 00000000..d4aac2e9 --- /dev/null +++ b/tls/cryptocb-common.c @@ -0,0 +1,452 @@ +/* crypto-common.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "cryptocb-common.h" + +#ifdef WOLF_CRYPTO_CB + +typedef struct { + word32 bufSz; +} hash_ctx_t; + +#ifdef USE_OPENSSL +#include +#endif + +/* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ +/* in: Update (when not NULL) / Final (when NULL) */ +static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, + void* shactx, void** devCtx, word32 flags) +{ + int ret = 0; + enum wc_HashType hash_type = (enum wc_HashType)type; + hash_ctx_t* ctx = (hash_ctx_t*)*devCtx; + byte* hashBuf = NULL; + word32 hashBufSz = 0; + + /* for updates alloc/realloc and copy */ + if (in != NULL) { + if (ctx == NULL) { + ctx = (hash_ctx_t*)malloc(sizeof(hash_ctx_t) + hashBufSz + inSz); + } + else { + hashBufSz = ctx->bufSz; + ctx = (hash_ctx_t*)realloc(ctx, sizeof(hash_ctx_t) + hashBufSz + inSz); + } + if (ctx == NULL) { + return MEMORY_E; + } + hashBuf = (byte*)ctx + sizeof(hash_ctx_t); + memcpy(&hashBuf[hashBufSz], in, inSz); + ctx->bufSz = hashBufSz + inSz; + *devCtx = ctx; + } + /* final */ + else if (digest != NULL) { + if (ctx == NULL) { + /* valid case of empty hash (0 len hash) */ + } + else { + hashBuf = (byte*)ctx + sizeof(hash_ctx_t); + hashBufSz = ctx->bufSz; + } + +#ifdef USE_OPENSSL + switch (hash_type) { + case WC_HASH_TYPE_SHA: + SHA1(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA224: + SHA224(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA256: + SHA256(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA384: + SHA384(hashBuf, hashBufSz, digest); + break; + case WC_HASH_TYPE_SHA512: + SHA512(hashBuf, hashBufSz, digest); + break; + default: + ret = NOT_COMPILED_IN; + break; + } +#else + ret = wc_Hash_ex(hash_type, + hashBuf, hashBufSz, + digest, wc_HashGetDigestSize(hash_type), + NULL, INVALID_DEVID); +#endif + if (!(flags & WC_HASH_FLAG_ISCOPY)) { + free(ctx); + *devCtx = NULL; + } + } + return ret; +} + +/* Example crypto dev callback function that calls software version */ +/* This is where you would plug-in calls to your own hardware crypto */ +int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */ + myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx; + + if (info == NULL) + return BAD_FUNC_ARG; + +#ifdef DEBUG_CRYPTOCB + wc_CryptoCb_InfoString(info); +#endif + + if (info->algo_type == WC_ALGO_TYPE_RNG) { + #ifndef WC_NO_RNG + /* set devId to invalid, so software is used */ + info->rng.rng->devId = INVALID_DEVID; + + ret = wc_RNG_GenerateBlock(info->rng.rng, + info->rng.out, info->rng.sz); + + /* reset devId */ + info->rng.rng->devId = devIdArg; + #endif + } + else if (info->algo_type == WC_ALGO_TYPE_SEED) { + #ifndef WC_NO_RNG + static byte seed[sizeof(word32)] = { 0x00, 0x00, 0x00, 0x01 }; + word32* seedWord32 = (word32*)seed; + word32 len; + + /* wc_GenerateSeed is a local symbol so we need to fake the entropy. */ + while (info->seed.sz > 0) { + len = (word32)sizeof(seed); + if (info->seed.sz < len) + len = info->seed.sz; + XMEMCPY(info->seed.seed, seed, sizeof(seed)); + info->seed.seed += len; + info->seed.sz -= len; + (*seedWord32)++; + } + + ret = 0; + #endif + } + else if (info->algo_type == WC_ALGO_TYPE_PK) { + #ifndef NO_RSA + if (info->pk.type == WC_PK_TYPE_RSA) { + /* set devId to invalid, so software is used */ + info->pk.rsa.key->devId = INVALID_DEVID; + + switch (info->pk.rsa.type) { + case RSA_PUBLIC_ENCRYPT: + case RSA_PUBLIC_DECRYPT: + /* perform software based RSA public op */ + ret = wc_RsaFunction( + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, info->pk.rsa.outLen, + info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); + break; + case RSA_PRIVATE_ENCRYPT: + case RSA_PRIVATE_DECRYPT: + /* perform software based RSA private op */ + ret = wc_RsaFunction( + info->pk.rsa.in, info->pk.rsa.inLen, + info->pk.rsa.out, info->pk.rsa.outLen, + info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); + break; + } + + /* reset devId */ + info->pk.rsa.key->devId = devIdArg; + } + #ifdef WOLFSSL_KEY_GEN + else if (info->pk.type == WC_PK_TYPE_RSA_KEYGEN) { + info->pk.rsakg.key->devId = INVALID_DEVID; + + ret = wc_MakeRsaKey(info->pk.rsakg.key, info->pk.rsakg.size, + info->pk.rsakg.e, info->pk.rsakg.rng); + + /* reset devId */ + info->pk.rsakg.key->devId = devIdArg; + } + #endif + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) { + /* set devId to invalid, so software is used */ + info->pk.eckg.key->devId = INVALID_DEVID; + + ret = wc_ecc_make_key_ex(info->pk.eckg.rng, info->pk.eckg.size, + info->pk.eckg.key, info->pk.eckg.curveId); + + /* reset devId */ + info->pk.eckg.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + /* set devId to invalid, so software is used */ + info->pk.eccsign.key->devId = INVALID_DEVID; + + ret = wc_ecc_sign_hash( + info->pk.eccsign.in, info->pk.eccsign.inlen, + info->pk.eccsign.out, info->pk.eccsign.outlen, + info->pk.eccsign.rng, info->pk.eccsign.key); + + /* reset devId */ + info->pk.eccsign.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + /* set devId to invalid, so software is used */ + info->pk.eccverify.key->devId = INVALID_DEVID; + + ret = wc_ecc_verify_hash( + info->pk.eccverify.sig, info->pk.eccverify.siglen, + info->pk.eccverify.hash, info->pk.eccverify.hashlen, + info->pk.eccverify.res, info->pk.eccverify.key); + + /* reset devId */ + info->pk.eccverify.key->devId = devIdArg; + } + else if (info->pk.type == WC_PK_TYPE_ECDH) { + /* set devId to invalid, so software is used */ + info->pk.ecdh.private_key->devId = INVALID_DEVID; + + ret = wc_ecc_shared_secret( + info->pk.ecdh.private_key, info->pk.ecdh.public_key, + info->pk.ecdh.out, info->pk.ecdh.outlen); + + /* reset devId */ + info->pk.ecdh.private_key->devId = devIdArg; + } + #endif /* HAVE_ECC */ + } + else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { +#if !defined(NO_AES) || !defined(NO_DES3) + #ifdef HAVE_AESGCM + if (info->cipher.type == WC_CIPHER_AES_GCM) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.aesgcm_enc.aes->devId = INVALID_DEVID; + + ret = wc_AesGcmEncrypt( + info->cipher.aesgcm_enc.aes, + info->cipher.aesgcm_enc.out, + info->cipher.aesgcm_enc.in, + info->cipher.aesgcm_enc.sz, + info->cipher.aesgcm_enc.iv, + info->cipher.aesgcm_enc.ivSz, + info->cipher.aesgcm_enc.authTag, + info->cipher.aesgcm_enc.authTagSz, + info->cipher.aesgcm_enc.authIn, + info->cipher.aesgcm_enc.authInSz); + + /* reset devId */ + info->cipher.aesgcm_enc.aes->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.aesgcm_dec.aes->devId = INVALID_DEVID; + + ret = wc_AesGcmDecrypt( + info->cipher.aesgcm_dec.aes, + info->cipher.aesgcm_dec.out, + info->cipher.aesgcm_dec.in, + info->cipher.aesgcm_dec.sz, + info->cipher.aesgcm_dec.iv, + info->cipher.aesgcm_dec.ivSz, + info->cipher.aesgcm_dec.authTag, + info->cipher.aesgcm_dec.authTagSz, + info->cipher.aesgcm_dec.authIn, + info->cipher.aesgcm_dec.authInSz); + + /* reset devId */ + info->cipher.aesgcm_dec.aes->devId = devIdArg; + } + } + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AES_CBC + if (info->cipher.type == WC_CIPHER_AES_CBC) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.aescbc.aes->devId = INVALID_DEVID; + + ret = wc_AesCbcEncrypt( + info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + + /* reset devId */ + info->cipher.aescbc.aes->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.aescbc.aes->devId = INVALID_DEVID; + + ret = wc_AesCbcDecrypt( + info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + + /* reset devId */ + info->cipher.aescbc.aes->devId = devIdArg; + } + } + #endif /* HAVE_AES_CBC */ + #ifndef NO_DES3 + if (info->cipher.type == WC_CIPHER_DES3) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.des3.des->devId = INVALID_DEVID; + + ret = wc_Des3_CbcEncrypt( + info->cipher.des3.des, + info->cipher.des3.out, + info->cipher.des3.in, + info->cipher.des3.sz); + + /* reset devId */ + info->cipher.des3.des->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.des3.des->devId = INVALID_DEVID; + + ret = wc_Des3_CbcDecrypt( + info->cipher.des3.des, + info->cipher.des3.out, + info->cipher.des3.in, + info->cipher.des3.sz); + + /* reset devId */ + info->cipher.des3.des->devId = devIdArg; + } + } + #endif /* !NO_DES3 */ +#endif /* !NO_AES || !NO_DES3 */ + } + else if (info->algo_type == WC_ALGO_TYPE_HASH) { +#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \ + defined(WOLFSSL_SHA512) + #if !defined(NO_SHA) + if (info->hash.type == WC_HASH_TYPE_SHA) { + if (info->hash.sha1 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha1->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx, + info->hash.sha1->flags); + + /* reset devId */ + info->hash.sha1->devId = devIdArg; + } + else + #endif + #if !defined(NO_SHA256) + if (info->hash.type == WC_HASH_TYPE_SHA256) { + if (info->hash.sha256 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha256->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx, + info->hash.sha256->flags); + + /* reset devId */ + info->hash.sha256->devId = devIdArg; + } + else + #endif + #ifdef WOLFSSL_SHA384 + if (info->hash.type == WC_HASH_TYPE_SHA384) { + if (info->hash.sha384 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha384->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx, + info->hash.sha384->flags); + + /* reset devId */ + info->hash.sha384->devId = devIdArg; + } + else + #endif + #ifdef WOLFSSL_SHA512 + if (info->hash.type == WC_HASH_TYPE_SHA512) { + if (info->hash.sha512 == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hash.sha512->devId = INVALID_DEVID; + + ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, + info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx, + info->hash.sha512->flags); + + /* reset devId */ + info->hash.sha512->devId = devIdArg; + } + else + #endif + { + } +#endif /* !NO_SHA || !NO_SHA256 || WOLFSSL_SHA384 || WOLFSSL_SHA512 */ + } + else if (info->algo_type == WC_ALGO_TYPE_HMAC) { +#ifndef NO_HMAC + if (info->hmac.hmac == NULL) + return CRYPTOCB_UNAVAILABLE; + + /* set devId to invalid, so software is used */ + info->hmac.hmac->devId = INVALID_DEVID; + + if (info->hmac.in != NULL) { + ret = wc_HmacUpdate( + info->hmac.hmac, + info->hmac.in, + info->hmac.inSz); + } + else if (info->hmac.digest != NULL) { + ret = wc_HmacFinal( + info->hmac.hmac, + info->hmac.digest); + } + + /* reset devId */ + info->hmac.hmac->devId = devIdArg; +#endif + } + + (void)devIdArg; + (void)myCtx; + + return ret; +} +#endif /* WOLF_CRYPTO_CB */ diff --git a/tls/cryptocb-common.h b/tls/cryptocb-common.h new file mode 100644 index 00000000..958a53c3 --- /dev/null +++ b/tls/cryptocb-common.h @@ -0,0 +1,45 @@ +/* cryptocb-common.h + * + * Copyright (C) 2006-2020 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _CRYPTOCB_COMMON_H_ +#define _CRYPTOCB_COMMON_H_ + +/* wolfSSL */ +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#include +#include + +#ifdef WOLF_CRYPTO_CB + +/* Example custom context for crypto callback */ +typedef struct { + int exampleVar; /* example, not used */ +} myCryptoCbCtx; + +int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx); + +#endif /* WOLF_CRYPTO_CB */ + +#endif /* !_CRYPTOCB_COMMON_H_ */ diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c index 50d0ecc5..5c2d2ae1 100644 --- a/tls/server-tls-cryptocb.c +++ b/tls/server-tls-cryptocb.c @@ -39,6 +39,8 @@ #include #include +#include "cryptocb-common.h" + #define DEFAULT_PORT 11111 #define USE_ECDHE_ECDSA @@ -54,440 +56,6 @@ #define CA_FILE "../certs/client-cert.pem" #endif -#ifdef WOLF_CRYPTO_CB -/* Example custom context for crypto callback */ -typedef struct { - int exampleVar; /* example, not used */ -} myCryptoCbCtx; - -typedef struct { - word32 bufSz; -} hash_ctx_t; - -#ifdef USE_OPENSSL -#include -#endif - -/* type: WC_HASH_TYPE_SHA, WC_HASH_TYPE_SHA256, WC_HASH_TYPE_SHA384, etc */ -/* in: Update (when not NULL) / Final (when NULL) */ -static int cb_hash(int type, const byte* in, word32 inSz, byte* digest, - void* shactx, void** devCtx, word32 flags) -{ - int ret = 0; - enum wc_HashType hash_type = (enum wc_HashType)type; - hash_ctx_t* ctx = (hash_ctx_t*)*devCtx; - byte* hashBuf = NULL; - word32 hashBufSz = 0; - - /* for updates alloc/realloc and copy */ - if (in != NULL) { - if (ctx == NULL) { - ctx = (hash_ctx_t*)malloc(sizeof(hash_ctx_t) + hashBufSz + inSz); - } - else { - hashBufSz = ctx->bufSz; - ctx = (hash_ctx_t*)realloc(ctx, sizeof(hash_ctx_t) + hashBufSz + inSz); - } - if (ctx == NULL) { - return MEMORY_E; - } - hashBuf = (byte*)ctx + sizeof(hash_ctx_t); - memcpy(&hashBuf[hashBufSz], in, inSz); - ctx->bufSz = hashBufSz + inSz; - *devCtx = ctx; - } - /* final */ - else if (digest != NULL) { - if (ctx == NULL) { - /* valid case of empty hash (0 len hash) */ - } - else { - hashBuf = (byte*)ctx + sizeof(hash_ctx_t); - hashBufSz = ctx->bufSz; - } - -#ifdef USE_OPENSSL - switch (hash_type) { - case WC_HASH_TYPE_SHA: - SHA1(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA224: - SHA224(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA256: - SHA256(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA384: - SHA384(hashBuf, hashBufSz, digest); - break; - case WC_HASH_TYPE_SHA512: - SHA512(hashBuf, hashBufSz, digest); - break; - default: - ret = NOT_COMPILED_IN; - break; - } -#else - ret = wc_Hash_ex(hash_type, - hashBuf, hashBufSz, - digest, wc_HashGetDigestSize(hash_type), - NULL, INVALID_DEVID); -#endif - if (!(flags & WC_HASH_FLAG_ISCOPY)) { - free(ctx); - *devCtx = NULL; - } - } - return ret; -} - -/* Example crypto dev callback function that calls software version */ -/* This is where you would plug-in calls to your own hardware crypto */ -static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) -{ - int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */ - myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx; - - if (info == NULL) - return BAD_FUNC_ARG; - -#ifdef DEBUG_CRYPTOCB - wc_CryptoCb_InfoString(info); -#endif - - if (info->algo_type == WC_ALGO_TYPE_RNG) { - #ifndef WC_NO_RNG - /* set devId to invalid, so software is used */ - info->rng.rng->devId = INVALID_DEVID; - - ret = wc_RNG_GenerateBlock(info->rng.rng, - info->rng.out, info->rng.sz); - - /* reset devId */ - info->rng.rng->devId = devIdArg; - #endif - } - else if (info->algo_type == WC_ALGO_TYPE_SEED) { - #ifndef WC_NO_RNG - static byte seed[sizeof(word32)] = { 0x00, 0x00, 0x00, 0x01 }; - word32* seedWord32 = (word32*)seed; - word32 len; - - /* wc_GenerateSeed is a local symbol so we need to fake the entropy. */ - while (info->seed.sz > 0) { - len = (word32)sizeof(seed); - if (info->seed.sz < len) - len = info->seed.sz; - XMEMCPY(info->seed.seed, seed, sizeof(seed)); - info->seed.seed += len; - info->seed.sz -= len; - (*seedWord32)++; - } - - ret = 0; - #endif - } - else if (info->algo_type == WC_ALGO_TYPE_PK) { - #ifndef NO_RSA - if (info->pk.type == WC_PK_TYPE_RSA) { - /* set devId to invalid, so software is used */ - info->pk.rsa.key->devId = INVALID_DEVID; - - switch (info->pk.rsa.type) { - case RSA_PUBLIC_ENCRYPT: - case RSA_PUBLIC_DECRYPT: - /* perform software based RSA public op */ - ret = wc_RsaFunction( - info->pk.rsa.in, info->pk.rsa.inLen, - info->pk.rsa.out, info->pk.rsa.outLen, - info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); - break; - case RSA_PRIVATE_ENCRYPT: - case RSA_PRIVATE_DECRYPT: - /* perform software based RSA private op */ - ret = wc_RsaFunction( - info->pk.rsa.in, info->pk.rsa.inLen, - info->pk.rsa.out, info->pk.rsa.outLen, - info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); - break; - } - - /* reset devId */ - info->pk.rsa.key->devId = devIdArg; - } - #ifdef WOLFSSL_KEY_GEN - else if (info->pk.type == WC_PK_TYPE_RSA_KEYGEN) { - info->pk.rsakg.key->devId = INVALID_DEVID; - - ret = wc_MakeRsaKey(info->pk.rsakg.key, info->pk.rsakg.size, - info->pk.rsakg.e, info->pk.rsakg.rng); - - /* reset devId */ - info->pk.rsakg.key->devId = devIdArg; - } - #endif - #endif /* !NO_RSA */ - #ifdef HAVE_ECC - if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) { - /* set devId to invalid, so software is used */ - info->pk.eckg.key->devId = INVALID_DEVID; - - ret = wc_ecc_make_key_ex(info->pk.eckg.rng, info->pk.eckg.size, - info->pk.eckg.key, info->pk.eckg.curveId); - - /* reset devId */ - info->pk.eckg.key->devId = devIdArg; - } - else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { - /* set devId to invalid, so software is used */ - info->pk.eccsign.key->devId = INVALID_DEVID; - - ret = wc_ecc_sign_hash( - info->pk.eccsign.in, info->pk.eccsign.inlen, - info->pk.eccsign.out, info->pk.eccsign.outlen, - info->pk.eccsign.rng, info->pk.eccsign.key); - - /* reset devId */ - info->pk.eccsign.key->devId = devIdArg; - } - else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { - /* set devId to invalid, so software is used */ - info->pk.eccverify.key->devId = INVALID_DEVID; - - ret = wc_ecc_verify_hash( - info->pk.eccverify.sig, info->pk.eccverify.siglen, - info->pk.eccverify.hash, info->pk.eccverify.hashlen, - info->pk.eccverify.res, info->pk.eccverify.key); - - /* reset devId */ - info->pk.eccverify.key->devId = devIdArg; - } - else if (info->pk.type == WC_PK_TYPE_ECDH) { - /* set devId to invalid, so software is used */ - info->pk.ecdh.private_key->devId = INVALID_DEVID; - - ret = wc_ecc_shared_secret( - info->pk.ecdh.private_key, info->pk.ecdh.public_key, - info->pk.ecdh.out, info->pk.ecdh.outlen); - - /* reset devId */ - info->pk.ecdh.private_key->devId = devIdArg; - } - #endif /* HAVE_ECC */ - } - else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { -#if !defined(NO_AES) || !defined(NO_DES3) - #ifdef HAVE_AESGCM - if (info->cipher.type == WC_CIPHER_AES_GCM) { - if (info->cipher.enc) { - /* set devId to invalid, so software is used */ - info->cipher.aesgcm_enc.aes->devId = INVALID_DEVID; - - ret = wc_AesGcmEncrypt( - info->cipher.aesgcm_enc.aes, - info->cipher.aesgcm_enc.out, - info->cipher.aesgcm_enc.in, - info->cipher.aesgcm_enc.sz, - info->cipher.aesgcm_enc.iv, - info->cipher.aesgcm_enc.ivSz, - info->cipher.aesgcm_enc.authTag, - info->cipher.aesgcm_enc.authTagSz, - info->cipher.aesgcm_enc.authIn, - info->cipher.aesgcm_enc.authInSz); - - /* reset devId */ - info->cipher.aesgcm_enc.aes->devId = devIdArg; - } - else { - /* set devId to invalid, so software is used */ - info->cipher.aesgcm_dec.aes->devId = INVALID_DEVID; - - ret = wc_AesGcmDecrypt( - info->cipher.aesgcm_dec.aes, - info->cipher.aesgcm_dec.out, - info->cipher.aesgcm_dec.in, - info->cipher.aesgcm_dec.sz, - info->cipher.aesgcm_dec.iv, - info->cipher.aesgcm_dec.ivSz, - info->cipher.aesgcm_dec.authTag, - info->cipher.aesgcm_dec.authTagSz, - info->cipher.aesgcm_dec.authIn, - info->cipher.aesgcm_dec.authInSz); - - /* reset devId */ - info->cipher.aesgcm_dec.aes->devId = devIdArg; - } - } - #endif /* HAVE_AESGCM */ - #ifdef HAVE_AES_CBC - if (info->cipher.type == WC_CIPHER_AES_CBC) { - if (info->cipher.enc) { - /* set devId to invalid, so software is used */ - info->cipher.aescbc.aes->devId = INVALID_DEVID; - - ret = wc_AesCbcEncrypt( - info->cipher.aescbc.aes, - info->cipher.aescbc.out, - info->cipher.aescbc.in, - info->cipher.aescbc.sz); - - /* reset devId */ - info->cipher.aescbc.aes->devId = devIdArg; - } - else { - /* set devId to invalid, so software is used */ - info->cipher.aescbc.aes->devId = INVALID_DEVID; - - ret = wc_AesCbcDecrypt( - info->cipher.aescbc.aes, - info->cipher.aescbc.out, - info->cipher.aescbc.in, - info->cipher.aescbc.sz); - - /* reset devId */ - info->cipher.aescbc.aes->devId = devIdArg; - } - } - #endif /* HAVE_AES_CBC */ - #ifndef NO_DES3 - if (info->cipher.type == WC_CIPHER_DES3) { - if (info->cipher.enc) { - /* set devId to invalid, so software is used */ - info->cipher.des3.des->devId = INVALID_DEVID; - - ret = wc_Des3_CbcEncrypt( - info->cipher.des3.des, - info->cipher.des3.out, - info->cipher.des3.in, - info->cipher.des3.sz); - - /* reset devId */ - info->cipher.des3.des->devId = devIdArg; - } - else { - /* set devId to invalid, so software is used */ - info->cipher.des3.des->devId = INVALID_DEVID; - - ret = wc_Des3_CbcDecrypt( - info->cipher.des3.des, - info->cipher.des3.out, - info->cipher.des3.in, - info->cipher.des3.sz); - - /* reset devId */ - info->cipher.des3.des->devId = devIdArg; - } - } - #endif /* !NO_DES3 */ -#endif /* !NO_AES || !NO_DES3 */ - } - else if (info->algo_type == WC_ALGO_TYPE_HASH) { -#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \ - defined(WOLFSSL_SHA512) - #if !defined(NO_SHA) - if (info->hash.type == WC_HASH_TYPE_SHA) { - if (info->hash.sha1 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha1->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha1, &info->hash.sha1->devCtx, - info->hash.sha1->flags); - - /* reset devId */ - info->hash.sha1->devId = devIdArg; - } - else - #endif - #if !defined(NO_SHA256) - if (info->hash.type == WC_HASH_TYPE_SHA256) { - if (info->hash.sha256 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha256->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha256, &info->hash.sha256->devCtx, - info->hash.sha256->flags); - - /* reset devId */ - info->hash.sha256->devId = devIdArg; - } - else - #endif - #ifdef WOLFSSL_SHA384 - if (info->hash.type == WC_HASH_TYPE_SHA384) { - if (info->hash.sha384 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha384->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha384, &info->hash.sha384->devCtx, - info->hash.sha384->flags); - - /* reset devId */ - info->hash.sha384->devId = devIdArg; - } - else - #endif - #ifdef WOLFSSL_SHA512 - if (info->hash.type == WC_HASH_TYPE_SHA512) { - if (info->hash.sha512 == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hash.sha512->devId = INVALID_DEVID; - - ret = cb_hash(info->hash.type, info->hash.in, info->hash.inSz, - info->hash.digest, info->hash.sha512, &info->hash.sha512->devCtx, - info->hash.sha512->flags); - - /* reset devId */ - info->hash.sha512->devId = devIdArg; - } - else - #endif - { - } -#endif /* !NO_SHA || !NO_SHA256 || WOLFSSL_SHA384 || WOLFSSL_SHA512 */ - } - else if (info->algo_type == WC_ALGO_TYPE_HMAC) { -#ifndef NO_HMAC - if (info->hmac.hmac == NULL) - return CRYPTOCB_UNAVAILABLE; - - /* set devId to invalid, so software is used */ - info->hmac.hmac->devId = INVALID_DEVID; - - if (info->hmac.in != NULL) { - ret = wc_HmacUpdate( - info->hmac.hmac, - info->hmac.in, - info->hmac.inSz); - } - else if (info->hmac.digest != NULL) { - ret = wc_HmacFinal( - info->hmac.hmac, - info->hmac.digest); - } - - /* reset devId */ - info->hmac.hmac->devId = devIdArg; -#endif - } - - (void)devIdArg; - (void)myCtx; - - return ret; -} -#endif /* WOLF_CRYPTO_CB */ - int main(int argc, char** argv) { @@ -523,14 +91,12 @@ int main(int argc, char** argv) memset(&myCtx, 0, sizeof(myCtx)); myCtx.exampleVar = 1; -#if 1 /* register a devID for crypto callbacks */ ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx); if (ret != 0) { fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed %d\n", ret); goto exit; } -#endif /* Create and initialize WOLFSSL_CTX */ #ifdef USE_TLSV13 diff --git a/tls/server-tls.c b/tls/server-tls.c index 09cd0ea0..a3ab5ad6 100644 --- a/tls/server-tls.c +++ b/tls/server-tls.c @@ -80,7 +80,7 @@ int main() /* Create and initialize WOLFSSL_CTX */ - if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) { + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); ret = -1; goto exit; From ab0d633d5b94d016e2887cdee928ddf8a888dfa6 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 10 Jan 2024 17:26:55 -0800 Subject: [PATCH 9/9] Peer review cleanups 2. --- tls/client-tls-cryptocb.c | 12 ++++++------ tls/server-tls-cryptocb.c | 13 ++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/tls/client-tls-cryptocb.c b/tls/client-tls-cryptocb.c index e835c4c2..03a91c81 100644 --- a/tls/client-tls-cryptocb.c +++ b/tls/client-tls-cryptocb.c @@ -178,7 +178,9 @@ int main(int argc, char** argv) wolfSSL_CTX_SetDevId(ctx, devId); #if 0 - /* Example: "TLS13-AES256-GCM-SHA384", "TLS13-AES128-GCM-SHA256" or "TLS13-CHACHA20-POLY1305-SHA256" */ + /* Examples: "TLS13-AES256-GCM-SHA384", + * "TLS13-AES128-GCM-SHA256" or + * "TLS13-CHACHA20-POLY1305-SHA256" */ wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); #endif @@ -243,12 +245,10 @@ int main(int argc, char** argv) exit: /* Cleanup and return */ + wolfSSL_free(ssl); /* Free the wolfSSL object */ if (sockfd != SOCKET_INVALID) - close(sockfd); /* Close the connection to the server */ - if (ssl != NULL) - wolfSSL_free(ssl); /* Free the wolfSSL object */ - if (ctx != NULL) - wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + close(sockfd); /* Close the connection to the server */ + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ #else diff --git a/tls/server-tls-cryptocb.c b/tls/server-tls-cryptocb.c index 5c2d2ae1..3d5dc53c 100644 --- a/tls/server-tls-cryptocb.c +++ b/tls/server-tls-cryptocb.c @@ -142,7 +142,9 @@ int main(int argc, char** argv) WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); #if 0 - /* Example: "TLS13-AES256-GCM-SHA384", "TLS13-AES128-GCM-SHA256" or "TLS13-CHACHA20-POLY1305-SHA256" */ + /* Examples: "TLS13-AES256-GCM-SHA384", + * "TLS13-AES128-GCM-SHA256" or + * "TLS13-CHACHA20-POLY1305-SHA256" */ wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"); #endif @@ -238,7 +240,6 @@ int main(int argc, char** argv) } - /* Write our reply into buff */ memset(buff, 0, sizeof(buff)); memcpy(buff, reply, strlen(reply)); @@ -264,14 +265,12 @@ int main(int argc, char** argv) exit: /* Cleanup and return */ - if (ssl) - wolfSSL_free(ssl); /* Free the wolfSSL object */ + wolfSSL_free(ssl); /* Free the wolfSSL object */ if (connd != SOCKET_INVALID) - close(connd); /* Close the connection to the client */ + close(connd); /* Close the connection to the client */ if (sockfd != SOCKET_INVALID) close(sockfd); /* Close the socket listening for clients */ - if (ctx) - wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ #else printf("Please configure wolfSSL with --enable-cryptocb and try again\n");