diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index bc161630c..09d9ee65a 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -9938,6 +9938,16 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (aes->devId != INVALID_DEVID) { + int ret = wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, + authTag, authTagSz, authIn, authInSz); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + } +#endif + XMEMSET(A, 0, sizeof(A)); XMEMCPY(B+1, nonce, nonceSz); lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz; @@ -10040,6 +10050,16 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (aes->devId != INVALID_DEVID) { + int ret = wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz, + authTag, authTagSz, authIn, authInSz); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + } +#endif + o = out; oSz = inSz; XMEMSET(A, 0, sizeof A); diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 0aac729c3..b06ef2552 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -578,6 +578,90 @@ int wc_CryptoCb_AesGcmDecrypt(Aes* aes, byte* out, } #endif /* HAVE_AESGCM */ +#ifdef HAVE_AESCCM +int wc_CryptoCb_AesCcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* nonce, word32 nonceSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + int ret = CRYPTOCB_UNAVAILABLE; + CryptoCb* dev; + + /* locate registered callback */ + if (aes) { + dev = wc_CryptoCb_FindDevice(aes->devId); + } + else { + /* locate first callback and try using it */ + dev = wc_CryptoCb_FindDeviceByIndex(0); + } + + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER; + cryptoInfo.cipher.type = WC_CIPHER_AES_CCM; + cryptoInfo.cipher.enc = 1; + cryptoInfo.cipher.aesccm_enc.aes = aes; + cryptoInfo.cipher.aesccm_enc.out = out; + cryptoInfo.cipher.aesccm_enc.in = in; + cryptoInfo.cipher.aesccm_enc.sz = sz; + cryptoInfo.cipher.aesccm_enc.nonce = nonce; + cryptoInfo.cipher.aesccm_enc.nonceSz = nonceSz; + cryptoInfo.cipher.aesccm_enc.authTag = authTag; + cryptoInfo.cipher.aesccm_enc.authTagSz = authTagSz; + cryptoInfo.cipher.aesccm_enc.authIn = authIn; + cryptoInfo.cipher.aesccm_enc.authInSz = authInSz; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} + +int wc_CryptoCb_AesCcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* nonce, word32 nonceSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + int ret = CRYPTOCB_UNAVAILABLE; + CryptoCb* dev; + + /* locate registered callback */ + if (aes) { + dev = wc_CryptoCb_FindDevice(aes->devId); + } + else { + /* locate first callback and try using it */ + dev = wc_CryptoCb_FindDeviceByIndex(0); + } + + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER; + cryptoInfo.cipher.type = WC_CIPHER_AES_CCM; + cryptoInfo.cipher.enc = 0; + cryptoInfo.cipher.aesccm_dec.aes = aes; + cryptoInfo.cipher.aesccm_dec.out = out; + cryptoInfo.cipher.aesccm_dec.in = in; + cryptoInfo.cipher.aesccm_dec.sz = sz; + cryptoInfo.cipher.aesccm_enc.nonce = nonce; + cryptoInfo.cipher.aesccm_enc.nonceSz = nonceSz; + cryptoInfo.cipher.aesccm_dec.authTag = authTag; + cryptoInfo.cipher.aesccm_dec.authTagSz = authTagSz; + cryptoInfo.cipher.aesccm_dec.authIn = authIn; + cryptoInfo.cipher.aesccm_dec.authInSz = authInSz; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} +#endif /* HAVE_AESCCM */ + #ifdef HAVE_AES_CBC int wc_CryptoCb_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 10c4da4cb..13dbdd4ce 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -38159,6 +38159,48 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) } } #endif /* HAVE_AES_CBC */ + #if defined(HAVE_AESCCM) && defined(WOLFSSL_AES_128) + if (info->cipher.type == WC_CIPHER_AES_CCM) { + if (info->cipher.enc) { + /* set devId to invalid, so software is used */ + info->cipher.aesccm_enc.aes->devId = INVALID_DEVID; + + ret = wc_AesCcmEncrypt( + info->cipher.aesccm_enc.aes, + info->cipher.aesccm_enc.out, + info->cipher.aesccm_enc.in, + info->cipher.aesccm_enc.sz, + info->cipher.aesccm_enc.nonce, + info->cipher.aesccm_enc.nonceSz, + info->cipher.aesccm_enc.authTag, + info->cipher.aesccm_enc.authTagSz, + info->cipher.aesccm_enc.authIn, + info->cipher.aesccm_enc.authInSz); + + /* reset devId */ + info->cipher.aesccm_enc.aes->devId = devIdArg; + } + else { + /* set devId to invalid, so software is used */ + info->cipher.aesccm_dec.aes->devId = INVALID_DEVID; + + ret = wc_AesCcmDecrypt( + info->cipher.aesccm_dec.aes, + info->cipher.aesccm_dec.out, + info->cipher.aesccm_dec.in, + info->cipher.aesccm_dec.sz, + info->cipher.aesccm_dec.nonce, + info->cipher.aesccm_dec.nonceSz, + info->cipher.aesccm_dec.authTag, + info->cipher.aesccm_dec.authTagSz, + info->cipher.aesccm_dec.authIn, + info->cipher.aesccm_dec.authInSz); + + /* reset devId */ + info->cipher.aesccm_dec.aes->devId = devIdArg; + } + } + #endif #ifndef NO_DES3 if (info->cipher.type == WC_CIPHER_DES3) { if (info->cipher.enc) { @@ -38382,6 +38424,10 @@ WOLFSSL_TEST_SUBROUTINE int cryptocb_test(void) if (ret == 0) ret = aes_test(); #endif + #if defined(HAVE_AESCCM) && defined(WOLFSSL_AES_128) + if (ret == 0) + ret = aesccm_test(); + #endif #endif /* !NO_AES */ #ifndef NO_DES3 if (ret == 0) diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index f5a081f9a..f6b266461 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -225,6 +225,32 @@ typedef struct wc_CryptoInfo { word32 authInSz; } aesgcm_dec; #endif /* HAVE_AESGCM */ + #ifdef HAVE_AESCCM + struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + const byte* nonce; + word32 nonceSz; + byte* authTag; + word32 authTagSz; + const byte* authIn; + word32 authInSz; + } aesccm_enc; + struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + const byte* nonce; + word32 nonceSz; + const byte* authTag; + word32 authTagSz; + const byte* authIn; + word32 authInSz; + } aesccm_dec; + #endif /* HAVE_AESCCM */ #ifdef HAVE_AES_CBC struct { Aes* aes; @@ -385,6 +411,19 @@ WOLFSSL_LOCAL int wc_CryptoCb_AesGcmDecrypt(Aes* aes, byte* out, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz); #endif /* HAVE_AESGCM */ +#ifdef HAVE_AESCCM +WOLFSSL_LOCAL int wc_CryptoCb_AesCcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* nonce, word32 nonceSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + +WOLFSSL_LOCAL int wc_CryptoCb_AesCcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* nonce, word32 nonceSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); +#endif /* HAVE_AESCCM */ #ifdef HAVE_AES_CBC WOLFSSL_LOCAL int wc_CryptoCb_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 957b43cb6..0d18df297 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -955,13 +955,14 @@ decouple library dependencies with standard string, memory and so on. WC_CIPHER_AES_CTR = 4, WC_CIPHER_AES_XTS = 5, WC_CIPHER_AES_CFB = 6, + WC_CIPHER_AES_CCM = 12, WC_CIPHER_DES3 = 7, WC_CIPHER_DES = 8, WC_CIPHER_CHACHA = 9, WC_CIPHER_HC128 = 10, WC_CIPHER_IDEA = 11, - WC_CIPHER_MAX = WC_CIPHER_HC128 + WC_CIPHER_MAX = WC_CIPHER_AES_CCM }; /* PK=public key (asymmetric) based algorithms */