diff --git a/tests/api.c b/tests/api.c index 54dd016512..9ff4bbc014 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28972,13 +28972,81 @@ static int test_wc_CryptoCb(void) #if defined(WOLF_CRYPTO_CB) && \ (!defined(WOLF_CRYPTO_CB_ONLY_SHA256) && !defined(WOLF_CRYPTO_CB_ONLY_AES) && \ !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA)) - /* TODO: Add crypto callback API tests */ - -#ifdef HAVE_IO_TESTS_DEPENDENCIES - #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \ + (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)) int tlsVer; +#endif + /* Exercise the exposed CryptoCb device-management API: + * wc_CryptoCb_RegisterDevice / UnRegisterDevice / GetDevice / + * DefaultDevID (and InfoString when DEBUG_CRYPTOCB is enabled). */ + { + int getDevId = 1234; + int getDevCtx = 0; + CryptoCb* dev = NULL; + int i, n, rc; + + /* Unregistered devId is not found. */ + ExpectNull(wc_CryptoCb_GetDevice(getDevId)); + + /* After registering, the device is found with matching fields. */ + ExpectIntEQ(wc_CryptoCb_RegisterDevice(getDevId, NULL, &getDevCtx), 0); + ExpectNotNull(dev = wc_CryptoCb_GetDevice(getDevId)); + if (dev != NULL) { + ExpectIntEQ(dev->devId, getDevId); + ExpectNull(dev->cb); + ExpectPtrEq(dev->ctx, &getDevCtx); + } + + /* A different, unregistered devId is still not found. */ + ExpectNull(wc_CryptoCb_GetDevice(getDevId + 1)); + + /* Re-registering an already-registered devId is rejected. */ + ExpectIntEQ(wc_CryptoCb_RegisterDevice(getDevId, NULL, &getDevCtx), + WC_NO_ERR_TRACE(ALREADY_E)); + + /* wc_CryptoCb_DefaultDevID behavior depends on the build config. */ + #ifdef WC_NO_DEFAULT_DEVID + ExpectIntEQ(wc_CryptoCb_DefaultDevID(), INVALID_DEVID); + #elif !defined(WOLFSSL_CAAM_DEVID) && !defined(HAVE_ARIA) && \ + !defined(WC_USE_DEVID) + /* "first available" mode: a device is registered, so one is returned. */ + ExpectIntNE(wc_CryptoCb_DefaultDevID(), INVALID_DEVID); #endif + /* After unregistering, the device is no longer found. */ + wc_CryptoCb_UnRegisterDevice(getDevId); + ExpectNull(wc_CryptoCb_GetDevice(getDevId)); + + /* Unregistering is a harmless no-op for unknown or invalid devIds. */ + wc_CryptoCb_UnRegisterDevice(getDevId); /* already removed */ + wc_CryptoCb_UnRegisterDevice(INVALID_DEVID); /* never a real devId */ + ExpectNull(wc_CryptoCb_GetDevice(getDevId)); + + /* The device table is finite: once full, registration returns + * BUFFER_E. Register unique devIds until that happens, then clean up. + * The cap (256) just guards against an unexpectedly large table. */ + rc = 0; + for (i = 0; rc == 0 && i < 256; i++) { + rc = wc_CryptoCb_RegisterDevice(0x5000 + i, NULL, NULL); + } + ExpectIntEQ(rc, WC_NO_ERR_TRACE(BUFFER_E)); + /* Every id except the final failed attempt registered; unregister them. */ + for (n = 0; n + 1 < i; n++) { + wc_CryptoCb_UnRegisterDevice(0x5000 + n); + } + + #ifdef DEBUG_CRYPTOCB + /* wc_CryptoCb_InfoString smoke test: must not dereference bad memory. */ + { + wc_CryptoInfo info; + XMEMSET(&info, 0, sizeof(info)); + info.algo_type = WC_ALGO_TYPE_NONE; + wc_CryptoCb_InfoString(&info); + } + #endif + } + +#ifdef HAVE_IO_TESTS_DEPENDENCIES #ifndef NO_RSA for (tlsVer = WOLFSSL_SSLV3; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) { ExpectIntEQ(test_wc_CryptoCb_TLS(tlsVer, diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index c3af7ed608..e0cff6df16 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -74,11 +74,6 @@ Crypto Callback Build Options: #define MAX_CRYPTO_DEVID_CALLBACKS 8 #endif -typedef struct CryptoCb { - int devId; - CryptoDevCallbackFunc cb; - void* ctx; -} CryptoCb; static WC_THREADSHARED CryptoCb gCryptoDev[MAX_CRYPTO_DEVID_CALLBACKS]; #ifdef WOLF_CRYPTO_CB_FIND @@ -345,7 +340,7 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info) /* Search through listed devices and return the first matching device ID * found. */ -static CryptoCb* wc_CryptoCb_GetDevice(int devId) +CryptoCb* wc_CryptoCb_GetDevice(int devId) { int i; for (i = 0; i < MAX_CRYPTO_DEVID_CALLBACKS; i++) { @@ -441,12 +436,14 @@ void wc_CryptoCb_SetDeviceFindCb(CryptoDevCallbackFind cb) int wc_CryptoCb_RegisterDevice(int devId, CryptoDevCallbackFunc cb, void* ctx) { int rc = 0; + CryptoCb* dev; - /* find existing or new */ - CryptoCb* dev = wc_CryptoCb_GetDevice(devId); - if (dev == NULL) - dev = wc_CryptoCb_GetDevice(INVALID_DEVID); + /* Reject re-registration of an already-registered device ID. */ + if (wc_CryptoCb_GetDevice(devId) != NULL) + return ALREADY_E; + /* find a free slot */ + dev = wc_CryptoCb_GetDevice(INVALID_DEVID); if (dev == NULL) return BUFFER_E; /* out of devices */ diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index b0aaad2f37..34b30e6c69 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -672,12 +672,19 @@ typedef struct wc_CryptoInfo { typedef int (*CryptoDevCallbackFunc)(int devId, struct wc_CryptoInfo* info, void* ctx); +typedef struct CryptoCb { + int devId; + CryptoDevCallbackFunc cb; + void* ctx; +} CryptoCb; + WOLFSSL_LOCAL void wc_CryptoCb_Init(void); WOLFSSL_LOCAL void wc_CryptoCb_Cleanup(void); WOLFSSL_LOCAL int wc_CryptoCb_GetDevIdAtIndex(int startIdx); WOLFSSL_API int wc_CryptoCb_RegisterDevice(int devId, CryptoDevCallbackFunc cb, void* ctx); WOLFSSL_API void wc_CryptoCb_UnRegisterDevice(int devId); WOLFSSL_API int wc_CryptoCb_DefaultDevID(void); +WOLFSSL_API CryptoCb* wc_CryptoCb_GetDevice(int devId); #ifdef WOLF_CRYPTO_CB_FIND typedef int (*CryptoDevCallbackFind)(int devId, int algoType);