1/* SPDX-License-Identifier: BSD-3-Clause */ 2/* Copyright(c) 2007-2022 Intel Corporation */ 3 4/** 5 *************************************************************************** 6 * @file lac_sym_hash_sw_precomputes.c 7 * 8 * @ingroup LacHashDefs 9 * 10 * Hash Software 11 ***************************************************************************/ 12 13/* 14****************************************************************************** 15* Include public/global header files 16****************************************************************************** 17*/ 18 19#include "cpa.h" 20#include "cpa_cy_sym.h" 21 22#include "icp_accel_devices.h" 23#include "icp_adf_init.h" 24#include "icp_adf_transport.h" 25#include "icp_adf_debug.h" 26 27/* 28******************************************************************************* 29* Include private header files 30******************************************************************************* 31*/ 32 33#include "qat_utils.h" 34#include "lac_mem.h" 35#include "lac_sym.h" 36#include "lac_log.h" 37#include "lac_mem_pools.h" 38#include "lac_list.h" 39#include "lac_sym_hash_defs.h" 40#include "lac_sym_qat_hash_defs_lookup.h" 41#include "lac_sal_types_crypto.h" 42#include "lac_sal.h" 43#include "lac_session.h" 44#include "lac_sym_hash_precomputes.h" 45 46static CpaStatus 47LacSymHash_Compute(CpaCySymHashAlgorithm hashAlgorithm, 48 lac_sym_qat_hash_alg_info_t *pHashAlgInfo, 49 Cpa8U *in, 50 Cpa8U *out) 51{ 52 /* 53 * Note: from SHA hashes appropriate endian swapping is required. 54 * For sha1, sha224 and sha256 double words based swapping. 55 * For sha384 and sha512 quad words swapping. 56 * No endianes swapping for md5 is required. 57 */ 58 CpaStatus status = CPA_STATUS_FAIL; 59 Cpa32U i = 0; 60 switch (hashAlgorithm) { 61 case CPA_CY_SYM_HASH_MD5: 62 if (CPA_STATUS_SUCCESS != qatUtilsHashMD5(in, out)) { 63 LAC_LOG_ERROR("qatUtilsHashMD5 Failed\n"); 64 return status; 65 } 66 status = CPA_STATUS_SUCCESS; 67 break; 68 case CPA_CY_SYM_HASH_SHA1: 69 if (CPA_STATUS_SUCCESS != qatUtilsHashSHA1(in, out)) { 70 LAC_LOG_ERROR("qatUtilsHashSHA1 Failed\n"); 71 return status; 72 } 73 for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize); 74 i++) { 75 ((Cpa32U *)(out))[i] = 76 LAC_MEM_WR_32(((Cpa32U *)(out))[i]); 77 } 78 status = CPA_STATUS_SUCCESS; 79 break; 80 case CPA_CY_SYM_HASH_SHA224: 81 if (CPA_STATUS_SUCCESS != qatUtilsHashSHA224(in, out)) { 82 LAC_LOG_ERROR("qatUtilsHashSHA224 Failed\n"); 83 return status; 84 } 85 for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize); 86 i++) { 87 ((Cpa32U *)(out))[i] = 88 LAC_MEM_WR_32(((Cpa32U *)(out))[i]); 89 } 90 status = CPA_STATUS_SUCCESS; 91 break; 92 case CPA_CY_SYM_HASH_SHA256: 93 if (CPA_STATUS_SUCCESS != qatUtilsHashSHA256(in, out)) { 94 LAC_LOG_ERROR("qatUtilsHashSHA256 Failed\n"); 95 return status; 96 } 97 for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize); 98 i++) { 99 ((Cpa32U *)(out))[i] = 100 LAC_MEM_WR_32(((Cpa32U *)(out))[i]); 101 } 102 status = CPA_STATUS_SUCCESS; 103 break; 104 case CPA_CY_SYM_HASH_SHA384: 105 if (CPA_STATUS_SUCCESS != qatUtilsHashSHA384(in, out)) { 106 LAC_LOG_ERROR("qatUtilsHashSHA384 Failed\n"); 107 return status; 108 } 109 for (i = 0; i < LAC_BYTES_TO_QUADWORDS(pHashAlgInfo->stateSize); 110 i++) { 111 ((Cpa64U *)(out))[i] = 112 LAC_MEM_WR_64(((Cpa64U *)(out))[i]); 113 } 114 status = CPA_STATUS_SUCCESS; 115 break; 116 case CPA_CY_SYM_HASH_SHA512: 117 if (CPA_STATUS_SUCCESS != qatUtilsHashSHA512(in, out)) { 118 LAC_LOG_ERROR("qatUtilsHashSHA512 Failed\n"); 119 return status; 120 } 121 for (i = 0; i < LAC_BYTES_TO_QUADWORDS(pHashAlgInfo->stateSize); 122 i++) { 123 ((Cpa64U *)(out))[i] = 124 LAC_MEM_WR_64(((Cpa64U *)(out))[i]); 125 } 126 status = CPA_STATUS_SUCCESS; 127 break; 128 default: 129 return CPA_STATUS_INVALID_PARAM; 130 } 131 return status; 132} 133 134CpaStatus 135LacSymHash_HmacPreComputes(CpaInstanceHandle instanceHandle, 136 CpaCySymHashAlgorithm hashAlgorithm, 137 Cpa32U authKeyLenInBytes, 138 Cpa8U *pAuthKey, 139 Cpa8U *pWorkingMemory, 140 Cpa8U *pState1, 141 Cpa8U *pState2, 142 lac_hash_precompute_done_cb_t callbackFn, 143 void *pCallbackTag) 144{ 145 Cpa8U *pIpadData = NULL; 146 Cpa8U *pOpadData = NULL; 147 CpaStatus status = CPA_STATUS_FAIL; 148 lac_sym_hash_precomp_op_data_t *pHmacIpadOpData = 149 (lac_sym_hash_precomp_op_data_t *)pWorkingMemory; 150 lac_sym_hash_precomp_op_data_t *pHmacOpadOpData = pHmacIpadOpData + 1; 151 152 /* Convenience pointers */ 153 lac_sym_hash_hmac_precomp_qat_t *pHmacIpadQatData = 154 &pHmacIpadOpData->u.hmacQatData; 155 lac_sym_hash_hmac_precomp_qat_t *pHmacOpadQatData = 156 &pHmacOpadOpData->u.hmacQatData; 157 158 lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL; 159 Cpa32U i = 0; 160 Cpa32U padLenBytes = 0; 161 162 LacSymQat_HashAlgLookupGet(instanceHandle, 163 hashAlgorithm, 164 &pHashAlgInfo); 165 pHmacIpadOpData->stateSize = pHashAlgInfo->stateSize; 166 pHmacOpadOpData->stateSize = pHashAlgInfo->stateSize; 167 168 /* Copy HMAC key into buffers */ 169 if (authKeyLenInBytes > 0) { 170 memcpy(pHmacIpadQatData->data, pAuthKey, authKeyLenInBytes); 171 memcpy(pHmacOpadQatData->data, pAuthKey, authKeyLenInBytes); 172 } 173 174 padLenBytes = pHashAlgInfo->blockLength - authKeyLenInBytes; 175 176 /* Clear the remaining buffer space */ 177 if (padLenBytes > 0) { 178 LAC_OS_BZERO(pHmacIpadQatData->data + authKeyLenInBytes, 179 padLenBytes); 180 LAC_OS_BZERO(pHmacOpadQatData->data + authKeyLenInBytes, 181 padLenBytes); 182 } 183 184 /* XOR Key with IPAD at 4-byte level */ 185 for (i = 0; i < pHashAlgInfo->blockLength; i++) { 186 Cpa8U *ipad = pHmacIpadQatData->data + i; 187 Cpa8U *opad = pHmacOpadQatData->data + i; 188 189 *ipad ^= LAC_HASH_IPAD_BYTE; 190 *opad ^= LAC_HASH_OPAD_BYTE; 191 } 192 pIpadData = (Cpa8U *)pHmacIpadQatData->data; 193 pOpadData = (Cpa8U *)pHmacOpadQatData->data; 194 195 status = LacSymHash_Compute(hashAlgorithm, 196 pHashAlgInfo, 197 (Cpa8U *)pIpadData, 198 pState1); 199 200 if (CPA_STATUS_SUCCESS == status) { 201 status = LacSymHash_Compute(hashAlgorithm, 202 pHashAlgInfo, 203 (Cpa8U *)pOpadData, 204 pState2); 205 } 206 207 if (CPA_STATUS_SUCCESS == status) { 208 callbackFn(pCallbackTag); 209 } 210 return status; 211} 212 213CpaStatus 214LacSymHash_AesECBPreCompute(CpaInstanceHandle instanceHandle, 215 CpaCySymHashAlgorithm hashAlgorithm, 216 Cpa32U authKeyLenInBytes, 217 Cpa8U *pAuthKey, 218 Cpa8U *pWorkingMemory, 219 Cpa8U *pState, 220 lac_hash_precompute_done_cb_t callbackFn, 221 void *pCallbackTag) 222{ 223 CpaStatus status = CPA_STATUS_FAIL; 224 Cpa32U stateSize = 0, x = 0; 225 lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL; 226 227 if (CPA_CY_SYM_HASH_AES_XCBC == hashAlgorithm) { 228 Cpa8U *in = pWorkingMemory; 229 Cpa8U *out = pState; 230 LacSymQat_HashAlgLookupGet(instanceHandle, 231 hashAlgorithm, 232 &pHashAlgInfo); 233 stateSize = pHashAlgInfo->stateSize; 234 memcpy(pWorkingMemory, pHashAlgInfo->initState, stateSize); 235 236 for (x = 0; x < LAC_HASH_XCBC_PRECOMP_KEY_NUM; x++) { 237 if (CPA_STATUS_SUCCESS != 238 qatUtilsAESEncrypt( 239 pAuthKey, authKeyLenInBytes, in, out)) { 240 return status; 241 } 242 in += LAC_HASH_XCBC_MAC_BLOCK_SIZE; 243 out += LAC_HASH_XCBC_MAC_BLOCK_SIZE; 244 } 245 status = CPA_STATUS_SUCCESS; 246 } else if (CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) { 247 Cpa8U *out = pState; 248 Cpa8U k1[LAC_HASH_CMAC_BLOCK_SIZE], 249 k2[LAC_HASH_CMAC_BLOCK_SIZE]; 250 Cpa8U *ptr = NULL, i = 0; 251 stateSize = LAC_HASH_CMAC_BLOCK_SIZE; 252 LacSymQat_HashAlgLookupGet(instanceHandle, 253 hashAlgorithm, 254 &pHashAlgInfo); 255 /* Original state size includes K, K1 and K2 which are of equal 256 * length. 257 * For precompute state size is only of the length of K which is 258 * equal 259 * to the block size for CPA_CY_SYM_HASH_AES_CMAC. 260 * The algorithm is described in rfc4493 261 * K is just copeid, K1 and K2 need to be single inplace encrypt 262 * with AES. 263 * */ 264 memcpy(out, pHashAlgInfo->initState, stateSize); 265 memcpy(out, pAuthKey, authKeyLenInBytes); 266 out += LAC_HASH_CMAC_BLOCK_SIZE; 267 268 for (x = 0; x < LAC_HASH_XCBC_PRECOMP_KEY_NUM - 1; x++) { 269 if (CPA_STATUS_SUCCESS != 270 qatUtilsAESEncrypt( 271 pAuthKey, authKeyLenInBytes, out, out)) { 272 return status; 273 } 274 out += LAC_HASH_CMAC_BLOCK_SIZE; 275 } 276 277 ptr = pState + LAC_HASH_CMAC_BLOCK_SIZE; 278 279 /* Derived keys (k1 and k2), copy them to 280 * pPrecompOpData->pState, 281 * but remember that at the beginning is original key (K0) 282 */ 283 /* Calculating K1 */ 284 for (i = 0; i < LAC_HASH_CMAC_BLOCK_SIZE; i++, ptr++) { 285 k1[i] = (*ptr) << 1; 286 if (i != 0) { 287 k1[i - 1] |= 288 (*ptr) >> (LAC_NUM_BITS_IN_BYTE - 1); 289 } 290 if (i + 1 == LAC_HASH_CMAC_BLOCK_SIZE) { 291 /* If msb of pState + LAC_HASH_CMAC_BLOCK_SIZE 292 is set xor 293 with RB. Because only the final byte of RB is 294 non-zero 295 this is all we need to xor */ 296 if ((*(pState + LAC_HASH_CMAC_BLOCK_SIZE)) & 297 LAC_SYM_HASH_MSBIT_MASK) { 298 k1[i] ^= LAC_SYM_AES_CMAC_RB_128; 299 } 300 } 301 } 302 303 /* Calculating K2 */ 304 for (i = 0; i < LAC_HASH_CMAC_BLOCK_SIZE; i++) { 305 k2[i] = (k1[i]) << 1; 306 if (i != 0) { 307 k2[i - 1] |= 308 (k1[i]) >> (LAC_NUM_BITS_IN_BYTE - 1); 309 } 310 if (i + 1 == LAC_HASH_CMAC_BLOCK_SIZE) { 311 /* If msb of k1 is set xor last byte with RB */ 312 if (k1[0] & LAC_SYM_HASH_MSBIT_MASK) { 313 k2[i] ^= LAC_SYM_AES_CMAC_RB_128; 314 } 315 } 316 } 317 /* Now, when we have K1 & K2 lets copy them to the state2 */ 318 ptr = pState + LAC_HASH_CMAC_BLOCK_SIZE; 319 memcpy(ptr, k1, LAC_HASH_CMAC_BLOCK_SIZE); 320 ptr += LAC_HASH_CMAC_BLOCK_SIZE; 321 memcpy(ptr, k2, LAC_HASH_CMAC_BLOCK_SIZE); 322 status = CPA_STATUS_SUCCESS; 323 } else if (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm || 324 CPA_CY_SYM_HASH_AES_GMAC == hashAlgorithm) { 325 Cpa8U *in = pWorkingMemory; 326 Cpa8U *out = pState; 327 LAC_OS_BZERO(pWorkingMemory, ICP_QAT_HW_GALOIS_H_SZ); 328 329 if (CPA_STATUS_SUCCESS != 330 qatUtilsAESEncrypt(pAuthKey, authKeyLenInBytes, in, out)) { 331 return status; 332 } 333 status = CPA_STATUS_SUCCESS; 334 } else { 335 return CPA_STATUS_INVALID_PARAM; 336 } 337 callbackFn(pCallbackTag); 338 return status; 339} 340 341CpaStatus 342LacSymHash_HmacPrecompInit(CpaInstanceHandle instanceHandle) 343{ 344 CpaStatus status = CPA_STATUS_SUCCESS; 345 return status; 346} 347 348void 349LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle) 350{ 351 return; 352} 353