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