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