/** @file crypt_new_rom.c * * @brief This file defines AES based functions. * * Copyright (C) 2014-2017, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 * (the "License"). You may use, redistribute and/or modify this File in * accordance with the terms and conditions of the License, a copy of which * is available by writing to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE * ARE EXPRESSLY DISCLAIMED. The License provides additional details about * this warranty disclaimer. */ /****************************************************** Change log: 03/07/2014: Initial version ******************************************************/ /* * AES based functions * * - AES Key Wrap algorithm (128-bit KEK) (RFC-3394) * - AES primitive algorithm * - AES CCM algorithm * * Date: 11/01/2005 */ #include "wltypes.h" #include "crypt_new_rom.h" #include "rc4_rom.h" #include "rijndael.h" #include "hostsa_ext_def.h" #include "authenticator.h" static const UINT8 MRVL_DEFAULT_IV[8] = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 }; UINT8 aesResult[32]; /* MRVL_AES_MEMCMP * : similiar to memcmp in std c lib * @dst : dst ptr to be compared to * @src : src ptr to be compared from * @len : size of the comparison * * ASSUMPTION : dst/src has to be valid data ptrs */ int MRVL_AES_MEMCMP(UINT8 *dst, UINT8 *src, int len) { int cnt = len; while (len--) { if (*dst++ == *src++) { cnt--; } } if (0 == cnt) { return 0; /* dst == src */ } return -1; /* dst != src */ } /* MRVL_AES_MEMSET * : similiar to memset in std c lib * @dst : dst starting pointer * @val : val to be set * @size : size of dst buffer to be set * * ASSUMPTION : dst buffer must always have larger than the value of size */ void MRVL_AES_MEMSET(UINT8 *dst, UINT8 val, int size) { while (size--) { *dst++ = val; } } /* MRVL_AES_MEMCPY * : similar to memcpy in std c lib * @dst : dst buffer starting ptr * @src : src buffer starting ptr * @size : size of copy * * ASSUMPTION : * 1: dst buffer must be larger than src + size of copy * 2: dst buffer isn't overlapping src buffer */ void MRVL_AES_MEMCPY(UINT8 *dst, UINT8 *src, int size) { if (dst < src) { while (size) { *dst++ = *src++; size--; } } else { while (size) { *(dst + size - 1) = *(src + size - 1); size--; } } } int MRVL_AesInterCheck(UINT8 *inter, UINT8 *d) { if (0 == MRVL_AES_MEMCMP(inter, d, 16)) { return 0; } return -1; } #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH extern const u8 Te4[256]; extern const u32 rcon[]; extern const u32 Td0[256]; extern const u32 Td1[256]; extern const u32 Td2[256]; extern const u32 Td3[256]; #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) static int rijndaelKeySetupEnc_2(u32 rk[ /*4*(Nr + 1) */ ], const u8 cipherKey[], int keyBits) { int i = 0; u32 temp; rk[0] = GETU32(cipherKey); rk[1] = GETU32(cipherKey + 4); rk[2] = GETU32(cipherKey + 8); rk[3] = GETU32(cipherKey + 12); if (keyBits == 128) { for (;;) { temp = rk[3]; rk[4] = rk[0] ^ (Te4[(temp >> 16) & 0xff] << 24) ^ (Te4[(temp >> 8) & 0xff] << 16) ^ (Te4[(temp) & 0xff] << 8) ^ (Te4[(temp >> 24)]) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; if (++i == 10) { return 10; } rk += 4; } } /** Handle 24 bytes key length */ rk[4] = GETU32(cipherKey + 16); rk[5] = GETU32(cipherKey + 20); if (keyBits == 192) { for (;;) { temp = rk[5]; rk[6] = rk[0] ^ (Te4[(temp >> 16) & 0xff] << 24) ^ (Te4[(temp >> 8) & 0xff] << 16) ^ (Te4[(temp) & 0xff] << 8) ^ (Te4[(temp >> 24)]) ^ rcon[i]; rk[7] = rk[1] ^ rk[6]; rk[8] = rk[2] ^ rk[7]; rk[9] = rk[3] ^ rk[8]; if (++i == 8) { return 12; } rk[10] = rk[4] ^ rk[9]; rk[11] = rk[5] ^ rk[10]; rk += 6; } } /** Handle 32 bytes key length */ rk[6] = GETU32(cipherKey + 24); rk[7] = GETU32(cipherKey + 28); if (keyBits == 256) { for (;;) { temp = rk[7]; rk[8] = rk[0] ^ (Te4[(temp >> 16) & 0xff] << 24) ^ (Te4[(temp >> 8) & 0xff] << 16) ^ (Te4[(temp) & 0xff] << 8) ^ (Te4[(temp >> 24)]) ^ rcon[i]; rk[9] = rk[1] ^ rk[8]; rk[10] = rk[2] ^ rk[9]; rk[11] = rk[3] ^ rk[10]; if (++i == 7) { return 14; } temp = rk[11]; rk[12] = rk[4] ^ (Te4[(temp >> 24)] << 24) ^ (Te4[(temp >> 16) & 0xff] << 16) ^ (Te4[(temp >> 8) & 0xff] << 8) ^ (Te4[(temp) & 0xff]); rk[13] = rk[5] ^ rk[12]; rk[14] = rk[6] ^ rk[13]; rk[15] = rk[7] ^ rk[14]; rk += 8; } } return 0; } static int rijndaelKeySetupDec_2(u32 rk[ /*4*(Nr + 1) */ ], const u8 cipherKey[], int keyBits, int have_encrypt) { int Nr, i, j; u32 temp; if (have_encrypt) { Nr = have_encrypt; } else { /* expand the cipher key: */ Nr = rijndaelKeySetupEnc_2(rk, cipherKey, keyBits); } /* invert the order of the round keys: */ for (i = 0, j = 4 * Nr; i < j; i += 4, j -= 4) { temp = rk[i]; rk[i] = rk[j]; rk[j] = temp; temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; } /* apply the inverse MixColumn transform to all round keys but the first and the last: */ for (i = 1; i < Nr; i++) { rk += 4; rk[0] = Td0[Te4[(rk[0] >> 24)]] ^ Td1[Te4[(rk[0] >> 16) & 0xff]] ^ Td2[Te4[(rk[0] >> 8) & 0xff]] ^ Td3[Te4[(rk[0]) & 0xff]]; rk[1] = Td0[Te4[(rk[1] >> 24)]] ^ Td1[Te4[(rk[1] >> 16) & 0xff]] ^ Td2[Te4[(rk[1] >> 8) & 0xff]] ^ Td3[Te4[(rk[1]) & 0xff]]; rk[2] = Td0[Te4[(rk[2] >> 24)]] ^ Td1[Te4[(rk[2] >> 16) & 0xff]] ^ Td2[Te4[(rk[2] >> 8) & 0xff]] ^ Td3[Te4[(rk[2]) & 0xff]]; rk[3] = Td0[Te4[(rk[3] >> 24)]] ^ Td1[Te4[(rk[3] >> 16) & 0xff]] ^ Td2[Te4[(rk[3] >> 8) & 0xff]] ^ Td3[Te4[(rk[3]) & 0xff]]; } return Nr; } static void rijndael_set_key_2(rijndael_ctx *ctx, u8 *key, int bits, int encrypt) { ctx->Nr = rijndaelKeySetupEnc_2(ctx->key, key, bits); if (encrypt) { ctx->decrypt = 0; } else { ctx->decrypt = 1; rijndaelKeySetupDec_2(ctx->key, key, bits, ctx->Nr); /**bt_test :: TBD */ } } #endif /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */ /* * AesEncrypt : aes primitive encryption * * @kek : key encryption key * @kekLen : kek len * @data : data pointer * * ASSUMPTION : both src and dst buffer has to be 16 bytes or 128-bit */ int MRVL_AesEncrypt(UINT8 *kek, UINT8 kekLen, UINT8 *data, UINT8 *ret) { //BufferDesc_t * pDesc = NULL; UINT8 buf[400] = { 0 }; rijndael_ctx *ctx; #if 0 //!defined(REMOVE_PATCH_HOOKS) int ptr_val; if (MRVL_AesEncrypt_hook(kek, kekLen, data, ret, &ptr_val)) { return ptr_val; } #endif #if 0 /* Wait forever ensures a buffer */ pDesc = (BufferDesc_t *) bml_AllocBuffer(ramHook_encrPoolConfig, 400, BML_WAIT_FOREVER); #endif //ctx = (rijndael_ctx *)BML_DATA_PTR(pDesc); ctx = (rijndael_ctx *)buf; #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH rijndael_set_key_2(ctx, (UINT8 *)kek, kekLen * 64, 1); #else rijndael_set_key(ctx, (UINT8 *)kek, kekLen * 64, 1); #endif /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */ rijndael_encrypt(ctx, data, ret); // bml_FreeBuffer((UINT32)pDesc); return 0; } /**************************************************************** * AES_WRAP : AES_WRAP is specified by RFC 3394 section 2.2.1 * * Inputs : plaintest, n 64-bit values {P1, P2, ..., Pn}, and * Key, K (the KEK) * Outputs : ciphertext, (n+1) 64-bit values {C0, ..., Cn} * * NOTE: this function is ported over from WPA_SUPPLICANT **************************************************************** * * @kek : key encryption key * @kekLen : kek len, in unit of 64-bit, has to be 2, 3, or 4 * @n : length of the wrapped key in 64-bit * unit; e.g.: 2 = 128-bit = 16 bytes * @plain : plaintext key to be wrapped, has to be n * (64-bit) * or n * 8 bytes * @cipher : wrapped key, (n + 1) * 64-bit or (n+1) * 8 bytes */ /* debugging */ int MRVL_AesWrap(UINT8 *kek, UINT8 kekLen, UINT32 n, UINT8 *plain, UINT8 *keyIv, UINT8 *cipher) { UINT8 a[8]; UINT8 b[16]; int i = 0; int j = 0; UINT8 *r = NULL; #if 0 //!defined(REMOVE_PATCH_HOOKS) int ptr_val; if (MRVL_AesWrap_hook(kek, kekLen, n, plain, keyIv, cipher, &ptr_val)) { return ptr_val; } #endif /* 0: before everything, check n value */ if (1 > n) { return -1; } r = cipher + 8; /* 1: initialize variables */ MRVL_AES_MEMSET(b, 0x0, 16); if (keyIv) { MRVL_AES_MEMCPY(a, keyIv, 8); } else { MRVL_AES_MEMCPY(a, (UINT8 *)MRVL_DEFAULT_IV, 8); } MRVL_AES_MEMCPY(r, plain, (8 * n)); /* 2: calculate intermediate values * For j = 0 to 5 * For i=1 to n * B = AES(K, A | R[i]) * A = MSB(64, B) ^ t where t = (n*j)+i * R[i] = LSB(64, B) */ for (j = 0; j <= 5; j++) { r = cipher + 8; for (i = 1; i <= n; i++) { MRVL_AES_MEMCPY(b, a, 8); MRVL_AES_MEMCPY(b + 8, r, 8); MRVL_AesEncrypt(kek, kekLen, b, b); MRVL_AES_MEMCPY(a, b, 8); a[7] ^= n * j + i; MRVL_AES_MEMCPY(r, b + 8, 8); r += 8; } } MRVL_AES_MEMCPY(cipher, a, 8); /* 3: output the results * these are already in @cipher */ return 0; } /**************************************************************** * AES_UNWRAP : AES_UNWRAP is specified by RFC 3394 section 2.2.2 * * Inputs : ciphertext, (n+1) 64-bit values {C0, ..., Cn}, and * Key, K (the KEK) * * Outputs : plaintest, n 64-bit values {P1, P2, ..., Pn} + first 8 bytes * for KEYIV * * **************************************************************** * * @kek : key encryption key * @kekLen : kek len, in unit of 64-bit, has to be 2, 3, or 4 * @n : length of the wrapped key in 64-bit * unit; e.g.: 2 = 128-bit = 16 bytes * @cipher : wrapped data, (n + 1) * 64-bit or (n+1) * 8 bytes * @plain : plaintext being unwrapped, has to be n * (64-bit) * or n * 8 bytes + extra 8 bytes for KEYIV */ int MRVL_AesUnWrap(UINT8 *kek, UINT8 kekLen, UINT32 n, UINT8 *cipher, UINT8 *keyIv, UINT8 *plain) { UINT8 b[16]; int i = 0; int j = 0; UINT8 a[8]; UINT8 *r = NULL; //BufferDesc_t * pDesc = NULL; UINT8 buf[400] = { 0 }; rijndael_ctx *ctx; #if 0 //!defined(REMOVE_PATCH_HOOKS) int ptr_val; if (MRVL_AesUnWrap_hook(kek, kekLen, n, cipher, keyIv, plain, &ptr_val)) { return ptr_val; } #endif /* 0: before everything, check n value */ if (1 > n) { return -1; } /* 1: initialize variables */ MRVL_AES_MEMSET(a, 0x0, 8); MRVL_AES_MEMSET(b, 0x0, 16); MRVL_AES_MEMCPY(a, cipher, 8); r = plain; MRVL_AES_MEMCPY(r, cipher + 8, 8 * n); #if 0 /* Wait forever ensures a buffer */ pDesc = (BufferDesc_t *) bml_AllocBuffer(ramHook_encrPoolConfig, 400, BML_WAIT_FOREVER); #endif //ctx = (rijndael_ctx *)BML_DATA_PTR(pDesc); ctx = (rijndael_ctx *)buf; #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH rijndael_set_key_2(ctx, (UINT8 *)kek, kekLen * 64, 0); #else rijndael_set_key(ctx, (UINT8 *)kek, kekLen * 64, 0); #endif /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */ /* 2: compute intermediate values * For j = 5 to 0 * For i = n to 1 * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i * A = MSB(64, B) * R[i] = LSB(64, B) */ for (j = 5; j >= 0; j--) { r = plain + (n - 1) * 8; for (i = n; i >= 1; i--) { MRVL_AES_MEMCPY(b, a, 8); b[7] ^= n * j + i; MRVL_AES_MEMCPY(b + 8, r, 8); rijndael_decrypt(ctx, b, b); MRVL_AES_MEMCPY(a, b, 8); MRVL_AES_MEMCPY(r, b + 8, 8); r -= 8; } } // bml_FreeBuffer((UINT32)pDesc); /* 3: copy decrypted KeyIV to keyIv array */ if (keyIv) { if (MRVL_AES_MEMCMP(keyIv, a, 8)) { return -1; } } else { if (MRVL_AES_MEMCMP((UINT8 *)MRVL_DEFAULT_IV, a, 8)) { return -1; } } return 0; } #if 0 /***** * AES CRYPTION HELPER FUNCTIONS * */ int MRVL_AesValidateHostRequest(UINT32 *pBitMap, UINT8 *pCmdPtr, UINT8 *pCryptData, SINT8 *AESwrapEnc) { host_MRVL_AES_CRYPT_t *pLocal = NULL; MrvlIEParamSet_t *pLocalIEParam = NULL; #if 0 //!defined(REMOVE_PATCH_HOOKS) int ptr_val; if (MRVL_AesValidateHostRequest_hook(pBitMap, pCmdPtr, pCryptData, AESwrapEnc, &ptr_val)) { return ptr_val; } #endif if (NULL == pBitMap || NULL == pCmdPtr) { return -1; } pLocal = (host_MRVL_AES_CRYPT_t *) pCmdPtr; pLocalIEParam = (MrvlIEParamSet_t *)&(pLocal->aesTlv); if ((0 != pLocal->action) && (0x1 != pLocal->action)) { *pBitMap |= MRVL_AES_NOT_EN_AND_DECRYPT; } if (0 == pLocal->action) { ((MRVL_ENDECRYPT_t *)pCryptData)->enDeAction = CRYPT_DECRYPT; } else if (1 == pLocal->action) { ((MRVL_ENDECRYPT_t *)pCryptData)->enDeAction = CRYPT_ENCRYPT; } switch (pLocal->algorithm) { case MRVL_CRYPTO_TEST_RC4: if ((1 > (pLocal->keyIVLen + pLocal->keyLen)) || (256 < (pLocal->keyIVLen + pLocal->keyLen))) { *pBitMap |= MRVL_AES_KEY_IV_INVALID_RC4; } break; case MRVL_CRYPTO_TEST_AES_ECB: if ((16 != pLocal->keyLen) && (24 != pLocal->keyLen) && (32 != pLocal->keyLen)) { *pBitMap |= MRVL_AES_KEY_SIZE_INVALID; } if ((16 != pLocalIEParam->Length)) { *pBitMap |= MRVL_AES_DATA_SIZE_INVALID; } break; case MRVL_CRYPTO_TEST_AES_WRAP: if (8 != pLocal->keyIVLen) { *pBitMap |= MRVL_AES_KEY_IV_INVALID_AES_WRAP; } if ((16 != pLocal->keyLen) && (24 != pLocal->keyLen) && (32 != pLocal->keyLen)) { *pBitMap |= MRVL_AES_KEY_SIZE_INVALID; } if ((1016 < pLocalIEParam->Length) || (8 > pLocalIEParam->Length)) { *pBitMap |= MRVL_AES_DATA_SIZE_INVALID; } if (1 == pLocal->action) { /* Encryption */ *AESwrapEnc = 8; } else if (0 == pLocal->action) { /* Decryption */ *AESwrapEnc = -8; } break; #ifdef DIAG_AES_CCM case MRVL_CRYPTO_TEST_AEC_CCM: { host_MRVL_AES_CCM_CRYPT_t *pLocalCCM = (host_MRVL_AES_CCM_CRYPT_t *) pCmdPtr; pLocalIEParam = (MrvlIEParamSet_t *)&(pLocalCCM->aesTlv); /* key length should be 16 */ if ((16 != pLocalCCM->keyLen) && (24 != pLocalCCM->keyLen) && (32 != pLocalCCM->keyLen)) { *pBitMap |= MRVL_AES_KEY_SIZE_INVALID; } /* nonce length 7 ~ 13 bytes */ if ((pLocalCCM->nonceLen < 7) || (pLocalCCM->nonceLen > 13)) { *pBitMap |= MRVL_AES_NONCE_INVALID; } /* AAD length 0 ~ 30 bytes */ if (pLocalCCM->aadLen > 30) { *pBitMap |= MRVL_AES_AAD_INVALID; } /* payload length 0 ~ 32 bytes */ if (40 < pLocalIEParam->Length) { *pBitMap |= MRVL_AES_DATA_SIZE_INVALID; } } break; #endif #ifdef WAPI_HW_SUPPORT case MRVL_CRYPTO_TEST_WAPI: { host_MRVL_WAPI_CRYPT_t *pLocalWAPI = (host_MRVL_WAPI_CRYPT_t *) pCmdPtr; /* key length should be 16 */ if (pLocalWAPI->keyLen != 32) { *pBitMap |= MRVL_AES_KEY_SIZE_INVALID; } /* nonce length 16 bytes */ if (pLocalWAPI->nonceLen != 16) { *pBitMap |= MRVL_AES_NONCE_INVALID; } /* AAD length 32 or 48 bytes */ if ((pLocalWAPI->aadLen != 32) && (pLocalWAPI->aadLen != 48)) { *pBitMap |= MRVL_AES_AAD_INVALID; } } break; #endif default: *pBitMap |= MRVL_AES_ALGORITHM_INVALID; break; } /* put the buffer ptr to cryptdata */ ((MRVL_ENDECRYPT_t *)pCryptData)->pData = pCmdPtr; return 0; } /************** * WRAPPER to do AES primitive encryption */ void MRVL_AesPrimitiveEncrypt(MRVL_ENDECRYPT_t *crypt, int *pErr) { UINT8 *kek = NULL; UINT8 *data = NULL; UINT8 kekLen = 0; host_MRVL_AES_CRYPT_t *pLocal = NULL; MrvlIEAesCrypt_t *pLocalIEParam = NULL; #if 0 //!defined(REMOVE_PATCH_HOOKS) if (MRVL_AesPrimitiveEncrypt_hook(crypt, pErr)) { return; } #endif if ((NULL == pErr) || (NULL == crypt)) { *pErr = -1; return; } *pErr = 0; if ((CRYPT_ENCRYPT != crypt->enDeAction)) { *pErr = -1; return; } pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData); pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv); kek = (UINT8 *)(pLocal->key); kekLen = pLocal->keyLen; data = (UINT8 *)(pLocalIEParam->payload); if (-1 == MRVL_AesEncrypt(kek, kekLen / 8, data, data)) { *pErr = -1; return; } } void MRVL_AesPrimitiveDecrypt(MRVL_ENDECRYPT_t *crypt, int *pErr) { UINT8 *kek = NULL; UINT8 *data = NULL; UINT8 kekLen = 0; host_MRVL_AES_CRYPT_t *pLocal = NULL; MrvlIEAesCrypt_t *pLocalIEParam = NULL; BufferDesc_t *pDesc; rijndael_ctx *ctx; #if 0 //!defined(REMOVE_PATCH_HOOKS) if (MRVL_AesPrimitiveDecrypt_hook(crypt, pErr)) { return; } #endif if ((NULL == pErr) || (NULL == crypt)) { *pErr = -1; return; } if ((CRYPT_DECRYPT != crypt->enDeAction)) { *pErr = -1; return; } pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData); pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv); kek = (UINT8 *)(pLocal->key); kekLen = pLocal->keyLen; data = (UINT8 *)(pLocalIEParam->payload); #if 0 /* Wait forever ensures a buffer */ pDesc = (BufferDesc_t *) bml_AllocBuffer(ramHook_encrPoolConfig, 400, BML_WAIT_FOREVER); #endif ctx = (rijndael_ctx *)BML_DATA_PTR(pDesc); #ifdef WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH rijndael_set_key_2(ctx, (UINT8 *)kek, kekLen * 8, 0); #else rijndael_set_key(ctx, (UINT8 *)kek, kekLen * 8, 0); #endif /** WAR_ROM_BUG64609_SUPPORT_24_32_BYTES_KEY_LENGTH */ rijndael_decrypt(ctx, data, data); bml_FreeBuffer((UINT32)pDesc); *pErr = 0; } void MRVL_AesWrapEncrypt(MRVL_ENDECRYPT_t *crypt, int *pErr) { UINT8 *kek = NULL; UINT8 *data = NULL; UINT8 *keyIV = NULL; UINT8 kekLen = 0; UINT32 dataLen = 0; host_MRVL_AES_CRYPT_t *pLocal = NULL; MrvlIEAesCrypt_t *pLocalIEParam = NULL; #if 0 //!defined(REMOVE_PATCH_HOOKS) if (MRVL_AesWrapEncrypt_hook(crypt, pErr)) { return; } #endif if ((NULL == pErr) || (NULL == crypt)) { *pErr = -1; return; } *pErr = 0; if ((CRYPT_ENCRYPT != crypt->enDeAction)) { *pErr = -1; return; } pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData); pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv); kek = (UINT8 *)(pLocal->key); keyIV = (UINT8 *)(pLocal->keyIV); kekLen = pLocal->keyLen; data = (UINT8 *)(pLocalIEParam->payload); dataLen = pLocalIEParam->hdr.Length; /* need to add one more 8-bytes for return length */ pLocalIEParam->hdr.Length = dataLen + 8; if (-1 == MRVL_AesWrap(kek, kekLen / 8, dataLen / 8, data, keyIV, aesResult)) { *pErr = -2; return; } MRVL_AES_MEMCPY(data, aesResult, pLocalIEParam->hdr.Length); } void MRVL_AesWrapDecrypt(MRVL_ENDECRYPT_t *crypt, int *pErr) { UINT8 *kek = NULL; UINT8 *keyIV = NULL; UINT8 *data = NULL; UINT8 kekLen = 0; UINT32 dataLen = 0; host_MRVL_AES_CRYPT_t *pLocal = NULL; MrvlIEAesCrypt_t *pLocalIEParam = NULL; #if 0 //!defined(REMOVE_PATCH_HOOKS) if (MRVL_AesWrapDecrypt_hook(crypt, pErr)) { return; } #endif if ((NULL == pErr) || (NULL == crypt)) { *pErr = -1; return; } *pErr = 0; if ((CRYPT_DECRYPT != crypt->enDeAction)) { *pErr = -1; return; } pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData); pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv); kek = (UINT8 *)(pLocal->key); keyIV = (UINT8 *)(pLocal->keyIV); kekLen = pLocal->keyLen; data = (UINT8 *)(pLocalIEParam->payload); dataLen = pLocalIEParam->hdr.Length; if (-1 == MRVL_AesUnWrap(kek, kekLen / 8, dataLen / 8 - 1, data, keyIV, aesResult)) { *pErr = -2; return; } dataLen -= 8; pLocalIEParam->hdr.Length = dataLen; MRVL_AES_MEMCPY(data, aesResult, dataLen); } #endif #ifdef RC4 void MRVL_Rc4Cryption(void *priv, MRVL_ENDECRYPT_t *crypt, int *pErr) { host_MRVL_AES_CRYPT_t *pLocal = NULL; MrvlIEAesCrypt_t *pLocalIEParam = NULL; UINT8 *key = NULL; UINT8 *keyIV = NULL; UINT8 *data = NULL; UINT32 dataLen = 0; if ((NULL == pErr) || (NULL == crypt)) { *pErr = -1; return; } *pErr = 0; /* since RC4 encrypt/decrypt are the same */ if ((CRYPT_DECRYPT != crypt->enDeAction) && (CRYPT_ENCRYPT != crypt->enDeAction)) { *pErr = -2; return; } pLocal = (host_MRVL_AES_CRYPT_t *) (crypt->pData); pLocalIEParam = (MrvlIEAesCrypt_t *)&(pLocal->aesTlv); key = (UINT8 *)(pLocal->key); data = (UINT8 *)(pLocalIEParam->payload); keyIV = (UINT8 *)(pLocal->keyIV); dataLen = pLocalIEParam->hdr.Length; RC4_Encrypt(priv, key, keyIV, pLocal->keyIVLen, data, dataLen, 0); return; } #endif /* RC4 */