From 54f0b1a44a3f592581c7479f5ed85e50d1695f52 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 14 Oct 2019 13:55:51 -0400 Subject: [PATCH] Sync QAT Fixes 1. The QAT callback's worker functions need to copy the IV into the AES IV register. QAT doesn't update it automatically. 2. Update the GMAC test to set its device to INVALID_DEVID. 3. Always allocate NUMA buffers before running crypto operation and store the results. 4. The QAT does not like non-multiple of 4 iv lenths, and aad lengths. Or 0. Remove a few test cases for those. 5. QAT wasn't getting a pointer to store the auth tag for GCM. Then store it. --- wolfcrypt/src/port/intel/quickassist_sync.c | 70 ++++++++++++++------- wolfcrypt/test/test.c | 12 +++- 2 files changed, 56 insertions(+), 26 deletions(-) diff --git a/wolfcrypt/src/port/intel/quickassist_sync.c b/wolfcrypt/src/port/intel/quickassist_sync.c index 19a576000..c913b2870 100644 --- a/wolfcrypt/src/port/intel/quickassist_sync.c +++ b/wolfcrypt/src/port/intel/quickassist_sync.c @@ -743,7 +743,11 @@ static void IntelQaSymCipherFree(IntelQaDev* dev) dev->out = NULL; dev->outLen = 0; #ifndef NO_AES - dev->op.cipher.authTag = NULL; + if (dev->op.cipher.authTag != NULL) { + XMEMSET(dev->op.cipher.authTag, 0, dev->op.cipher.authTagSz); + XFREE(dev->op.cipher.authTag, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA); + dev->op.cipher.authTag = NULL; + } dev->op.cipher.authTagSz = 0; #endif } @@ -772,7 +776,9 @@ static int IntelQaSymCipher(IntelQaDev* dev, byte* out, const byte* in, Cpa32U metaSize = 0; Cpa8U* authInBuf = NULL; Cpa32U authInSzAligned = authInSz; + Cpa8U* authTagBuf = NULL; IntelQaSymCtx* ctx; + CpaBoolean verifyResult = CPA_FALSE; QLOG("IntelQaSymCipher: dev %p, out %p, in %p, inOutSz %d, op %d, " "algo %d, dir %d, hash %d\n", @@ -806,19 +812,15 @@ static int IntelQaSymCipher(IntelQaDev* dev, byte* out, const byte* in, bufferList = &dev->op.cipher.bufferList; flatBuffer = &dev->op.cipher.flatBuffer; metaBuf = XMALLOC(metaSize, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA); -#ifndef WOLFSSL_SNIFFER - dataBuf = XREALLOC((byte*)in, dataLen, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA); - ivBuf = XREALLOC((byte*)iv, AES_BLOCK_SIZE, dev->heap, - DYNAMIC_TYPE_ASYNC_NUMA); -#else dataBuf = XMALLOC(dataLen, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA); XMEMCPY(dataBuf, in, inOutSz); ivBuf = XMALLOC(AES_BLOCK_SIZE, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA); XMEMCPY(ivBuf, iv, ivSz); -#endif + authTagBuf = XMALLOC(authTagSz, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA); /* check allocations */ - if (ivBuf == NULL || metaBuf == NULL || dataBuf == NULL) { + if (ivBuf == NULL || metaBuf == NULL || dataBuf == NULL || + authTagBuf == NULL) { ret = MEMORY_E; goto exit; } @@ -830,14 +832,9 @@ static int IntelQaSymCipher(IntelQaDev* dev, byte* out, const byte* in, (authInSzAligned % AES_BLOCK_SIZE); } -#ifndef WOLFSSL_SNIFFER - authInBuf = XREALLOC((byte*)authIn, authInSzAligned, dev->heap, - DYNAMIC_TYPE_ASYNC_NUMA); -#else authInBuf = XMALLOC(authInSzAligned, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA); XMEMCPY(authInBuf, authIn, authInSz); -#endif if (authInBuf == NULL) { ret = MEMORY_E; goto exit; } @@ -878,7 +875,10 @@ static int IntelQaSymCipher(IntelQaDev* dev, byte* out, const byte* in, setup.hashSetupData.digestResultLenInBytes = authTagSz; setup.hashSetupData.authModeSetupData.aadLenInBytes = authInSz; - setup.digestIsAppended = CPA_TRUE; + if (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT) + setup.digestIsAppended = CPA_TRUE; + else + setup.digestIsAppended = CPA_FALSE; } /* open session */ @@ -903,13 +903,19 @@ static int IntelQaSymCipher(IntelQaDev* dev, byte* out, const byte* in, XMEMCPY(flatBuffer->pData + inOutSz, authTag, authTagSz); } } + else { + if (authTag && authTagSz > 0) { + XMEMCPY(authTagBuf, authTag, authTagSz); + } + } /* store info needed for output */ dev->out = out; dev->outLen = inOutSz; if (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) { - dev->op.cipher.authTag = authTag; + dev->op.cipher.authTag = authTagBuf; dev->op.cipher.authTagSz = authTagSz; + opData->pDigestResult = authTagBuf; } else { dev->op.cipher.authTag = NULL; @@ -920,11 +926,16 @@ static int IntelQaSymCipher(IntelQaDev* dev, byte* out, const byte* in, /* perform symmetric AES operation async */ /* use same buffer list for in-place operation */ status = cpaCySymPerformOp(dev->handle, dev, opData, - bufferList, bufferList, NULL); - - if (ret == WC_PENDING_E) - return ret; + bufferList, bufferList, &verifyResult); + if (symOperation == CPA_CY_SYM_OP_ALGORITHM_CHAINING && + cipherAlgorithm == CPA_CY_SYM_CIPHER_AES_GCM && + cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT && + hashAlgorithm == CPA_CY_SYM_HASH_AES_GCM) { + if (verifyResult == CPA_FALSE) { + ret = AES_GCM_AUTH_E; + } + } exit: if (ret != 0) { @@ -932,10 +943,13 @@ exit: dev, status, ret); } -#ifdef WOLFSSL_SNIFFER /* Capture the inline decrypt into the output. */ XMEMCPY(out, dataBuf, inOutSz); -#endif + if (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) { + if (authTag != NULL && authTagSz > 0) { + XMEMCPY(authTag, authTagBuf, authTagSz); + } + } /* handle cleanup */ IntelQaSymCipherFree(dev); @@ -949,11 +963,14 @@ int IntelQaSymAesCbcEncrypt(IntelQaDev* dev, const byte* key, word32 keySz, const byte* iv, word32 ivSz) { - return IntelQaSymCipher(dev, out, in, sz, + int ret = IntelQaSymCipher(dev, out, in, sz, key, keySz, iv, ivSz, CPA_CY_SYM_OP_CIPHER, CPA_CY_SYM_CIPHER_AES_CBC, CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT, CPA_CY_SYM_HASH_NONE, NULL, 0, NULL, 0); + + XMEMCPY((byte*)iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + return ret; } #ifdef HAVE_AES_DECRYPT @@ -962,11 +979,18 @@ int IntelQaSymAesCbcDecrypt(IntelQaDev* dev, const byte* key, word32 keySz, const byte* iv, word32 ivSz) { - return IntelQaSymCipher(dev, out, in, sz, + byte nextIv[AES_BLOCK_SIZE]; + int ret; + + XMEMCPY(nextIv, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + ret = IntelQaSymCipher(dev, out, in, sz, key, keySz, iv, ivSz, CPA_CY_SYM_OP_CIPHER, CPA_CY_SYM_CIPHER_AES_CBC, CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT, CPA_CY_SYM_HASH_NONE, NULL, 0, NULL, 0); + + XMEMCPY((byte*)iv, nextIv, AES_BLOCK_SIZE); + return ret; } #endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AES_CBC */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 04de111b9..87f6538d9 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -890,7 +890,8 @@ initDefaultName(); if ( (ret = aesgcm_test()) != 0) return err_sys("AES-GCM test failed!\n", ret); #endif - #if !defined(WOLFSSL_AFALG_XILINX_AES) && !defined(WOLFSSL_XILINX_CRYPT) + #if !defined(WOLFSSL_AFALG_XILINX_AES) && !defined(WOLFSSL_XILINX_CRYPT) && \ + !(defined(WOLF_CRYPTO_CB) && defined(HAVE_INTEL_QA_SYNC)) if ((ret = aesgcm_default_test()) != 0) { return err_sys("AES-GCM test failed!\n", ret); } @@ -7390,7 +7391,8 @@ int aesgcm_test(void) #if !defined(HAVE_FIPS) && \ !defined(WOLFSSL_PIC32MZ_CRYPT) && \ !defined(FREESCALE_LTC) && !defined(FREESCALE_MMCAU) && \ - !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES) + !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES) && \ + !(defined(WOLF_CRYPTO_CB) && defined(HAVE_INTEL_QA_SYNC)) #define ENABLE_NON_12BYTE_IV_TEST #ifdef WOLFSSL_AES_192 @@ -7596,6 +7598,7 @@ int aesgcm_test(void) } #endif +#if !(defined(WOLF_CRYPTO_CB) && defined(HAVE_INTEL_QA_SYNC)) /* Variable authenticated data length test */ for (alen=0; alen<(int)sizeof(p); alen++) { /* AES-GCM encrypt and decrypt both use AES encrypt internally */ @@ -7616,6 +7619,7 @@ int aesgcm_test(void) return -5713; #endif /* HAVE_AES_DECRYPT */ } +#endif #if !defined(WOLFSSL_AFALG_XILINX_AES) && !defined(WOLFSSL_XILINX_CRYPT) #ifdef BENCH_AESGCM_LARGE @@ -7734,7 +7738,8 @@ int aesgcm_test(void) #endif /* ENABLE_NON_12BYTE_IV_TEST */ #if defined(WOLFSSL_AES_256) && !defined(WOLFSSL_AFALG_XILINX_AES) && \ - !defined(WOLFSSL_XILINX_CRYPT) + !defined(WOLFSSL_XILINX_CRYPT) && \ + !(defined(WOLF_CRYPTO_CB) && defined(HAVE_INTEL_QA_SYNC)) XMEMSET(resultT, 0, sizeof(resultT)); XMEMSET(resultC, 0, sizeof(resultC)); XMEMSET(resultP, 0, sizeof(resultP)); @@ -7895,6 +7900,7 @@ int gmac_test(void) byte tag[16]; XMEMSET(&gmac, 0, sizeof(Gmac)); /* clear context */ + wc_AesInit((Aes*)&gmac, HEAP_HINT, INVALID_DEVID); /* Make sure devId updated */ XMEMSET(tag, 0, sizeof(tag)); wc_GmacSetKey(&gmac, k1, sizeof(k1)); wc_GmacUpdate(&gmac, iv1, sizeof(iv1), a1, sizeof(a1), tag, sizeof(t1));