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