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 
46 static CpaStatus
47 LacSymHash_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 
134 CpaStatus
135 LacSymHash_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 
213 CpaStatus
214 LacSymHash_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 
341 CpaStatus
342 LacSymHash_HmacPrecompInit(CpaInstanceHandle instanceHandle)
343 {
344 	CpaStatus status = CPA_STATUS_SUCCESS;
345 	return status;
346 }
347 
348 void
349 LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle)
350 {
351 	return;
352 }
353