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
LacSymHash_Compute(CpaCySymHashAlgorithm hashAlgorithm,lac_sym_qat_hash_alg_info_t * pHashAlgInfo,Cpa8U * in,Cpa8U * out)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
LacSymHash_HmacPreComputes(CpaInstanceHandle instanceHandle,CpaCySymHashAlgorithm hashAlgorithm,Cpa32U authKeyLenInBytes,Cpa8U * pAuthKey,Cpa8U * pWorkingMemory,Cpa8U * pState1,Cpa8U * pState2,lac_hash_precompute_done_cb_t callbackFn,void * pCallbackTag)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
LacSymHash_AesECBPreCompute(CpaInstanceHandle instanceHandle,CpaCySymHashAlgorithm hashAlgorithm,Cpa32U authKeyLenInBytes,Cpa8U * pAuthKey,Cpa8U * pWorkingMemory,Cpa8U * pState,lac_hash_precompute_done_cb_t callbackFn,void * pCallbackTag)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
LacSymHash_HmacPrecompInit(CpaInstanceHandle instanceHandle)342 LacSymHash_HmacPrecompInit(CpaInstanceHandle instanceHandle)
343 {
344 CpaStatus status = CPA_STATUS_SUCCESS;
345 return status;
346 }
347
348 void
LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle)349 LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle)
350 {
351 return;
352 }
353