1/***************************************************************************
2 *
3 * <COPYRIGHT_TAG>
4 *
5 ***************************************************************************/
6
7/**
8 *****************************************************************************
9 * @file lac_sym_key.c
10 *
11 * @ingroup LacSymKey
12 *
13 * This file contains the implementation of all keygen functionality
14 *
15 *****************************************************************************/
16
17/*
18*******************************************************************************
19* Include public/global header files
20*******************************************************************************
21*/
22#include "cpa.h"
23#include "cpa_cy_key.h"
24#include "cpa_cy_im.h"
25
26/*
27*******************************************************************************
28* Include private header files
29*******************************************************************************
30*/
31#include "icp_accel_devices.h"
32#include "icp_adf_debug.h"
33#include "icp_adf_init.h"
34#include "icp_adf_transport.h"
35
36#include "qat_utils.h"
37
38#include "lac_log.h"
39#include "lac_hooks.h"
40#include "lac_sym.h"
41#include "lac_sym_qat_hash_defs_lookup.h"
42#include "lac_sym_qat.h"
43#include "lac_sal.h"
44#include "lac_sym_key.h"
45#include "lac_sal_types_crypto.h"
46#include "sal_service_state.h"
47#include "lac_sym_qat_key.h"
48#include "lac_sym_hash_defs.h"
49#include "sal_statistics.h"
50
51/* Number of statistics */
52#define LAC_KEY_NUM_STATS (sizeof(CpaCyKeyGenStats64) / sizeof(Cpa64U))
53
54#define LAC_KEY_STAT_INC(statistic, instanceHandle)                            \
55	do {                                                                   \
56		sal_crypto_service_t *pService = NULL;                         \
57		pService = (sal_crypto_service_t *)instanceHandle;             \
58		if (CPA_TRUE ==                                                \
59		    pService->generic_service_info.stats                       \
60			->bKeyGenStatsEnabled) {                               \
61			qatUtilsAtomicInc(                                     \
62			    &pService                                          \
63				 ->pLacKeyStats[offsetof(CpaCyKeyGenStats64,   \
64							 statistic) /          \
65						sizeof(Cpa64U)]);              \
66		}                                                              \
67	} while (0)
68/**< Macro to increment a Key stat (derives offset into array of atomics) */
69
70#define LAC_KEY_STATS32_GET(keyStats, instanceHandle)                          \
71	do {                                                                   \
72		int i;                                                         \
73		sal_crypto_service_t *pService =                               \
74		    (sal_crypto_service_t *)instanceHandle;                    \
75		for (i = 0; i < LAC_KEY_NUM_STATS; i++) {                      \
76			((Cpa32U *)&(keyStats))[i] =                           \
77			    (Cpa32U)qatUtilsAtomicGet(                         \
78				&pService->pLacKeyStats[i]);                   \
79		}                                                              \
80	} while (0)
81/**< Macro to get all 32bit Key stats (from internal array of atomics) */
82
83#define LAC_KEY_STATS64_GET(keyStats, instanceHandle)                          \
84	do {                                                                   \
85		int i;                                                         \
86		sal_crypto_service_t *pService =                               \
87		    (sal_crypto_service_t *)instanceHandle;                    \
88		for (i = 0; i < LAC_KEY_NUM_STATS; i++) {                      \
89			((Cpa64U *)&(keyStats))[i] =                           \
90			    qatUtilsAtomicGet(&pService->pLacKeyStats[i]);     \
91		}                                                              \
92	} while (0)
93/**< Macro to get all 64bit Key stats (from internal array of atomics) */
94
95#define IS_HKDF_UNSUPPORTED(cmdId, hkdfSupported)                              \
96	((ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= cmdId &&                           \
97	  ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL >= cmdId) &&         \
98	 !hkdfSupported) /**< macro to check whether the HKDF algorithm can be \
99			    supported on the device */
100
101/* Sublabel for HKDF TLS Key Generation, as defined in RFC8446. */
102const static Cpa8U key256[HKDF_SUB_LABEL_KEY_LENGTH] = { 0,   16,  9,   't',
103							 'l', 's', '1', '3',
104							 ' ', 'k', 'e', 'y',
105							 0 };
106const static Cpa8U key384[HKDF_SUB_LABEL_KEY_LENGTH] = { 0,   32,  9,   't',
107							 'l', 's', '1', '3',
108							 ' ', 'k', 'e', 'y',
109							 0 };
110const static Cpa8U keyChaChaPoly[HKDF_SUB_LABEL_KEY_LENGTH] = { 0,   32,  9,
111								't', 'l', 's',
112								'1', '3', ' ',
113								'k', 'e', 'y',
114								0 };
115/* Sublabel for HKDF TLS IV key Generation, as defined in RFC8446. */
116const static Cpa8U iv256[HKDF_SUB_LABEL_IV_LENGTH] = { 0,   12,  8,   't',
117						       'l', 's', '1', '3',
118						       ' ', 'i', 'v', 0 };
119const static Cpa8U iv384[HKDF_SUB_LABEL_IV_LENGTH] = { 0,   12,  8,   't',
120						       'l', 's', '1', '3',
121						       ' ', 'i', 'v', 0 };
122/* Sublabel for HKDF TLS RESUMPTION key Generation, as defined in RFC8446. */
123const static Cpa8U resumption256[HKDF_SUB_LABEL_RESUMPTION_LENGTH] =
124    { 0,   32,  16,  't', 'l', 's', '1', '3', ' ', 'r',
125      'e', 's', 'u', 'm', 'p', 't', 'i', 'o', 'n', 0 };
126const static Cpa8U resumption384[HKDF_SUB_LABEL_RESUMPTION_LENGTH] =
127    { 0,   48,  16,  't', 'l', 's', '1', '3', ' ', 'r',
128      'e', 's', 'u', 'm', 'p', 't', 'i', 'o', 'n', 0 };
129/* Sublabel for HKDF TLS FINISHED key Generation, as defined in RFC8446. */
130const static Cpa8U finished256[HKDF_SUB_LABEL_FINISHED_LENGTH] =
131    { 0,   32,  14,  't', 'l', 's', '1', '3', ' ',
132      'f', 'i', 'n', 'i', 's', 'h', 'e', 'd', 0 };
133const static Cpa8U finished384[HKDF_SUB_LABEL_FINISHED_LENGTH] =
134    { 0,   48,  14,  't', 'l', 's', '1', '3', ' ',
135      'f', 'i', 'n', 'i', 's', 'h', 'e', 'd', 0 };
136
137/**
138 ******************************************************************************
139 * @ingroup LacSymKey
140 *      SSL/TLS stat type
141 *
142 * @description
143 *      This enum determines which stat should be incremented
144 *****************************************************************************/
145typedef enum {
146	LAC_KEY_REQUESTS = 0,
147	/**< Key requests sent */
148	LAC_KEY_REQUEST_ERRORS,
149	/**< Key requests errors */
150	LAC_KEY_COMPLETED,
151	/**< Key requests which received responses */
152	LAC_KEY_COMPLETED_ERRORS
153	/**< Key requests which received responses with errors */
154} lac_key_stat_type_t;
155
156/*** Local functions prototypes ***/
157static void
158LacSymKey_MgfHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
159			    void *pOpaqueData,
160			    icp_qat_fw_comn_flags cmnRespFlags);
161
162static CpaStatus
163LacSymKey_MgfSync(const CpaInstanceHandle instanceHandle,
164		  const CpaCyGenFlatBufCbFunc pKeyGenCb,
165		  void *pCallbackTag,
166		  const void *pKeyGenMgfOpData,
167		  CpaFlatBuffer *pGeneratedMaskBuffer,
168		  CpaBoolean bIsExtRequest);
169
170static void
171LacSymKey_SslTlsHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
172			       void *pOpaqueData,
173			       icp_qat_fw_comn_flags cmnRespFlags);
174
175static CpaStatus
176LacSymKey_SslTlsSync(CpaInstanceHandle instanceHandle,
177		     const CpaCyGenFlatBufCbFunc pKeyGenCb,
178		     void *pCallbackTag,
179		     icp_qat_fw_la_cmd_id_t lacCmdId,
180		     void *pKeyGenSslTlsOpData,
181		     Cpa8U hashAlgorithm,
182		     CpaFlatBuffer *pKeyGenOutpuData);
183
184/*** Implementation ***/
185
186/**
187 ******************************************************************************
188 * @ingroup LacSymKey
189 *      Get the instance handle. Support single handle.
190 * @param[in] instanceHandle_in        user supplied handle.
191 * @retval    CpaInstanceHandle        the instance handle
192 */
193static CpaInstanceHandle
194LacKey_GetHandle(CpaInstanceHandle instanceHandle_in)
195{
196	CpaInstanceHandle instanceHandle = NULL;
197	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
198		instanceHandle =
199		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
200	} else {
201		instanceHandle = instanceHandle_in;
202	}
203	return instanceHandle;
204}
205
206/**
207*******************************************************************************
208* @ingroup LacSymKey
209*      Perform SSL/TLS key gen operation
210*
211* @description
212*      Perform SSL/TLS key gen operation
213*
214* @param[in] instanceHandle        QAT device handle.
215* @param[in] pKeyGenCb             Pointer to callback function to be invoked
216*                                  when the operation is complete.
217* @param[in] pCallbackTag          Opaque User Data for this specific call.
218* @param[in] lacCmdId              Lac command ID (identify SSL & TLS ops)
219* @param[in] pKeyGenSslTlsOpData   Structure containing all the data needed to
220*                                  perform the SSL/TLS key generation
221*                                  operation.
222* @param[in]  hashAlgorithm        Specifies the hash algorithm to use.
223*                                  According to RFC5246, this should be
224*                                  "SHA-256 or a stronger standard hash
225*                                  function."
226* @param[out] pKeyGenOutputData    pointer to where output result should be
227*                                  written
228*
229* @retval CPA_STATUS_SUCCESS       Function executed successfully.
230* @retval CPA_STATUS_FAIL           Function failed.
231* @retval CPA_STATUS_RETRY          Function should be retried.
232* @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in.
233* @retval CPA_STATUS_RESOURCE       Error related to system resources.
234*
235*****************************************************************************/
236static CpaStatus
237LacSymKey_KeyGenSslTls_GenCommon(CpaInstanceHandle instanceHandle,
238				 const CpaCyGenFlatBufCbFunc pKeyGenCb,
239				 void *pCallbackTag,
240				 icp_qat_fw_la_cmd_id_t lacCmdId,
241				 void *pKeyGenSslTlsOpData,
242				 Cpa8U hashAlgorithm,
243				 CpaFlatBuffer *pKeyGenOutputData);
244
245/**
246 ******************************************************************************
247 * @ingroup LacSymKey
248 *      Increment stat for TLS or SSL operation
249 *
250 * @description
251 *      This is a generic function to update the stats for either a TLS or SSL
252 *      operation.
253 *
254 * @param[in] lacCmdId          Indicate SSL or TLS operations
255 * @param[in] statType          Statistics Type
256 * @param[in] instanceHandle    Instance Handle
257 *
258 * @return None
259 *
260 *****************************************************************************/
261static void
262LacKey_StatsInc(icp_qat_fw_la_cmd_id_t lacCmdId,
263		lac_key_stat_type_t statType,
264		CpaInstanceHandle instanceHandle)
265{
266	if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
267		switch (statType) {
268		case LAC_KEY_REQUESTS:
269			LAC_KEY_STAT_INC(numSslKeyGenRequests, instanceHandle);
270			break;
271		case LAC_KEY_REQUEST_ERRORS:
272			LAC_KEY_STAT_INC(numSslKeyGenRequestErrors,
273					 instanceHandle);
274			break;
275		case LAC_KEY_COMPLETED:
276			LAC_KEY_STAT_INC(numSslKeyGenCompleted, instanceHandle);
277			break;
278		case LAC_KEY_COMPLETED_ERRORS:
279			LAC_KEY_STAT_INC(numSslKeyGenCompletedErrors,
280					 instanceHandle);
281			break;
282		default:
283			QAT_UTILS_LOG("Invalid statistics type\n");
284			break;
285		}
286	} else /* TLS v1.0/1.1 and 1.2 */
287	{
288		switch (statType) {
289		case LAC_KEY_REQUESTS:
290			LAC_KEY_STAT_INC(numTlsKeyGenRequests, instanceHandle);
291			break;
292		case LAC_KEY_REQUEST_ERRORS:
293			LAC_KEY_STAT_INC(numTlsKeyGenRequestErrors,
294					 instanceHandle);
295			break;
296		case LAC_KEY_COMPLETED:
297			LAC_KEY_STAT_INC(numTlsKeyGenCompleted, instanceHandle);
298			break;
299		case LAC_KEY_COMPLETED_ERRORS:
300			LAC_KEY_STAT_INC(numTlsKeyGenCompletedErrors,
301					 instanceHandle);
302			break;
303		default:
304			QAT_UTILS_LOG("Invalid statistics type\n");
305			break;
306		}
307	}
308}
309
310void
311LacKeygen_StatsShow(CpaInstanceHandle instanceHandle)
312{
313	CpaCyKeyGenStats64 keyStats = { 0 };
314
315	LAC_KEY_STATS64_GET(keyStats, instanceHandle);
316
317	QAT_UTILS_LOG(SEPARATOR BORDER
318		      "                  Key Stats:                " BORDER
319		      "\n" SEPARATOR);
320
321	QAT_UTILS_LOG(BORDER " SSL Key Requests:               %16llu " BORDER
322			     "\n" BORDER
323			     " SSL Key Request Errors:         %16llu " BORDER
324			     "\n" BORDER
325			     " SSL Key Completed               %16llu " BORDER
326			     "\n" BORDER
327			     " SSL Key Complete Errors:        %16llu " BORDER
328			     "\n" SEPARATOR,
329		      (unsigned long long)keyStats.numSslKeyGenRequests,
330		      (unsigned long long)keyStats.numSslKeyGenRequestErrors,
331		      (unsigned long long)keyStats.numSslKeyGenCompleted,
332		      (unsigned long long)keyStats.numSslKeyGenCompletedErrors);
333
334	QAT_UTILS_LOG(BORDER " TLS Key Requests:               %16llu " BORDER
335			     "\n" BORDER
336			     " TLS Key Request Errors:         %16llu " BORDER
337			     "\n" BORDER
338			     " TLS Key Completed               %16llu " BORDER
339			     "\n" BORDER
340			     " TLS Key Complete Errors:        %16llu " BORDER
341			     "\n" SEPARATOR,
342		      (unsigned long long)keyStats.numTlsKeyGenRequests,
343		      (unsigned long long)keyStats.numTlsKeyGenRequestErrors,
344		      (unsigned long long)keyStats.numTlsKeyGenCompleted,
345		      (unsigned long long)keyStats.numTlsKeyGenCompletedErrors);
346
347	QAT_UTILS_LOG(BORDER " MGF Key Requests:               %16llu " BORDER
348			     "\n" BORDER
349			     " MGF Key Request Errors:         %16llu " BORDER
350			     "\n" BORDER
351			     " MGF Key Completed               %16llu " BORDER
352			     "\n" BORDER
353			     " MGF Key Complete Errors:        %16llu " BORDER
354			     "\n" SEPARATOR,
355		      (unsigned long long)keyStats.numMgfKeyGenRequests,
356		      (unsigned long long)keyStats.numMgfKeyGenRequestErrors,
357		      (unsigned long long)keyStats.numMgfKeyGenCompleted,
358		      (unsigned long long)keyStats.numMgfKeyGenCompletedErrors);
359}
360
361/** @ingroup LacSymKey */
362CpaStatus
363cpaCyKeyGenQueryStats(CpaInstanceHandle instanceHandle_in,
364		      struct _CpaCyKeyGenStats *pSymKeyStats)
365{
366	CpaInstanceHandle instanceHandle = NULL;
367
368
369	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
370		instanceHandle =
371		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
372	} else {
373		instanceHandle = instanceHandle_in;
374	}
375
376	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
377	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
378				(SAL_SERVICE_TYPE_CRYPTO |
379				 SAL_SERVICE_TYPE_CRYPTO_SYM));
380	LAC_CHECK_NULL_PARAM(pSymKeyStats);
381
382	SAL_RUNNING_CHECK(instanceHandle);
383
384	LAC_KEY_STATS32_GET(*pSymKeyStats, instanceHandle);
385
386	return CPA_STATUS_SUCCESS;
387}
388
389/** @ingroup LacSymKey */
390CpaStatus
391cpaCyKeyGenQueryStats64(CpaInstanceHandle instanceHandle_in,
392			CpaCyKeyGenStats64 *pSymKeyStats)
393{
394	CpaInstanceHandle instanceHandle = NULL;
395
396
397	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
398		instanceHandle =
399		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
400	} else {
401		instanceHandle = instanceHandle_in;
402	}
403
404	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
405	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
406				(SAL_SERVICE_TYPE_CRYPTO |
407				 SAL_SERVICE_TYPE_CRYPTO_SYM));
408	LAC_CHECK_NULL_PARAM(pSymKeyStats);
409
410	SAL_RUNNING_CHECK(instanceHandle);
411
412	LAC_KEY_STATS64_GET(*pSymKeyStats, instanceHandle);
413
414	return CPA_STATUS_SUCCESS;
415}
416
417/**
418 ******************************************************************************
419 * @ingroup LacSymKey
420 *      Return the size of the digest for a specific hash algorithm.
421 * @description
422 *      Return the expected digest size based on the sha algorithm submitted.
423 *      The only supported value are sha256, sha384 and sha512.
424 *
425 * @param[in]  hashAlgorithm        either sha256, sha384 or sha512.
426 * @return the expected size or 0 for an invalid hash.
427 *
428 *****************************************************************************/
429static Cpa32U
430getDigestSizeFromHashAlgo(CpaCySymHashAlgorithm hashAlgorithm)
431{
432	switch (hashAlgorithm) {
433	case CPA_CY_SYM_HASH_SHA256:
434		return LAC_HASH_SHA256_DIGEST_SIZE;
435	case CPA_CY_SYM_HASH_SHA384:
436		return LAC_HASH_SHA384_DIGEST_SIZE;
437	case CPA_CY_SYM_HASH_SHA512:
438		return LAC_HASH_SHA512_DIGEST_SIZE;
439	case CPA_CY_SYM_HASH_SM3:
440		return LAC_HASH_SM3_DIGEST_SIZE;
441	default:
442		return 0;
443	}
444}
445
446/**
447 ******************************************************************************
448 * @ingroup LacSymKey
449 *      Return the hash algorithm for a specific cipher.
450 * @description
451 *      Return the hash algorithm related to the cipher suite.
452 *      Supported hash's are SHA256, and SHA384.
453 *
454 * @param[in]  cipherSuite AES_128_GCM, AES_256_GCM, AES_128_CCM,
455 *             and CHACHA20_POLY1305.
456 * @return the expected hash algorithm or 0 for an invalid cipher.
457 *
458 *****************************************************************************/
459static CpaCySymHashAlgorithm
460getHashAlgorithmFromCipherSuiteHKDF(CpaCyKeyHKDFCipherSuite cipherSuite)
461{
462	switch (cipherSuite) {
463	case CPA_CY_HKDF_TLS_AES_128_GCM_SHA256: /* Fall through */
464	case CPA_CY_HKDF_TLS_CHACHA20_POLY1305_SHA256:
465	case CPA_CY_HKDF_TLS_AES_128_CCM_SHA256:
466	case CPA_CY_HKDF_TLS_AES_128_CCM_8_SHA256:
467		return CPA_CY_SYM_HASH_SHA256;
468	case CPA_CY_HKDF_TLS_AES_256_GCM_SHA384:
469		return CPA_CY_SYM_HASH_SHA384;
470	default:
471		return 0;
472	}
473}
474
475/**
476 ******************************************************************************
477 * @ingroup LacSymKey
478 *      Return the digest size of cipher.
479 * @description
480 *      Return the output key size of specific cipher, for specified sub label
481 *
482 * @param[in]  cipherSuite = AES_128_GCM, AES_256_GCM, AES_128_CCM,
483 *             and CHACHA20_POLY1305.
484 *             subLabels = KEY, IV, RESUMPTION, and FINISHED.
485 * @return the expected digest size of the cipher.
486 *
487 *****************************************************************************/
488static const Cpa32U cipherSuiteHKDFHashSizes
489    [LAC_KEY_HKDF_CIPHERS_MAX][LAC_KEY_HKDF_SUBLABELS_MAX] = {
490	    {},			    /* Not used */
491	    { 32, 16, 12, 32, 32 }, /* AES_128_GCM_SHA256 */
492	    { 48, 32, 12, 48, 48 }, /* AES_256_GCM_SHA384 */
493	    { 32, 32, 12, 32, 32 }, /* CHACHA20_POLY1305_SHA256 */
494	    { 32, 16, 12, 32, 32 }, /* AES_128_CCM_SHA256 */
495	    { 32, 16, 12, 32, 32 }  /* AES_128_CCM_8_SHA256 */
496    };
497
498/**
499 ******************************************************************************
500 * @ingroup LacSymKey
501 *      Key Generation MGF response handler
502 *
503 * @description
504 *      Handles Key Generation MGF response messages from the QAT.
505 *
506 * @param[in] lacCmdId       Command id of the original request
507 * @param[in] pOpaqueData    Pointer to opaque data that was in request
508 * @param[in] cmnRespFlags   Indicates whether request succeeded
509 *
510 * @return void
511 *
512 *****************************************************************************/
513static void
514LacSymKey_MgfHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
515			    void *pOpaqueData,
516			    icp_qat_fw_comn_flags cmnRespFlags)
517{
518	CpaCyKeyGenMgfOpData *pMgfOpData = NULL;
519	lac_sym_key_cookie_t *pCookie = NULL;
520	CpaCyGenFlatBufCbFunc pKeyGenMgfCb = NULL;
521	void *pCallbackTag = NULL;
522	CpaFlatBuffer *pGeneratedKeyBuffer = NULL;
523	CpaStatus status = CPA_STATUS_SUCCESS;
524	CpaBoolean respStatusOk =
525	    (ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
526	     ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(cmnRespFlags)) ?
527	    CPA_TRUE :
528	    CPA_FALSE;
529
530	pCookie = (lac_sym_key_cookie_t *)pOpaqueData;
531
532	if (CPA_TRUE == respStatusOk) {
533		status = CPA_STATUS_SUCCESS;
534		LAC_KEY_STAT_INC(numMgfKeyGenCompleted,
535				 pCookie->instanceHandle);
536	} else {
537		status = CPA_STATUS_FAIL;
538		LAC_KEY_STAT_INC(numMgfKeyGenCompletedErrors,
539				 pCookie->instanceHandle);
540	}
541
542	pKeyGenMgfCb = (CpaCyGenFlatBufCbFunc)(pCookie->pKeyGenCb);
543
544	pMgfOpData = pCookie->pKeyGenOpData;
545	pCallbackTag = pCookie->pCallbackTag;
546	pGeneratedKeyBuffer = pCookie->pKeyGenOutputData;
547
548	Lac_MemPoolEntryFree(pCookie);
549
550	(*pKeyGenMgfCb)(pCallbackTag, status, pMgfOpData, pGeneratedKeyBuffer);
551}
552
553/**
554 ******************************************************************************
555 * @ingroup LacSymKey
556 *      Synchronous mode of operation wrapper function
557 *
558 * @description
559 *      Wrapper function to implement synchronous mode of operation for
560 *      cpaCyKeyGenMgf and cpaCyKeyGenMgfExt function.
561 *
562 * @param[in] instanceHandle       Instance handle
563 * @param[in] pKeyGenCb            Internal callback function pointer
564 * @param[in] pCallbackTag         Callback tag
565 * @param[in] pKeyGenMgfOpData     Pointer to user provided Op Data structure
566 * @param[in] pGeneratedMaskBuffer Pointer to a buffer where generated mask
567 *                                 will be stored
568 * @param[in] bIsExtRequest        Indicates origin of function call;
569 *                                 if CPA_TRUE then the call comes from
570 *                                 cpaCyKeyGenMgfExt function, otherwise
571 *                                 from cpaCyKeyGenMgf
572 *
573 * @retval CPA_STATUS_SUCCESS        Function executed successfully.
574 * @retval CPA_STATUS_FAIL           Function failed.
575 * @retval CPA_STATUS_RETRY          Function should be retried.
576 * @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in.
577 * @retval CPA_STATUS_RESOURCE       Error related to system resources.
578 *
579 *****************************************************************************/
580static CpaStatus
581LacSymKey_MgfSync(const CpaInstanceHandle instanceHandle,
582		  const CpaCyGenFlatBufCbFunc pKeyGenCb,
583		  void *pCallbackTag,
584		  const void *pKeyGenMgfOpData,
585		  CpaFlatBuffer *pGeneratedMaskBuffer,
586		  CpaBoolean bIsExtRequest)
587{
588	CpaStatus status = CPA_STATUS_SUCCESS;
589
590	lac_sync_op_data_t *pSyncCallbackData = NULL;
591
592	status = LacSync_CreateSyncCookie(&pSyncCallbackData);
593
594	if (CPA_STATUS_SUCCESS == status) {
595		if (CPA_TRUE == bIsExtRequest) {
596			status = cpaCyKeyGenMgfExt(
597			    instanceHandle,
598			    LacSync_GenFlatBufCb,
599			    pSyncCallbackData,
600			    (const CpaCyKeyGenMgfOpDataExt *)pKeyGenMgfOpData,
601			    pGeneratedMaskBuffer);
602		} else {
603			status = cpaCyKeyGenMgf(instanceHandle,
604						LacSync_GenFlatBufCb,
605						pSyncCallbackData,
606						(const CpaCyKeyGenMgfOpData *)
607						    pKeyGenMgfOpData,
608						pGeneratedMaskBuffer);
609		}
610	} else {
611		/* Failure allocating sync cookie */
612		LAC_KEY_STAT_INC(numMgfKeyGenRequestErrors, instanceHandle);
613		return status;
614	}
615
616	if (CPA_STATUS_SUCCESS == status) {
617		CpaStatus syncStatus = CPA_STATUS_SUCCESS;
618
619		syncStatus =
620		    LacSync_WaitForCallback(pSyncCallbackData,
621					    LAC_SYM_SYNC_CALLBACK_TIMEOUT,
622					    &status,
623					    NULL);
624
625		/* If callback doesn't come back */
626		if (CPA_STATUS_SUCCESS != syncStatus) {
627			LAC_KEY_STAT_INC(numMgfKeyGenCompletedErrors,
628					 instanceHandle);
629			LAC_LOG_ERROR("Callback timed out");
630			status = syncStatus;
631		}
632	} else {
633		/* As the Request was not sent the Callback will never
634		 * be called, so need to indicate that we're finished
635		 * with cookie so it can be destroyed.
636		 */
637		LacSync_SetSyncCookieComplete(pSyncCallbackData);
638	}
639
640	LacSync_DestroySyncCookie(&pSyncCallbackData);
641
642	return status;
643}
644
645/**
646 ******************************************************************************
647 * @ingroup LacSymKey
648 *      Perform MGF key gen operation
649 *
650 * @description
651 *      This function performs MGF key gen operation. It is common for requests
652 *      coming from both cpaCyKeyGenMgf and cpaCyKeyGenMgfExt QAT API
653 *      functions.
654 *
655 * @param[in] instanceHandle       Instance handle
656 * @param[in] pKeyGenCb            Pointer to callback function to be invoked
657 *                                 when the operation is complete.
658 * @param[in] pCallbackTag         Opaque User Data for this specific call.
659 * @param[in] pOpData              Pointer to the Op Data structure provided by
660 *                                 the user in API function call. For calls
661 *                                 originating from cpaCyKeyGenMgfExt it will
662 *                                 point to CpaCyKeyGenMgfOpDataExt type of
663 *                                 structure while for calls originating from
664 *                                 cpaCyKeyGenMgf it will point to
665 *                                 CpaCyKeyGenMgfOpData type of structure.
666 * @param[in] pKeyGenMgfOpData     Pointer to the user provided
667 *                                 CpaCyKeyGenMgfOpData structure. For calls
668 *                                 originating from cpaCyKeyGenMgf it will
669 *                                 point to the same structure as pOpData
670 *                                 parameter; for calls originating from
671 *                                 cpaCyKeyGenMgfExt it will point to the
672 *                                 baseOpData member of the
673 *                                 CpaCyKeyGenMgfOpDataExt structure passed in
674 *                                 as a parameter to the API function call.
675 * @param[in] pGeneratedMaskBuffer Pointer to a buffer where generated mask
676 *                                 will be stored
677 * @param[in] hashAlgorithm        Indicates which hash algorithm is to be used
678 *                                 to perform MGF key gen operation. For calls
679 *                                 originating from cpaCyKeyGenMgf it will
680 *                                 always be CPA_CY_SYM_HASH_SHA1.
681 *
682 * @retval CPA_STATUS_SUCCESS        Function executed successfully.
683 * @retval CPA_STATUS_FAIL           Function failed.
684 * @retval CPA_STATUS_RETRY          Function should be retried.
685 * @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in.
686 * @retval CPA_STATUS_RESOURCE       Error related to system resources.
687 *
688 *****************************************************************************/
689static CpaStatus
690LacSymKey_MgfCommon(const CpaInstanceHandle instanceHandle,
691		    const CpaCyGenFlatBufCbFunc pKeyGenCb,
692		    void *pCallbackTag,
693		    const void *pOpData,
694		    const CpaCyKeyGenMgfOpData *pKeyGenMgfOpData,
695		    CpaFlatBuffer *pGeneratedMaskBuffer,
696		    CpaCySymHashAlgorithm hashAlgorithm)
697{
698	CpaStatus status = CPA_STATUS_SUCCESS;
699
700	icp_qat_fw_la_bulk_req_t keyGenReq = { { 0 } };
701	icp_qat_la_bulk_req_hdr_t keyGenReqHdr = { { 0 } };
702	icp_qat_fw_la_key_gen_common_t keyGenReqMid = { { 0 } };
703	icp_qat_la_bulk_req_ftr_t keyGenReqFtr = { { { 0 } } };
704	Cpa8U *pMsgDummy = NULL;
705	Cpa8U *pCacheDummyHdr = NULL;
706	Cpa8U *pCacheDummyMid = NULL;
707	Cpa8U *pCacheDummyFtr = NULL;
708	sal_qat_content_desc_info_t contentDescInfo = { 0 };
709	lac_sym_key_cookie_t *pCookie = NULL;
710	lac_sym_cookie_t *pSymCookie = NULL;
711	sal_crypto_service_t *pService = NULL;
712	Cpa64U inputPhysAddr = 0;
713	Cpa64U outputPhysAddr = 0;
714/* Structure initializer is supported by C99, but it is
715 * not supported by some former Intel compiler.
716 */
717	CpaCySymHashSetupData hashSetupData = { 0 };
718	Cpa32U hashBlkSizeInBytes = 0;
719	lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
720	icp_qat_fw_serv_specif_flags laCmdFlags = 0;
721	icp_qat_fw_comn_flags cmnRequestFlags =
722	    ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
723					QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
724
725	pService = (sal_crypto_service_t *)instanceHandle;
726	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
727	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
728				(SAL_SERVICE_TYPE_CRYPTO |
729				 SAL_SERVICE_TYPE_CRYPTO_SYM));
730
731	SAL_RUNNING_CHECK(instanceHandle);
732	LAC_CHECK_NULL_PARAM(pOpData);
733	LAC_CHECK_NULL_PARAM(pKeyGenMgfOpData);
734	LAC_CHECK_NULL_PARAM(pGeneratedMaskBuffer);
735	LAC_CHECK_NULL_PARAM(pGeneratedMaskBuffer->pData);
736	LAC_CHECK_NULL_PARAM(pKeyGenMgfOpData->seedBuffer.pData);
737
738	/* Maximum seed length for MGF1 request */
739	if (pKeyGenMgfOpData->seedBuffer.dataLenInBytes >
740	    ICP_QAT_FW_LA_MGF_SEED_LEN_MAX) {
741		LAC_INVALID_PARAM_LOG("seedBuffer.dataLenInBytes");
742		return CPA_STATUS_INVALID_PARAM;
743	}
744
745	/* Maximum mask length for MGF1 request */
746	if (pKeyGenMgfOpData->maskLenInBytes > ICP_QAT_FW_LA_MGF_MASK_LEN_MAX) {
747		LAC_INVALID_PARAM_LOG("maskLenInBytes");
748		return CPA_STATUS_INVALID_PARAM;
749	}
750
751	/* check for enough space in the flat buffer */
752	if (pKeyGenMgfOpData->maskLenInBytes >
753	    pGeneratedMaskBuffer->dataLenInBytes) {
754		LAC_INVALID_PARAM_LOG("pGeneratedMaskBuffer.dataLenInBytes");
755		return CPA_STATUS_INVALID_PARAM;
756	}
757
758	/* Get hash alg info */
759	LacSymQat_HashAlgLookupGet(instanceHandle,
760				   hashAlgorithm,
761				   &pHashAlgInfo);
762
763	/* Allocate the cookie */
764	pCookie = (lac_sym_key_cookie_t *)Lac_MemPoolEntryAlloc(
765	    pService->lac_sym_cookie_pool);
766	if (NULL == pCookie) {
767		LAC_LOG_ERROR("Cannot get mem pool entry");
768		status = CPA_STATUS_RESOURCE;
769	} else if ((void *)CPA_STATUS_RETRY == pCookie) {
770		pCookie = NULL;
771		status = CPA_STATUS_RETRY;
772	} else {
773		pSymCookie = (lac_sym_cookie_t *)pCookie;
774	}
775
776	if (CPA_STATUS_SUCCESS == status) {
777		/* populate the cookie */
778		pCookie->instanceHandle = instanceHandle;
779		pCookie->pCallbackTag = pCallbackTag;
780		pCookie->pKeyGenOpData = (void *)LAC_CONST_PTR_CAST(pOpData);
781		pCookie->pKeyGenCb = pKeyGenCb;
782		pCookie->pKeyGenOutputData = pGeneratedMaskBuffer;
783		hashSetupData.hashAlgorithm = hashAlgorithm;
784		hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
785		hashSetupData.digestResultLenInBytes =
786		    pHashAlgInfo->digestLength;
787
788		/* Populate the CD ctrl Block (LW 27 - LW 31)
789		 * and the CD Hash HW setup block
790		 */
791		LacSymQat_HashContentDescInit(
792		    &(keyGenReqFtr),
793		    instanceHandle,
794		    &hashSetupData,
795		    /* point to base of hw setup block */
796		    (Cpa8U *)pCookie->contentDesc,
797		    LAC_SYM_KEY_NO_HASH_BLK_OFFSET_QW,
798		    ICP_QAT_FW_SLICE_DRAM_WR,
799		    ICP_QAT_HW_AUTH_MODE0, /* just a plain hash */
800		    CPA_FALSE, /* Not using sym Constants Table in Shared SRAM
801				*/
802		    CPA_FALSE, /* not using the optimised Content Desc */
803		    CPA_FALSE, /* Not using the stateful SHA3 Content Desc */
804		    NULL,
805		    &hashBlkSizeInBytes);
806
807		/* Populate the Req param LW 14-26 */
808		LacSymQat_KeyMgfRequestPopulate(
809		    &keyGenReqHdr,
810		    &keyGenReqMid,
811		    pKeyGenMgfOpData->seedBuffer.dataLenInBytes,
812		    pKeyGenMgfOpData->maskLenInBytes,
813		    (Cpa8U)pHashAlgInfo->digestLength);
814
815		contentDescInfo.pData = pCookie->contentDesc;
816		contentDescInfo.hardwareSetupBlockPhys =
817		    LAC_MEM_CAST_PTR_TO_UINT64(
818			pSymCookie->keyContentDescPhyAddr);
819		contentDescInfo.hwBlkSzQuadWords =
820		    LAC_BYTES_TO_QUADWORDS(hashBlkSizeInBytes);
821
822		/* Populate common request fields */
823		inputPhysAddr =
824		    LAC_MEM_CAST_PTR_TO_UINT64(LAC_OS_VIRT_TO_PHYS_EXTERNAL(
825			pService->generic_service_info,
826			pKeyGenMgfOpData->seedBuffer.pData));
827
828		if (inputPhysAddr == 0) {
829			LAC_LOG_ERROR(
830			    "Unable to get the seed buffer physical address");
831			status = CPA_STATUS_FAIL;
832		}
833		outputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
834		    LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
835						 pGeneratedMaskBuffer->pData));
836		if (outputPhysAddr == 0) {
837			LAC_LOG_ERROR(
838			    "Unable to get the physical address of the mask");
839			status = CPA_STATUS_FAIL;
840		}
841	}
842
843	if (CPA_STATUS_SUCCESS == status) {
844		/* Make up the full keyGenReq struct from its constituents */
845		pMsgDummy = (Cpa8U *)&(keyGenReq);
846		pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
847		pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
848		pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
849
850		memcpy(pMsgDummy,
851		       pCacheDummyHdr,
852		       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
853		memset((pMsgDummy +
854			(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
855		       0,
856		       (LAC_LONG_WORD_IN_BYTES *
857			LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
858		memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
859				    LAC_START_OF_CACHE_MID_IN_LW),
860		       pCacheDummyMid,
861		       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_MID_IN_LW));
862		memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
863				    LAC_START_OF_CACHE_FTR_IN_LW),
864		       pCacheDummyFtr,
865		       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
866
867		SalQatMsg_ContentDescHdrWrite((icp_qat_fw_comn_req_t *)&(
868						  keyGenReq),
869					      &(contentDescInfo));
870
871		SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&keyGenReq,
872				      ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
873				      ICP_QAT_FW_LA_CMD_MGF1,
874				      cmnRequestFlags,
875				      laCmdFlags);
876
877		/*
878		 * MGF uses a flat buffer but we can use zero for source and
879		 * dest length because the firmware will use the seed length,
880		 * hash length and mask length to find source length.
881		 */
882		SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)&(keyGenReq),
883				      pCookie,
884				      LAC_SYM_KEY_QAT_PTR_TYPE,
885				      inputPhysAddr,
886				      outputPhysAddr,
887				      0,
888				      0);
889
890		/* Send to QAT */
891		status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
892					     (void *)&(keyGenReq),
893					     LAC_QAT_SYM_REQ_SZ_LW);
894	}
895	if (CPA_STATUS_SUCCESS == status) {
896		/* Update stats */
897		LAC_KEY_STAT_INC(numMgfKeyGenRequests, instanceHandle);
898	} else {
899		LAC_KEY_STAT_INC(numMgfKeyGenRequestErrors, instanceHandle);
900		/* clean up memory */
901		if (NULL != pCookie) {
902			Lac_MemPoolEntryFree(pCookie);
903		}
904	}
905	return status;
906}
907
908/**
909 * cpaCyKeyGenMgf
910 */
911CpaStatus
912cpaCyKeyGenMgf(const CpaInstanceHandle instanceHandle_in,
913	       const CpaCyGenFlatBufCbFunc pKeyGenCb,
914	       void *pCallbackTag,
915	       const CpaCyKeyGenMgfOpData *pKeyGenMgfOpData,
916	       CpaFlatBuffer *pGeneratedMaskBuffer)
917{
918	CpaInstanceHandle instanceHandle = NULL;
919
920
921	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
922		instanceHandle =
923		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
924	} else {
925		instanceHandle = instanceHandle_in;
926	}
927
928	/* If synchronous Operation */
929	if (NULL == pKeyGenCb) {
930		return LacSymKey_MgfSync(instanceHandle,
931					 pKeyGenCb,
932					 pCallbackTag,
933					 (const void *)pKeyGenMgfOpData,
934					 pGeneratedMaskBuffer,
935					 CPA_FALSE);
936	}
937	/* Asynchronous Operation */
938	return LacSymKey_MgfCommon(instanceHandle,
939				   pKeyGenCb,
940				   pCallbackTag,
941				   (const void *)pKeyGenMgfOpData,
942				   pKeyGenMgfOpData,
943				   pGeneratedMaskBuffer,
944				   CPA_CY_SYM_HASH_SHA1);
945}
946
947/**
948 * cpaCyKeyGenMgfExt
949 */
950CpaStatus
951cpaCyKeyGenMgfExt(const CpaInstanceHandle instanceHandle_in,
952		  const CpaCyGenFlatBufCbFunc pKeyGenCb,
953		  void *pCallbackTag,
954		  const CpaCyKeyGenMgfOpDataExt *pKeyGenMgfOpDataExt,
955		  CpaFlatBuffer *pGeneratedMaskBuffer)
956{
957	CpaInstanceHandle instanceHandle = NULL;
958
959
960	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
961		instanceHandle =
962		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
963	} else {
964		instanceHandle = instanceHandle_in;
965	}
966
967	/* If synchronous Operation */
968	if (NULL == pKeyGenCb) {
969		return LacSymKey_MgfSync(instanceHandle,
970					 pKeyGenCb,
971					 pCallbackTag,
972					 (const void *)pKeyGenMgfOpDataExt,
973					 pGeneratedMaskBuffer,
974					 CPA_TRUE);
975	}
976
977	/* Param check specific for Ext function, rest of parameters validated
978	 * in LacSymKey_MgfCommon
979	 */
980	LAC_CHECK_NULL_PARAM(pKeyGenMgfOpDataExt);
981	if (CPA_CY_SYM_HASH_MD5 > pKeyGenMgfOpDataExt->hashAlgorithm ||
982	    CPA_CY_SYM_HASH_SHA512 < pKeyGenMgfOpDataExt->hashAlgorithm) {
983		LAC_INVALID_PARAM_LOG("hashAlgorithm");
984		return CPA_STATUS_INVALID_PARAM;
985	}
986
987	/* Asynchronous Operation */
988	return LacSymKey_MgfCommon(instanceHandle,
989				   pKeyGenCb,
990				   pCallbackTag,
991				   (const void *)pKeyGenMgfOpDataExt,
992				   &pKeyGenMgfOpDataExt->baseOpData,
993				   pGeneratedMaskBuffer,
994				   pKeyGenMgfOpDataExt->hashAlgorithm);
995}
996
997/**
998 ******************************************************************************
999 * @ingroup LacSymKey
1000 *      Key Generation SSL & TLS response handler
1001 *
1002 * @description
1003 *      Handles Key Generation SSL & TLS response messages from the QAT.
1004 *
1005 * @param[in] lacCmdId        Command id of the original request
1006 * @param[in] pOpaqueData     Pointer to opaque data that was in request
1007 * @param[in] cmnRespFlags    LA response flags
1008 *
1009 * @return void
1010 *
1011 *****************************************************************************/
1012static void
1013LacSymKey_SslTlsHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
1014			       void *pOpaqueData,
1015			       icp_qat_fw_comn_flags cmnRespFlags)
1016{
1017	void *pSslTlsOpData = NULL;
1018	CpaCyGenFlatBufCbFunc pKeyGenSslTlsCb = NULL;
1019	lac_sym_key_cookie_t *pCookie = NULL;
1020	void *pCallbackTag = NULL;
1021	CpaFlatBuffer *pGeneratedKeyBuffer = NULL;
1022	CpaStatus status = CPA_STATUS_SUCCESS;
1023
1024	CpaBoolean respStatusOk =
1025	    (ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
1026	     ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(cmnRespFlags)) ?
1027	    CPA_TRUE :
1028	    CPA_FALSE;
1029
1030	pCookie = (lac_sym_key_cookie_t *)pOpaqueData;
1031
1032	pSslTlsOpData = pCookie->pKeyGenOpData;
1033
1034	if (CPA_TRUE == respStatusOk) {
1035		LacKey_StatsInc(lacCmdId,
1036				LAC_KEY_COMPLETED,
1037				pCookie->instanceHandle);
1038	} else {
1039		status = CPA_STATUS_FAIL;
1040		LacKey_StatsInc(lacCmdId,
1041				LAC_KEY_COMPLETED_ERRORS,
1042				pCookie->instanceHandle);
1043	}
1044
1045	pKeyGenSslTlsCb = (CpaCyGenFlatBufCbFunc)(pCookie->pKeyGenCb);
1046
1047	pCallbackTag = pCookie->pCallbackTag;
1048	pGeneratedKeyBuffer = pCookie->pKeyGenOutputData;
1049
1050	Lac_MemPoolEntryFree(pCookie);
1051
1052	(*pKeyGenSslTlsCb)(pCallbackTag,
1053			   status,
1054			   pSslTlsOpData,
1055			   pGeneratedKeyBuffer);
1056}
1057
1058/**
1059*******************************************************************************
1060* @ingroup LacSymKey
1061*      Synchronous mode of operation function wrapper for performing SSL/TLS
1062*      key gen operation
1063*
1064* @description
1065*      Synchronous mode of operation function wrapper for performing SSL/TLS
1066*      key gen operation
1067*
1068* @param[in] instanceHandle        QAT device handle.
1069* @param[in] pKeyGenCb             Pointer to callback function to be invoked
1070*                                  when the operation is complete.
1071* @param[in] pCallbackTag          Opaque User Data for this specific call.
1072* @param[in] lacCmdId              Lac command ID (identify SSL & TLS ops)
1073* @param[in] pKeyGenSslTlsOpData   Structure containing all the data needed to
1074*                                  perform the SSL/TLS key generation
1075*                                  operation.
1076* @param[in]  hashAlgorithm        Specifies the hash algorithm to use.
1077*                                  According to RFC5246, this should be
1078*                                  "SHA-256 or a stronger standard hash
1079*                                  function."
1080* @param[out] pKeyGenOutputData    pointer to where output result should be
1081*                                  written
1082*
1083* @retval CPA_STATUS_SUCCESS        Function executed successfully.
1084* @retval CPA_STATUS_FAIL           Function failed.
1085* @retval CPA_STATUS_RETRY          Function should be retried.
1086* @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in.
1087* @retval CPA_STATUS_RESOURCE       Error related to system resources.
1088*
1089*****************************************************************************/
1090static CpaStatus
1091LacSymKey_SslTlsSync(CpaInstanceHandle instanceHandle,
1092		     const CpaCyGenFlatBufCbFunc pKeyGenCb,
1093		     void *pCallbackTag,
1094		     icp_qat_fw_la_cmd_id_t lacCmdId,
1095		     void *pKeyGenSslTlsOpData,
1096		     Cpa8U hashAlgorithm,
1097		     CpaFlatBuffer *pKeyGenOutpuData)
1098{
1099	lac_sync_op_data_t *pSyncCallbackData = NULL;
1100	CpaStatus status = CPA_STATUS_SUCCESS;
1101
1102	status = LacSync_CreateSyncCookie(&pSyncCallbackData);
1103	if (CPA_STATUS_SUCCESS == status) {
1104		status = LacSymKey_KeyGenSslTls_GenCommon(instanceHandle,
1105							  pKeyGenCb,
1106							  pSyncCallbackData,
1107							  lacCmdId,
1108							  pKeyGenSslTlsOpData,
1109							  hashAlgorithm,
1110							  pKeyGenOutpuData);
1111	} else {
1112		/* Failure allocating sync cookie */
1113		LacKey_StatsInc(lacCmdId,
1114				LAC_KEY_REQUEST_ERRORS,
1115				instanceHandle);
1116		return status;
1117	}
1118
1119	if (CPA_STATUS_SUCCESS == status) {
1120		CpaStatus syncStatus = CPA_STATUS_SUCCESS;
1121
1122		syncStatus =
1123		    LacSync_WaitForCallback(pSyncCallbackData,
1124					    LAC_SYM_SYNC_CALLBACK_TIMEOUT,
1125					    &status,
1126					    NULL);
1127
1128		/* If callback doesn't come back */
1129		if (CPA_STATUS_SUCCESS != syncStatus) {
1130			LacKey_StatsInc(lacCmdId,
1131					LAC_KEY_COMPLETED_ERRORS,
1132					instanceHandle);
1133			LAC_LOG_ERROR("Callback timed out");
1134			status = syncStatus;
1135		}
1136	} else {
1137		/* As the Request was not sent the Callback will never
1138		 * be called, so need to indicate that we're finished
1139		 * with cookie so it can be destroyed.
1140		 */
1141		LacSync_SetSyncCookieComplete(pSyncCallbackData);
1142	}
1143
1144	LacSync_DestroySyncCookie(&pSyncCallbackData);
1145
1146	return status;
1147}
1148
1149static CpaStatus
1150computeHashKey(CpaFlatBuffer *secret,
1151	       CpaFlatBuffer *hash,
1152	       CpaCySymHashAlgorithm *hashAlgorithm)
1153{
1154	CpaStatus status = CPA_STATUS_SUCCESS;
1155
1156	switch (*hashAlgorithm) {
1157	case CPA_CY_SYM_HASH_MD5:
1158		status = qatUtilsHashMD5Full(secret->pData,
1159					     hash->pData,
1160					     secret->dataLenInBytes);
1161		break;
1162	case CPA_CY_SYM_HASH_SHA1:
1163		status = qatUtilsHashSHA1Full(secret->pData,
1164					      hash->pData,
1165					      secret->dataLenInBytes);
1166		break;
1167	case CPA_CY_SYM_HASH_SHA256:
1168		status = qatUtilsHashSHA256Full(secret->pData,
1169						hash->pData,
1170						secret->dataLenInBytes);
1171		break;
1172	case CPA_CY_SYM_HASH_SHA384:
1173		status = qatUtilsHashSHA384Full(secret->pData,
1174						hash->pData,
1175						secret->dataLenInBytes);
1176		break;
1177	case CPA_CY_SYM_HASH_SHA512:
1178		status = qatUtilsHashSHA512Full(secret->pData,
1179						hash->pData,
1180						secret->dataLenInBytes);
1181		break;
1182	default:
1183		status = CPA_STATUS_FAIL;
1184	}
1185	return status;
1186}
1187
1188static CpaStatus
1189LacSymKey_KeyGenSslTls_GenCommon(CpaInstanceHandle instanceHandle,
1190				 const CpaCyGenFlatBufCbFunc pKeyGenCb,
1191				 void *pCallbackTag,
1192				 icp_qat_fw_la_cmd_id_t lacCmdId,
1193				 void *pKeyGenSslTlsOpData,
1194				 Cpa8U hashAlgCipher,
1195				 CpaFlatBuffer *pKeyGenOutputData)
1196{
1197	CpaStatus status = CPA_STATUS_SUCCESS;
1198	CpaBoolean precompute = CPA_FALSE;
1199	icp_qat_fw_la_bulk_req_t keyGenReq = { { 0 } };
1200	icp_qat_la_bulk_req_hdr_t keyGenReqHdr = { { 0 } };
1201	icp_qat_fw_la_key_gen_common_t keyGenReqMid = { { 0 } };
1202	icp_qat_la_bulk_req_ftr_t keyGenReqFtr = { { { 0 } } };
1203	Cpa8U *pMsgDummy = NULL;
1204	Cpa8U *pCacheDummyHdr = NULL;
1205	Cpa8U *pCacheDummyMid = NULL;
1206	Cpa8U *pCacheDummyFtr = NULL;
1207	lac_sym_key_cookie_t *pCookie = NULL;
1208	lac_sym_cookie_t *pSymCookie = NULL;
1209	Cpa64U inputPhysAddr = 0;
1210	Cpa64U outputPhysAddr = 0;
1211/* Structure initializer is supported by C99, but it is
1212 * not supported by some former Intel compiler.
1213 */
1214	CpaCySymHashSetupData hashSetupData = { 0 };
1215	sal_qat_content_desc_info_t contentDescInfo = { 0 };
1216	Cpa32U hashBlkSizeInBytes = 0;
1217	Cpa32U tlsPrefixLen = 0;
1218
1219	CpaFlatBuffer inputSecret = { 0 };
1220	CpaFlatBuffer hashKeyOutput = { 0 };
1221	Cpa32U uSecretLen = 0;
1222	CpaCySymHashNestedModeSetupData *pNestedModeSetupData =
1223	    &(hashSetupData.nestedModeSetupData);
1224	icp_qat_fw_serv_specif_flags laCmdFlags = 0;
1225	icp_qat_fw_comn_flags cmnRequestFlags =
1226	    ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
1227					QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
1228
1229	sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
1230
1231	/* If synchronous Operation */
1232	if (NULL == pKeyGenCb) {
1233		return LacSymKey_SslTlsSync(instanceHandle,
1234					    LacSync_GenFlatBufCb,
1235					    pCallbackTag,
1236					    lacCmdId,
1237					    pKeyGenSslTlsOpData,
1238					    hashAlgCipher,
1239					    pKeyGenOutputData);
1240	}
1241	/* Allocate the cookie */
1242	pCookie = (lac_sym_key_cookie_t *)Lac_MemPoolEntryAlloc(
1243	    pService->lac_sym_cookie_pool);
1244	if (NULL == pCookie) {
1245		LAC_LOG_ERROR("Cannot get mem pool entry");
1246		status = CPA_STATUS_RESOURCE;
1247	} else if ((void *)CPA_STATUS_RETRY == pCookie) {
1248		pCookie = NULL;
1249		status = CPA_STATUS_RETRY;
1250	} else {
1251		pSymCookie = (lac_sym_cookie_t *)pCookie;
1252	}
1253
1254	if (CPA_STATUS_SUCCESS == status) {
1255		icp_qat_hw_auth_mode_t qatHashMode = 0;
1256
1257		if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
1258			qatHashMode = ICP_QAT_HW_AUTH_MODE0;
1259		} else /* TLS v1.1, v1.2, v1.3 */
1260		{
1261			qatHashMode = ICP_QAT_HW_AUTH_MODE2;
1262		}
1263
1264		pCookie->instanceHandle = pService;
1265		pCookie->pCallbackTag = pCallbackTag;
1266		pCookie->pKeyGenCb = pKeyGenCb;
1267		pCookie->pKeyGenOpData = pKeyGenSslTlsOpData;
1268		pCookie->pKeyGenOutputData = pKeyGenOutputData;
1269		hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_NESTED;
1270
1271		/* SSL3 */
1272		if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
1273			hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
1274			hashSetupData.digestResultLenInBytes =
1275			    LAC_HASH_MD5_DIGEST_SIZE;
1276			pNestedModeSetupData->outerHashAlgorithm =
1277			    CPA_CY_SYM_HASH_MD5;
1278
1279			pNestedModeSetupData->pInnerPrefixData = NULL;
1280			pNestedModeSetupData->innerPrefixLenInBytes = 0;
1281			pNestedModeSetupData->pOuterPrefixData = NULL;
1282			pNestedModeSetupData->outerPrefixLenInBytes = 0;
1283		}
1284		/* TLS v1.1 */
1285		else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == lacCmdId) {
1286			CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
1287			    (CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
1288
1289			hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
1290			hashSetupData.digestResultLenInBytes =
1291			    LAC_HASH_MD5_DIGEST_SIZE;
1292			pNestedModeSetupData->outerHashAlgorithm =
1293			    CPA_CY_SYM_HASH_MD5;
1294
1295			uSecretLen = pKeyGenTlsOpData->secret.dataLenInBytes;
1296
1297			/* We want to handle pre_master_secret > 128 bytes
1298			 * therefore we
1299			 * only verify if the current operation is Master Secret
1300			 * Derive.
1301			 * The other operations remain unchanged.
1302			 */
1303			if ((uSecretLen >
1304			     ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX) &&
1305			    (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
1306				 pKeyGenTlsOpData->tlsOp ||
1307			     CPA_CY_KEY_TLS_OP_USER_DEFINED ==
1308				 pKeyGenTlsOpData->tlsOp)) {
1309				CpaCySymHashAlgorithm hashAlgorithm =
1310				    (CpaCySymHashAlgorithm)hashAlgCipher;
1311				/* secret = [s1 | s2 ]
1312				 * s1 = outer prefix, s2 = inner prefix
1313				 * length of s1 and s2 = ceil(secret_length / 2)
1314				 * (secret length + 1)/2 will always give the
1315				 * ceil as
1316				 * division by 2
1317				 * (>>1) will give the smallest integral value
1318				 * not less than
1319				 * arg
1320				 */
1321				tlsPrefixLen =
1322				    (pKeyGenTlsOpData->secret.dataLenInBytes +
1323				     1) >>
1324				    1;
1325				inputSecret.dataLenInBytes = tlsPrefixLen;
1326				inputSecret.pData =
1327				    pKeyGenTlsOpData->secret.pData;
1328
1329				/* Since the pre_master_secret is > 128, we
1330				 * split the input
1331				 * pre_master_secret in 2 halves and compute the
1332				 * MD5 of the
1333				 * first half and the SHA1 on the second half.
1334				 */
1335				hashAlgorithm = CPA_CY_SYM_HASH_MD5;
1336
1337				/* Initialize pointer where MD5 key will go. */
1338				hashKeyOutput.pData =
1339				    &pCookie->hashKeyBuffer[0];
1340				hashKeyOutput.dataLenInBytes =
1341				    LAC_HASH_MD5_DIGEST_SIZE;
1342				computeHashKey(&inputSecret,
1343					       &hashKeyOutput,
1344					       &hashAlgorithm);
1345
1346				pNestedModeSetupData->pOuterPrefixData =
1347				    &pCookie->hashKeyBuffer[0];
1348				pNestedModeSetupData->outerPrefixLenInBytes =
1349				    LAC_HASH_MD5_DIGEST_SIZE;
1350
1351				/* Point to the second half of the
1352				 * pre_master_secret */
1353				inputSecret.pData =
1354				    pKeyGenTlsOpData->secret.pData +
1355				    (pKeyGenTlsOpData->secret.dataLenInBytes -
1356				     tlsPrefixLen);
1357
1358				/* Compute SHA1 on the second half of the
1359				 * pre_master_secret
1360				 */
1361				hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
1362				/* Initialize pointer where SHA1 key will go. */
1363				hashKeyOutput.pData =
1364				    &pCookie->hashKeyBuffer
1365					 [LAC_HASH_MD5_DIGEST_SIZE];
1366				hashKeyOutput.dataLenInBytes =
1367				    LAC_HASH_SHA1_DIGEST_SIZE;
1368				computeHashKey(&inputSecret,
1369					       &hashKeyOutput,
1370					       &hashAlgorithm);
1371
1372				pNestedModeSetupData->pInnerPrefixData =
1373				    &pCookie->hashKeyBuffer
1374					 [LAC_HASH_MD5_DIGEST_SIZE];
1375				pNestedModeSetupData->innerPrefixLenInBytes =
1376				    LAC_HASH_SHA1_DIGEST_SIZE;
1377			} else {
1378				/* secret = [s1 | s2 ]
1379				 * s1 = outer prefix, s2 = inner prefix
1380				 * length of s1 and s2 = ceil(secret_length / 2)
1381				 * (secret length + 1)/2 will always give the
1382				 * ceil as
1383				 * division by 2
1384				 * (>>1) will give the smallest integral value
1385				 * not less than
1386				 * arg
1387				 */
1388				tlsPrefixLen =
1389				    (pKeyGenTlsOpData->secret.dataLenInBytes +
1390				     1) >>
1391				    1;
1392				/* last byte of s1 will be first byte of s2 if
1393				 * Length is odd
1394				 */
1395				pNestedModeSetupData->pInnerPrefixData =
1396				    pKeyGenTlsOpData->secret.pData +
1397				    (pKeyGenTlsOpData->secret.dataLenInBytes -
1398				     tlsPrefixLen);
1399
1400				pNestedModeSetupData->pOuterPrefixData =
1401				    pKeyGenTlsOpData->secret.pData;
1402
1403				pNestedModeSetupData->innerPrefixLenInBytes =
1404				    pNestedModeSetupData
1405					->outerPrefixLenInBytes = tlsPrefixLen;
1406			}
1407		}
1408		/* TLS v1.2 */
1409		else if (ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == lacCmdId) {
1410			CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
1411			    (CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
1412			CpaCySymHashAlgorithm hashAlgorithm =
1413			    (CpaCySymHashAlgorithm)hashAlgCipher;
1414
1415			uSecretLen = pKeyGenTlsOpData->secret.dataLenInBytes;
1416
1417			hashSetupData.hashAlgorithm =
1418			    (CpaCySymHashAlgorithm)hashAlgorithm;
1419			hashSetupData.digestResultLenInBytes =
1420			    (Cpa32U)getDigestSizeFromHashAlgo(hashAlgorithm);
1421			pNestedModeSetupData->outerHashAlgorithm =
1422			    (CpaCySymHashAlgorithm)hashAlgorithm;
1423			if (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
1424				pKeyGenTlsOpData->tlsOp ||
1425			    CPA_CY_KEY_TLS_OP_USER_DEFINED ==
1426				pKeyGenTlsOpData->tlsOp) {
1427				switch (hashAlgorithm) {
1428				case CPA_CY_SYM_HASH_SM3:
1429					precompute = CPA_FALSE;
1430					break;
1431				case CPA_CY_SYM_HASH_SHA256:
1432					if (uSecretLen >
1433					    ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX) {
1434						precompute = CPA_TRUE;
1435					}
1436					break;
1437				case CPA_CY_SYM_HASH_SHA384:
1438				case CPA_CY_SYM_HASH_SHA512:
1439					if (uSecretLen >
1440					    ICP_QAT_FW_LA_TLS_SECRET_LEN_MAX) {
1441						precompute = CPA_TRUE;
1442					}
1443					break;
1444				default:
1445					break;
1446				}
1447			}
1448			if (CPA_TRUE == precompute) {
1449				/* Case when secret > algorithm block size
1450				 * RFC 4868: For SHA-256 Block size is 512 bits,
1451				 * for SHA-384
1452				 * and SHA-512 Block size is 1024 bits
1453				 * Initialize pointer
1454				 * where SHAxxx key will go.
1455				 */
1456				hashKeyOutput.pData =
1457				    &pCookie->hashKeyBuffer[0];
1458				hashKeyOutput.dataLenInBytes =
1459				    hashSetupData.digestResultLenInBytes;
1460				computeHashKey(&pKeyGenTlsOpData->secret,
1461					       &hashKeyOutput,
1462					       &hashSetupData.hashAlgorithm);
1463
1464				/* Outer prefix = secret , inner prefix = secret
1465				 * secret < 64 bytes
1466				 */
1467				pNestedModeSetupData->pInnerPrefixData =
1468				    hashKeyOutput.pData;
1469				pNestedModeSetupData->pOuterPrefixData =
1470				    hashKeyOutput.pData;
1471				pNestedModeSetupData->innerPrefixLenInBytes =
1472				    hashKeyOutput.dataLenInBytes;
1473				pNestedModeSetupData->outerPrefixLenInBytes =
1474				    hashKeyOutput.dataLenInBytes;
1475			} else {
1476				/* Outer prefix = secret , inner prefix = secret
1477				 * secret <= 64 bytes
1478				 */
1479				pNestedModeSetupData->pInnerPrefixData =
1480				    pKeyGenTlsOpData->secret.pData;
1481
1482				pNestedModeSetupData->pOuterPrefixData =
1483				    pKeyGenTlsOpData->secret.pData;
1484
1485				pNestedModeSetupData->innerPrefixLenInBytes =
1486				    pKeyGenTlsOpData->secret.dataLenInBytes;
1487				pNestedModeSetupData->outerPrefixLenInBytes =
1488				    pKeyGenTlsOpData->secret.dataLenInBytes;
1489			}
1490		}
1491		/* TLS v1.3 */
1492		else if ((ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= lacCmdId) &&
1493			 (ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL >=
1494			  lacCmdId)) {
1495			CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
1496			    (CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
1497			CpaCySymHashAlgorithm hashAlgorithm =
1498			    getHashAlgorithmFromCipherSuiteHKDF(hashAlgCipher);
1499
1500			/* Set HASH data */
1501			hashSetupData.hashAlgorithm = hashAlgorithm;
1502			/* Calculate digest length from the HASH type */
1503			hashSetupData.digestResultLenInBytes =
1504			    cipherSuiteHKDFHashSizes[hashAlgCipher]
1505						    [LAC_KEY_HKDF_DIGESTS];
1506			/* Outer Hash type is the same as inner hash type */
1507			pNestedModeSetupData->outerHashAlgorithm =
1508			    hashAlgorithm;
1509
1510			/* EXPAND (PRK):
1511			 * Outer prefix = secret, inner prefix = secret
1512			 * EXTRACT (SEED/SALT):
1513			 * Outer prefix = seed, inner prefix = seed
1514			 * Secret <= 64 Bytes
1515			 * We do not pre compute as secret can't be larger than
1516			 * 64 bytes
1517			 */
1518
1519			if ((ICP_QAT_FW_LA_CMD_HKDF_EXPAND == lacCmdId) ||
1520			    (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == lacCmdId)) {
1521				pNestedModeSetupData->pInnerPrefixData =
1522				    pKeyGenTlsOpData->secret;
1523				pNestedModeSetupData->pOuterPrefixData =
1524				    pKeyGenTlsOpData->secret;
1525				pNestedModeSetupData->innerPrefixLenInBytes =
1526				    pKeyGenTlsOpData->secretLen;
1527				pNestedModeSetupData->outerPrefixLenInBytes =
1528				    pKeyGenTlsOpData->secretLen;
1529			} else {
1530				pNestedModeSetupData->pInnerPrefixData =
1531				    pKeyGenTlsOpData->seed;
1532				pNestedModeSetupData->pOuterPrefixData =
1533				    pKeyGenTlsOpData->seed;
1534				pNestedModeSetupData->innerPrefixLenInBytes =
1535				    pKeyGenTlsOpData->seedLen;
1536				pNestedModeSetupData->outerPrefixLenInBytes =
1537				    pKeyGenTlsOpData->seedLen;
1538			}
1539		}
1540
1541		/* Set the footer Data.
1542		 * Note that following function doesn't look at inner/outer
1543		 * prefix pointers in nested digest ctx
1544		 */
1545		LacSymQat_HashContentDescInit(
1546		    &keyGenReqFtr,
1547		    instanceHandle,
1548		    &hashSetupData,
1549		    pCookie
1550			->contentDesc, /* Pointer to base of hw setup block */
1551		    LAC_SYM_KEY_NO_HASH_BLK_OFFSET_QW,
1552		    ICP_QAT_FW_SLICE_DRAM_WR,
1553		    qatHashMode,
1554		    CPA_FALSE, /* Not using sym Constants Table in Shared SRAM
1555				*/
1556		    CPA_FALSE, /* not using the optimised content Desc */
1557		    CPA_FALSE, /* Not using the stateful SHA3 Content Desc */
1558		    NULL,      /* precompute data */
1559		    &hashBlkSizeInBytes);
1560
1561		/* SSL3 */
1562		if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
1563			CpaCyKeyGenSslOpData *pKeyGenSslOpData =
1564			    (CpaCyKeyGenSslOpData *)pKeyGenSslTlsOpData;
1565			Cpa8U *pLabel = NULL;
1566			Cpa32U labelLen = 0;
1567			Cpa8U iterations = 0;
1568			Cpa64U labelPhysAddr = 0;
1569
1570			/* Iterations = ceiling of output required / output per
1571			 * iteration Ceiling of a / b = (a + (b-1)) / b
1572			 */
1573			iterations =
1574			    (pKeyGenSslOpData->generatedKeyLenInBytes +
1575			     (LAC_SYM_QAT_KEY_SSL_BYTES_PER_ITERATION - 1)) >>
1576			    LAC_SYM_QAT_KEY_SSL_ITERATIONS_SHIFT;
1577
1578			if (CPA_CY_KEY_SSL_OP_USER_DEFINED ==
1579			    pKeyGenSslOpData->sslOp) {
1580				pLabel = pKeyGenSslOpData->userLabel.pData;
1581				labelLen =
1582				    pKeyGenSslOpData->userLabel.dataLenInBytes;
1583				labelPhysAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
1584				    pService->generic_service_info, pLabel);
1585
1586				if (labelPhysAddr == 0) {
1587					LAC_LOG_ERROR(
1588					    "Unable to get the physical address of the"
1589					    " label");
1590					status = CPA_STATUS_FAIL;
1591				}
1592			} else {
1593				pLabel = pService->pSslLabel;
1594
1595				/* Calculate label length.
1596				 * eg. 3 iterations is ABBCCC so length is 6
1597				 */
1598				labelLen =
1599				    ((iterations * iterations) + iterations) >>
1600				    1;
1601				labelPhysAddr =
1602				    LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
1603			}
1604
1605			LacSymQat_KeySslRequestPopulate(
1606			    &keyGenReqHdr,
1607			    &keyGenReqMid,
1608			    pKeyGenSslOpData->generatedKeyLenInBytes,
1609			    labelLen,
1610			    pKeyGenSslOpData->secret.dataLenInBytes,
1611			    iterations);
1612
1613			LacSymQat_KeySslKeyMaterialInputPopulate(
1614			    &(pService->generic_service_info),
1615			    &(pCookie->u.sslKeyInput),
1616			    pKeyGenSslOpData->seed.pData,
1617			    labelPhysAddr,
1618			    pKeyGenSslOpData->secret.pData);
1619
1620			inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
1621			    pSymCookie->keySslKeyInputPhyAddr);
1622		}
1623		/* TLS v1.1, v1.2 */
1624		else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == lacCmdId ||
1625			 ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == lacCmdId) {
1626			CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
1627			    (CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
1628			lac_sym_qat_hash_state_buffer_info_t
1629			    hashStateBufferInfo = { 0 };
1630			CpaBoolean hashStateBuffer = CPA_FALSE;
1631			icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
1632			    (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
1633				keyGenReqFtr.cd_ctrl);
1634			icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
1635			Cpa8U *pLabel = NULL;
1636			Cpa32U labelLen = 0;
1637			Cpa64U labelPhysAddr = 0;
1638			hashStateBufferInfo.pData = pCookie->hashStateBuffer;
1639			hashStateBufferInfo.pDataPhys =
1640			    LAC_MEM_CAST_PTR_TO_UINT64(
1641				pSymCookie->keyHashStateBufferPhyAddr);
1642			hashStateBufferInfo.stateStorageSzQuadWords = 0;
1643
1644			LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
1645							     instanceHandle,
1646							     &(hashSetupData),
1647							     hashStateBuffer,
1648							     qatHashMode,
1649							     CPA_FALSE);
1650
1651			pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
1652			    keyGenReqFtr.serv_specif_rqpars);
1653
1654			hashStateBufferInfo.prefixAadSzQuadWords =
1655			    LAC_BYTES_TO_QUADWORDS(
1656				pHashReqParams->u2.inner_prefix_sz +
1657				pHashControlBlock->outer_prefix_sz);
1658
1659			/* Copy prefix data into hash state buffer */
1660			pMsgDummy = (Cpa8U *)&(keyGenReq);
1661			pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
1662			pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
1663			pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
1664			memcpy(pMsgDummy,
1665			       pCacheDummyHdr,
1666			       (LAC_LONG_WORD_IN_BYTES *
1667				LAC_SIZE_OF_CACHE_HDR_IN_LW));
1668			memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
1669					    LAC_START_OF_CACHE_MID_IN_LW),
1670			       pCacheDummyMid,
1671			       (LAC_LONG_WORD_IN_BYTES *
1672				LAC_SIZE_OF_CACHE_MID_IN_LW));
1673			memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
1674					    LAC_START_OF_CACHE_FTR_IN_LW),
1675			       pCacheDummyFtr,
1676			       (LAC_LONG_WORD_IN_BYTES *
1677				LAC_SIZE_OF_CACHE_FTR_IN_LW));
1678
1679			LacSymQat_HashStatePrefixAadBufferPopulate(
1680			    &hashStateBufferInfo,
1681			    &keyGenReqFtr,
1682			    pNestedModeSetupData->pInnerPrefixData,
1683			    pNestedModeSetupData->innerPrefixLenInBytes,
1684			    pNestedModeSetupData->pOuterPrefixData,
1685			    pNestedModeSetupData->outerPrefixLenInBytes);
1686
1687			/* Firmware only looks at hash state buffer pointer and
1688			 * the
1689			 * hash state buffer size so all other fields are set to
1690			 * 0
1691			 */
1692			LacSymQat_HashRequestParamsPopulate(
1693			    &(keyGenReq),
1694			    0, /* Auth offset */
1695			    0, /* Auth length */
1696			    &(pService->generic_service_info),
1697			    &hashStateBufferInfo, /* Hash state prefix buffer */
1698			    ICP_QAT_FW_LA_PARTIAL_NONE,
1699			    0, /* Hash result size */
1700			    CPA_FALSE,
1701			    NULL,
1702			    CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
1703			    NULL);		  /* HKDF only */
1704
1705			/* Set up the labels and their length */
1706			if (CPA_CY_KEY_TLS_OP_USER_DEFINED ==
1707			    pKeyGenTlsOpData->tlsOp) {
1708				pLabel = pKeyGenTlsOpData->userLabel.pData;
1709				labelLen =
1710				    pKeyGenTlsOpData->userLabel.dataLenInBytes;
1711				labelPhysAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
1712				    pService->generic_service_info, pLabel);
1713
1714				if (labelPhysAddr == 0) {
1715					LAC_LOG_ERROR(
1716					    "Unable to get the physical address of the"
1717					    " label");
1718					status = CPA_STATUS_FAIL;
1719				}
1720			} else if (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
1721				   pKeyGenTlsOpData->tlsOp) {
1722				pLabel = pService->pTlsLabel->masterSecret;
1723				labelLen =
1724				    sizeof(
1725					LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL) -
1726				    1;
1727				labelPhysAddr =
1728				    LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
1729			} else if (CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE ==
1730				   pKeyGenTlsOpData->tlsOp) {
1731				pLabel = pService->pTlsLabel->keyMaterial;
1732				labelLen =
1733				    sizeof(LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL) -
1734				    1;
1735				labelPhysAddr =
1736				    LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
1737			} else if (CPA_CY_KEY_TLS_OP_CLIENT_FINISHED_DERIVE ==
1738				   pKeyGenTlsOpData->tlsOp) {
1739				pLabel = pService->pTlsLabel->clientFinished;
1740				labelLen =
1741				    sizeof(LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL) -
1742				    1;
1743				labelPhysAddr =
1744				    LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
1745			} else {
1746				pLabel = pService->pTlsLabel->serverFinished;
1747				labelLen =
1748				    sizeof(LAC_SYM_KEY_TLS_SERVER_FIN_LABEL) -
1749				    1;
1750				labelPhysAddr =
1751				    LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
1752			}
1753			LacSymQat_KeyTlsRequestPopulate(
1754			    &keyGenReqMid,
1755			    pKeyGenTlsOpData->generatedKeyLenInBytes,
1756			    labelLen,
1757			    pKeyGenTlsOpData->secret.dataLenInBytes,
1758			    pKeyGenTlsOpData->seed.dataLenInBytes,
1759			    lacCmdId);
1760
1761			LacSymQat_KeyTlsKeyMaterialInputPopulate(
1762			    &(pService->generic_service_info),
1763			    &(pCookie->u.tlsKeyInput),
1764			    pKeyGenTlsOpData->seed.pData,
1765			    labelPhysAddr);
1766
1767			inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
1768			    pSymCookie->keyTlsKeyInputPhyAddr);
1769		}
1770		/* TLS v1.3 */
1771		else if (ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= lacCmdId &&
1772			 ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND >=
1773			     lacCmdId) {
1774			CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
1775			    (CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
1776			lac_sym_qat_hash_state_buffer_info_t
1777			    hashStateBufferInfo = { 0 };
1778			CpaBoolean hashStateBuffer = CPA_FALSE;
1779			icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
1780			    (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
1781				keyGenReqFtr.cd_ctrl);
1782			icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
1783			hashStateBufferInfo.pData = pCookie->hashStateBuffer;
1784			hashStateBufferInfo.pDataPhys =
1785			    LAC_MEM_CAST_PTR_TO_UINT64(
1786				pSymCookie->keyHashStateBufferPhyAddr);
1787			hashStateBufferInfo.stateStorageSzQuadWords = 0;
1788
1789			LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
1790							     instanceHandle,
1791							     &(hashSetupData),
1792							     hashStateBuffer,
1793							     qatHashMode,
1794							     CPA_FALSE);
1795
1796			pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
1797			    keyGenReqFtr.serv_specif_rqpars);
1798
1799			hashStateBufferInfo.prefixAadSzQuadWords =
1800			    LAC_BYTES_TO_QUADWORDS(
1801				pHashReqParams->u2.inner_prefix_sz +
1802				pHashControlBlock->outer_prefix_sz);
1803
1804			/* Copy prefix data into hash state buffer */
1805			pMsgDummy = (Cpa8U *)&(keyGenReq);
1806			pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
1807			pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
1808			pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
1809			memcpy(pMsgDummy,
1810			       pCacheDummyHdr,
1811			       (LAC_LONG_WORD_IN_BYTES *
1812				LAC_SIZE_OF_CACHE_HDR_IN_LW));
1813			memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
1814					    LAC_START_OF_CACHE_MID_IN_LW),
1815			       pCacheDummyMid,
1816			       (LAC_LONG_WORD_IN_BYTES *
1817				LAC_SIZE_OF_CACHE_MID_IN_LW));
1818			memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
1819					    LAC_START_OF_CACHE_FTR_IN_LW),
1820			       pCacheDummyFtr,
1821			       (LAC_LONG_WORD_IN_BYTES *
1822				LAC_SIZE_OF_CACHE_FTR_IN_LW));
1823
1824			LacSymQat_HashStatePrefixAadBufferPopulate(
1825			    &hashStateBufferInfo,
1826			    &keyGenReqFtr,
1827			    pNestedModeSetupData->pInnerPrefixData,
1828			    pNestedModeSetupData->innerPrefixLenInBytes,
1829			    pNestedModeSetupData->pOuterPrefixData,
1830			    pNestedModeSetupData->outerPrefixLenInBytes);
1831
1832			/* Firmware only looks at hash state buffer pointer and
1833			 * the
1834			 * hash state buffer size so all other fields are set to
1835			 * 0
1836			 */
1837			LacSymQat_HashRequestParamsPopulate(
1838			    &(keyGenReq),
1839			    0, /* Auth offset */
1840			    0, /* Auth length */
1841			    &(pService->generic_service_info),
1842			    &hashStateBufferInfo, /* Hash state prefix buffer */
1843			    ICP_QAT_FW_LA_PARTIAL_NONE,
1844			    0, /* Hash result size */
1845			    CPA_FALSE,
1846			    NULL,
1847			    CPA_CY_SYM_HASH_NONE,      /* Hash algorithm */
1848			    pKeyGenTlsOpData->secret); /* IKM or PRK */
1849
1850			LacSymQat_KeyTlsRequestPopulate(
1851			    &keyGenReqMid,
1852			    cipherSuiteHKDFHashSizes[hashAlgCipher]
1853						    [LAC_KEY_HKDF_DIGESTS],
1854			    /* For EXTRACT, EXPAND, FW expects info to be passed
1855			       as label */
1856			    pKeyGenTlsOpData->infoLen,
1857			    pKeyGenTlsOpData->secretLen,
1858			    pKeyGenTlsOpData->seedLen,
1859			    lacCmdId);
1860
1861			LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
1862			    &(pService->generic_service_info),
1863			    &(pCookie->u.tlsHKDFKeyInput),
1864			    pKeyGenTlsOpData,
1865			    0,	 /* No subLabels used */
1866			    lacCmdId); /* Pass op being performed */
1867
1868			inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
1869			    pSymCookie->keyTlsKeyInputPhyAddr);
1870		}
1871		/* TLS v1.3 LABEL */
1872		else if (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == lacCmdId ||
1873			 ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL ==
1874			     lacCmdId) {
1875			CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
1876			    (CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
1877			Cpa64U subLabelsPhysAddr = 0;
1878			lac_sym_qat_hash_state_buffer_info_t
1879			    hashStateBufferInfo = { 0 };
1880			CpaBoolean hashStateBuffer = CPA_FALSE;
1881			icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
1882			    (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
1883				keyGenReqFtr.cd_ctrl);
1884			icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
1885			hashStateBufferInfo.pData = pCookie->hashStateBuffer;
1886			hashStateBufferInfo.pDataPhys =
1887			    LAC_MEM_CAST_PTR_TO_UINT64(
1888				pSymCookie->keyHashStateBufferPhyAddr);
1889			hashStateBufferInfo.stateStorageSzQuadWords = 0;
1890
1891			LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
1892							     instanceHandle,
1893							     &(hashSetupData),
1894							     hashStateBuffer,
1895							     qatHashMode,
1896							     CPA_FALSE);
1897
1898			pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
1899			    keyGenReqFtr.serv_specif_rqpars);
1900
1901			hashStateBufferInfo.prefixAadSzQuadWords =
1902			    LAC_BYTES_TO_QUADWORDS(
1903				pHashReqParams->u2.inner_prefix_sz +
1904				pHashControlBlock->outer_prefix_sz);
1905
1906			/* Copy prefix data into hash state buffer */
1907			pMsgDummy = (Cpa8U *)&(keyGenReq);
1908			pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
1909			pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
1910			pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
1911			memcpy(pMsgDummy,
1912			       pCacheDummyHdr,
1913			       (LAC_LONG_WORD_IN_BYTES *
1914				LAC_SIZE_OF_CACHE_HDR_IN_LW));
1915			memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
1916					    LAC_START_OF_CACHE_MID_IN_LW),
1917			       pCacheDummyMid,
1918			       (LAC_LONG_WORD_IN_BYTES *
1919				LAC_SIZE_OF_CACHE_MID_IN_LW));
1920			memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
1921					    LAC_START_OF_CACHE_FTR_IN_LW),
1922			       pCacheDummyFtr,
1923			       (LAC_LONG_WORD_IN_BYTES *
1924				LAC_SIZE_OF_CACHE_FTR_IN_LW));
1925
1926			LacSymQat_HashStatePrefixAadBufferPopulate(
1927			    &hashStateBufferInfo,
1928			    &keyGenReqFtr,
1929			    pNestedModeSetupData->pInnerPrefixData,
1930			    pNestedModeSetupData->innerPrefixLenInBytes,
1931			    pNestedModeSetupData->pOuterPrefixData,
1932			    pNestedModeSetupData->outerPrefixLenInBytes);
1933
1934			/* Firmware only looks at hash state buffer pointer and
1935			 * the
1936			 * hash state buffer size so all other fields are set to
1937			 * 0
1938			 */
1939			LacSymQat_HashRequestParamsPopulate(
1940			    &(keyGenReq),
1941			    0, /* Auth offset */
1942			    0, /* Auth length */
1943			    &(pService->generic_service_info),
1944			    &hashStateBufferInfo, /* Hash state prefix buffer */
1945			    ICP_QAT_FW_LA_PARTIAL_NONE,
1946			    0, /* Hash result size */
1947			    CPA_FALSE,
1948			    NULL,
1949			    CPA_CY_SYM_HASH_NONE,      /* Hash algorithm */
1950			    pKeyGenTlsOpData->secret); /* IKM or PRK */
1951
1952			LacSymQat_KeyTlsRequestPopulate(
1953			    &keyGenReqMid,
1954			    cipherSuiteHKDFHashSizes[hashAlgCipher]
1955						    [LAC_KEY_HKDF_DIGESTS],
1956			    pKeyGenTlsOpData->numLabels, /* Number of Labels */
1957			    pKeyGenTlsOpData->secretLen,
1958			    pKeyGenTlsOpData->seedLen,
1959			    lacCmdId);
1960
1961			/* Get physical address of subLabels */
1962			switch (hashAlgCipher) {
1963			case CPA_CY_HKDF_TLS_AES_128_GCM_SHA256: /* Fall Through
1964								    */
1965			case CPA_CY_HKDF_TLS_AES_128_CCM_SHA256:
1966			case CPA_CY_HKDF_TLS_AES_128_CCM_8_SHA256:
1967				subLabelsPhysAddr = pService->pTlsHKDFSubLabel
1968							->sublabelPhysAddr256;
1969				break;
1970			case CPA_CY_HKDF_TLS_CHACHA20_POLY1305_SHA256:
1971				subLabelsPhysAddr =
1972				    pService->pTlsHKDFSubLabel
1973					->sublabelPhysAddrChaChaPoly;
1974				break;
1975			case CPA_CY_HKDF_TLS_AES_256_GCM_SHA384:
1976				subLabelsPhysAddr = pService->pTlsHKDFSubLabel
1977							->sublabelPhysAddr384;
1978				break;
1979			default:
1980				break;
1981			}
1982
1983			LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
1984			    &(pService->generic_service_info),
1985			    &(pCookie->u.tlsHKDFKeyInput),
1986			    pKeyGenTlsOpData,
1987			    subLabelsPhysAddr,
1988			    lacCmdId); /* Pass op being performed */
1989
1990			inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
1991			    pSymCookie->keyTlsKeyInputPhyAddr);
1992		}
1993
1994		outputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
1995		    LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
1996						 pKeyGenOutputData->pData));
1997
1998		if (outputPhysAddr == 0) {
1999			LAC_LOG_ERROR(
2000			    "Unable to get the physical address of the"
2001			    " output buffer");
2002			status = CPA_STATUS_FAIL;
2003		}
2004	}
2005	if (CPA_STATUS_SUCCESS == status) {
2006		Cpa8U lw26[4];
2007		char *tmp = NULL;
2008		unsigned char a;
2009		int n = 0;
2010		/* Make up the full keyGenReq struct from its constituents
2011		 * before calling the SalQatMsg functions below.
2012		 * Note: The full cache struct has been reduced to a
2013		 * header, mid and footer for memory size reduction
2014		 */
2015		pMsgDummy = (Cpa8U *)&(keyGenReq);
2016		pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
2017		pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
2018		pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
2019
2020		memcpy(pMsgDummy,
2021		       pCacheDummyHdr,
2022		       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
2023		memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
2024				    LAC_START_OF_CACHE_MID_IN_LW),
2025		       pCacheDummyMid,
2026		       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_MID_IN_LW));
2027		memcpy(&lw26,
2028		       pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
2029				    LAC_START_OF_CACHE_FTR_IN_LW),
2030		       LAC_LONG_WORD_IN_BYTES);
2031		memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
2032				    LAC_START_OF_CACHE_FTR_IN_LW),
2033		       pCacheDummyFtr,
2034		       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
2035		tmp = (char *)(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
2036					    LAC_START_OF_CACHE_FTR_IN_LW));
2037
2038		/* Copy LW26, or'd with what's already there, into the Msg, for
2039		 * TLS */
2040		for (n = 0; n < LAC_LONG_WORD_IN_BYTES; n++) {
2041			a = (unsigned char)*(tmp + n);
2042			lw26[n] = lw26[n] | a;
2043		}
2044		memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
2045				    LAC_START_OF_CACHE_FTR_IN_LW),
2046		       &lw26,
2047		       LAC_LONG_WORD_IN_BYTES);
2048
2049		contentDescInfo.pData = pCookie->contentDesc;
2050		contentDescInfo.hardwareSetupBlockPhys =
2051		    LAC_MEM_CAST_PTR_TO_UINT64(
2052			pSymCookie->keyContentDescPhyAddr);
2053		contentDescInfo.hwBlkSzQuadWords =
2054		    LAC_BYTES_TO_QUADWORDS(hashBlkSizeInBytes);
2055
2056		/* Populate common request fields */
2057		SalQatMsg_ContentDescHdrWrite((icp_qat_fw_comn_req_t *)&(
2058						  keyGenReq),
2059					      &(contentDescInfo));
2060
2061		SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&keyGenReq,
2062				      ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
2063				      lacCmdId,
2064				      cmnRequestFlags,
2065				      laCmdFlags);
2066
2067		SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)&(keyGenReq),
2068				      pCookie,
2069				      LAC_SYM_KEY_QAT_PTR_TYPE,
2070				      inputPhysAddr,
2071				      outputPhysAddr,
2072				      0,
2073				      0);
2074
2075		/* Send to QAT */
2076		status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
2077					     (void *)&(keyGenReq),
2078					     LAC_QAT_SYM_REQ_SZ_LW);
2079	}
2080	if (CPA_STATUS_SUCCESS == status) {
2081		/* Update stats */
2082		LacKey_StatsInc(lacCmdId,
2083				LAC_KEY_REQUESTS,
2084				pCookie->instanceHandle);
2085	} else {
2086		/* Clean up cookie memory */
2087		if (NULL != pCookie) {
2088			LacKey_StatsInc(lacCmdId,
2089					LAC_KEY_REQUEST_ERRORS,
2090					pCookie->instanceHandle);
2091			Lac_MemPoolEntryFree(pCookie);
2092		}
2093	}
2094	return status;
2095}
2096
2097/**
2098 * @ingroup LacSymKey
2099 *      Parameters check for TLS v1.0/1.1, v1.2, v1.3 and SSL3
2100 * @description
2101 *      Check user parameters against the firmware/spec requirements.
2102 *
2103 * @param[in] pKeyGenOpData              Pointer to a structure containing all
2104 *                                       the data needed to perform the key
2105 *                                       generation operation.
2106 * @param[in]  hashAlgCipher             Specifies the hash algorithm,
2107 *                                       or cipher we are using.
2108 *                                       According to RFC5246, this should be
2109 *                                       "SHA-256 or a stronger standard hash
2110 *                                       function."
2111 * @param[in] pGeneratedKeyBuffer        User output buffers.
2112 * @param[in] cmdId                      Keygen operation to perform.
2113 */
2114static CpaStatus
2115LacSymKey_CheckParamSslTls(const void *pKeyGenOpData,
2116			   Cpa8U hashAlgCipher,
2117			   const CpaFlatBuffer *pGeneratedKeyBuffer,
2118			   icp_qat_fw_la_cmd_id_t cmdId)
2119{
2120	/* Api max value */
2121	Cpa32U maxSecretLen = 0;
2122	Cpa32U maxSeedLen = 0;
2123	Cpa32U maxOutputLen = 0;
2124	Cpa32U maxInfoLen = 0;
2125	Cpa32U maxLabelLen = 0;
2126
2127	/* User info */
2128	Cpa32U uSecretLen = 0;
2129	Cpa32U uSeedLen = 0;
2130	Cpa32U uOutputLen = 0;
2131
2132	LAC_CHECK_NULL_PARAM(pKeyGenOpData);
2133	LAC_CHECK_NULL_PARAM(pGeneratedKeyBuffer);
2134	LAC_CHECK_NULL_PARAM(pGeneratedKeyBuffer->pData);
2135
2136	if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == cmdId) {
2137		CpaCyKeyGenSslOpData *opData =
2138		    (CpaCyKeyGenSslOpData *)pKeyGenOpData;
2139
2140		/* User info */
2141		uSecretLen = opData->secret.dataLenInBytes;
2142		uSeedLen = opData->seed.dataLenInBytes;
2143		uOutputLen = opData->generatedKeyLenInBytes;
2144
2145		/* Api max value */
2146		maxSecretLen = ICP_QAT_FW_LA_SSL_SECRET_LEN_MAX;
2147		maxSeedLen = ICP_QAT_FW_LA_SSL_SEED_LEN_MAX;
2148		maxOutputLen = ICP_QAT_FW_LA_SSL_OUTPUT_LEN_MAX;
2149
2150		/* Check user buffers */
2151		LAC_CHECK_NULL_PARAM(opData->secret.pData);
2152		LAC_CHECK_NULL_PARAM(opData->seed.pData);
2153
2154		/* Check operation */
2155		if ((Cpa32U)opData->sslOp > CPA_CY_KEY_SSL_OP_USER_DEFINED) {
2156			LAC_INVALID_PARAM_LOG("opData->sslOp");
2157			return CPA_STATUS_INVALID_PARAM;
2158		}
2159		if ((Cpa32U)opData->sslOp == CPA_CY_KEY_SSL_OP_USER_DEFINED) {
2160			LAC_CHECK_NULL_PARAM(opData->userLabel.pData);
2161			/* Maximum label length for SSL Key Gen request */
2162			if (opData->userLabel.dataLenInBytes >
2163			    ICP_QAT_FW_LA_SSL_LABEL_LEN_MAX) {
2164				LAC_INVALID_PARAM_LOG(
2165				    "userLabel.dataLenInBytes");
2166				return CPA_STATUS_INVALID_PARAM;
2167			}
2168		}
2169
2170		/* Only seed length for SSL3 Key Gen request */
2171		if (maxSeedLen != uSeedLen) {
2172			LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
2173			return CPA_STATUS_INVALID_PARAM;
2174		}
2175
2176		/* Maximum output length for SSL3 Key Gen request */
2177		if (uOutputLen > maxOutputLen) {
2178			LAC_INVALID_PARAM_LOG("generatedKeyLenInBytes");
2179			return CPA_STATUS_INVALID_PARAM;
2180		}
2181	}
2182	/* TLS v1.1 or TLS v.12 */
2183	else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == cmdId ||
2184		 ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == cmdId) {
2185		CpaCyKeyGenTlsOpData *opData =
2186		    (CpaCyKeyGenTlsOpData *)pKeyGenOpData;
2187
2188		/* User info */
2189		uSecretLen = opData->secret.dataLenInBytes;
2190		uSeedLen = opData->seed.dataLenInBytes;
2191		uOutputLen = opData->generatedKeyLenInBytes;
2192
2193		if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == cmdId) {
2194			/* Api max value */
2195			/* ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX needs to be
2196			 * multiplied
2197			 * by 4 in order to verifiy the 512 conditions. We did
2198			 * not change
2199			 * ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX as it
2200			 * represents
2201			 * the max value tha firmware can handle.
2202			 */
2203			maxSecretLen =
2204			    ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX * 4;
2205		} else {
2206			/* Api max value */
2207			/* ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX needs to be
2208			 * multiplied
2209			 * by 8 in order to verifiy the 512 conditions. We did
2210			 * not change
2211			 * ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX as it
2212			 * represents
2213			 * the max value tha firmware can handle.
2214			 */
2215			maxSecretLen =
2216			    ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX * 8;
2217
2218			/* Check Hash algorithm */
2219			if (0 == getDigestSizeFromHashAlgo(hashAlgCipher)) {
2220				LAC_INVALID_PARAM_LOG("hashAlgorithm");
2221				return CPA_STATUS_INVALID_PARAM;
2222			}
2223		}
2224		maxSeedLen = ICP_QAT_FW_LA_TLS_SEED_LEN_MAX;
2225		maxOutputLen = ICP_QAT_FW_LA_TLS_OUTPUT_LEN_MAX;
2226		/* Check user buffers */
2227		LAC_CHECK_NULL_PARAM(opData->secret.pData);
2228		LAC_CHECK_NULL_PARAM(opData->seed.pData);
2229
2230		/* Check operation */
2231		if ((Cpa32U)opData->tlsOp > CPA_CY_KEY_TLS_OP_USER_DEFINED) {
2232			LAC_INVALID_PARAM_LOG("opData->tlsOp");
2233			return CPA_STATUS_INVALID_PARAM;
2234		} else if ((Cpa32U)opData->tlsOp ==
2235			   CPA_CY_KEY_TLS_OP_USER_DEFINED) {
2236			LAC_CHECK_NULL_PARAM(opData->userLabel.pData);
2237			/* Maximum label length for TLS Key Gen request */
2238			if (opData->userLabel.dataLenInBytes >
2239			    ICP_QAT_FW_LA_TLS_LABEL_LEN_MAX) {
2240				LAC_INVALID_PARAM_LOG(
2241				    "userLabel.dataLenInBytes");
2242				return CPA_STATUS_INVALID_PARAM;
2243			}
2244		}
2245
2246		/* Maximum/only seed length for TLS Key Gen request */
2247		if (((Cpa32U)opData->tlsOp !=
2248		     CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE) &&
2249		    ((Cpa32U)opData->tlsOp !=
2250		     CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE)) {
2251			if (uSeedLen > maxSeedLen) {
2252				LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
2253				return CPA_STATUS_INVALID_PARAM;
2254			}
2255		} else {
2256			if (maxSeedLen != uSeedLen) {
2257				LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
2258				return CPA_STATUS_INVALID_PARAM;
2259			}
2260		}
2261
2262		/* Maximum output length for TLS Key Gen request */
2263		if (uOutputLen > maxOutputLen) {
2264			LAC_INVALID_PARAM_LOG("generatedKeyLenInBytes");
2265			return CPA_STATUS_INVALID_PARAM;
2266		}
2267	}
2268	/* TLS v1.3 */
2269	else if (cmdId >= ICP_QAT_FW_LA_CMD_HKDF_EXTRACT &&
2270		 cmdId <= ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL) {
2271		CpaCyKeyGenHKDFOpData *HKDF_Data =
2272		    (CpaCyKeyGenHKDFOpData *)pKeyGenOpData;
2273		CpaCyKeyHKDFCipherSuite cipherSuite = hashAlgCipher;
2274		CpaCySymHashAlgorithm hashAlgorithm =
2275		    getHashAlgorithmFromCipherSuiteHKDF(cipherSuite);
2276		maxSeedLen =
2277		    cipherSuiteHKDFHashSizes[cipherSuite][LAC_KEY_HKDF_DIGESTS];
2278		maxSecretLen = CPA_CY_HKDF_KEY_MAX_SECRET_SZ;
2279		maxInfoLen = CPA_CY_HKDF_KEY_MAX_INFO_SZ;
2280		maxLabelLen = CPA_CY_HKDF_KEY_MAX_LABEL_SZ;
2281
2282		uSecretLen = HKDF_Data->secretLen;
2283
2284		/* Check using supported hash function */
2285		if (0 ==
2286		    (uOutputLen = getDigestSizeFromHashAlgo(hashAlgorithm))) {
2287			LAC_INVALID_PARAM_LOG("Hash function not supported");
2288			return CPA_STATUS_INVALID_PARAM;
2289		}
2290
2291		/* Number of labels does not exceed the MAX */
2292		if (HKDF_Data->numLabels > CPA_CY_HKDF_KEY_MAX_LABEL_COUNT) {
2293			LAC_INVALID_PARAM_LOG(
2294			    "CpaCyKeyGenHKDFOpData.numLabels");
2295			return CPA_STATUS_INVALID_PARAM;
2296		}
2297
2298		switch (cmdId) {
2299		case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT:
2300			if (maxSeedLen < HKDF_Data->seedLen) {
2301				LAC_INVALID_PARAM_LOG(
2302				    "CpaCyKeyGenHKDFOpData.seedLen");
2303				return CPA_STATUS_INVALID_PARAM;
2304			}
2305			break;
2306		case ICP_QAT_FW_LA_CMD_HKDF_EXPAND:
2307			maxSecretLen =
2308			    cipherSuiteHKDFHashSizes[cipherSuite]
2309						    [LAC_KEY_HKDF_DIGESTS];
2310
2311			if (maxInfoLen < HKDF_Data->infoLen) {
2312				LAC_INVALID_PARAM_LOG(
2313				    "CpaCyKeyGenHKDFOpData.infoLen");
2314				return CPA_STATUS_INVALID_PARAM;
2315			}
2316			break;
2317		case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND:
2318			uOutputLen *= 2;
2319			if (maxSeedLen < HKDF_Data->seedLen) {
2320				LAC_INVALID_PARAM_LOG(
2321				    "CpaCyKeyGenHKDFOpData.seedLen");
2322				return CPA_STATUS_INVALID_PARAM;
2323			}
2324			if (maxInfoLen < HKDF_Data->infoLen) {
2325				LAC_INVALID_PARAM_LOG(
2326				    "CpaCyKeyGenHKDFOpData.infoLen");
2327				return CPA_STATUS_INVALID_PARAM;
2328			}
2329			break;
2330		case ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL: /* Fall through */
2331		case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL: {
2332			Cpa8U subl_mask = 0, subl_number = 1;
2333			Cpa8U i = 0;
2334
2335			if (maxSeedLen < HKDF_Data->seedLen) {
2336				LAC_INVALID_PARAM_LOG(
2337				    "CpaCyKeyGenHKDFOpData.seedLen");
2338				return CPA_STATUS_INVALID_PARAM;
2339			}
2340
2341			/* If EXPAND set uOutputLen to zero */
2342			if (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == cmdId) {
2343				uOutputLen = 0;
2344				maxSecretLen = cipherSuiteHKDFHashSizes
2345				    [cipherSuite][LAC_KEY_HKDF_DIGESTS];
2346			}
2347
2348			for (i = 0; i < HKDF_Data->numLabels; i++) {
2349				/* Check that the labelLen does not overflow */
2350				if (maxLabelLen <
2351				    HKDF_Data->label[i].labelLen) {
2352					LAC_INVALID_PARAM_LOG1(
2353					    "CpaCyKeyGenHKDFOpData.label[%d].labelLen",
2354					    i);
2355					return CPA_STATUS_INVALID_PARAM;
2356				}
2357
2358				if (HKDF_Data->label[i].sublabelFlag &
2359				    ~HKDF_SUB_LABELS_ALL) {
2360					LAC_INVALID_PARAM_LOG1(
2361					    "CpaCyKeyGenHKDFOpData.label[%d]."
2362					    "subLabelFlag",
2363					    i);
2364					return CPA_STATUS_INVALID_PARAM;
2365				}
2366
2367				/* Calculate the appended subLabel output
2368				 * lengths and
2369				 * check that the output buffer that the user
2370				 * has
2371				 * supplied is the correct length.
2372				 */
2373				uOutputLen += cipherSuiteHKDFHashSizes
2374				    [cipherSuite][LAC_KEY_HKDF_DIGESTS];
2375				/* Get mask of subLabel */
2376				subl_mask = HKDF_Data->label[i].sublabelFlag;
2377
2378				for (subl_number = 1;
2379				     subl_number <= LAC_KEY_HKDF_SUBLABELS_NUM;
2380				     subl_number++) {
2381					/* Add the used subLabel key lengths */
2382					if (subl_mask & 1) {
2383						uOutputLen +=
2384						    cipherSuiteHKDFHashSizes
2385							[cipherSuite]
2386							[subl_number];
2387					}
2388					subl_mask >>= 1;
2389				}
2390			}
2391		} break;
2392		default:
2393			break;
2394		}
2395	} else {
2396		LAC_INVALID_PARAM_LOG("TLS/SSL operation");
2397		return CPA_STATUS_INVALID_PARAM;
2398	}
2399
2400	/* Maximum secret length for TLS/SSL Key Gen request */
2401	if (uSecretLen > maxSecretLen) {
2402		LAC_INVALID_PARAM_LOG("HKFD.secretLen/secret.dataLenInBytes");
2403		return CPA_STATUS_INVALID_PARAM;
2404	}
2405
2406	/* Check for enough space in the flat buffer */
2407	if (uOutputLen > pGeneratedKeyBuffer->dataLenInBytes) {
2408		LAC_INVALID_PARAM_LOG("pGeneratedKeyBuffer->dataLenInBytes");
2409		return CPA_STATUS_INVALID_PARAM;
2410	}
2411	return CPA_STATUS_SUCCESS;
2412}
2413
2414/**
2415 *
2416 */
2417/**
2418 * @ingroup LacSymKey
2419 *      Common Keygen Code for TLS v1.0/1.1, v1.2 and SSL3.
2420 * @description
2421 *      Check user parameters and perform the required operation.
2422 *
2423 * @param[in] instanceHandle_in          Instance handle.
2424 * @param[in] pKeyGenCb                  Pointer to callback function to be
2425 *                                       invoked when the operation is complete.
2426 *                                       If this is set to a NULL value the
2427 *                                       function will operate synchronously.
2428 * @param[in] pCallbackTag               Opaque User Data for this specific
2429 *                                       call. Will be returned unchanged in the
2430 *                                       callback.
2431 * @param[in] pKeyGenOpData              Pointer to a structure containing all
2432 *                                       the data needed to perform the key
2433 *                                       generation operation.
2434 * @param[in]  hashAlgorithm             Specifies the hash algorithm to use.
2435 *                                       According to RFC5246, this should be
2436 *                                       "SHA-256 or a stronger standard hash
2437 *                                       function."
2438 * @param[out] pGeneratedKeyBuffer       User output buffer.
2439 * @param[in] cmdId                      Keygen operation to perform.
2440 */
2441static CpaStatus
2442LacSymKey_KeyGenSslTls(const CpaInstanceHandle instanceHandle_in,
2443		       const CpaCyGenFlatBufCbFunc pKeyGenCb,
2444		       void *pCallbackTag,
2445		       const void *pKeyGenOpData,
2446		       Cpa8U hashAlgorithm,
2447		       CpaFlatBuffer *pGeneratedKeyBuffer,
2448		       icp_qat_fw_la_cmd_id_t cmdId)
2449{
2450	CpaStatus status = CPA_STATUS_FAIL;
2451	CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
2452
2453	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
2454	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
2455				(SAL_SERVICE_TYPE_CRYPTO |
2456				 SAL_SERVICE_TYPE_CRYPTO_SYM));
2457	SAL_RUNNING_CHECK(instanceHandle);
2458
2459	status = LacSymKey_CheckParamSslTls(pKeyGenOpData,
2460					    hashAlgorithm,
2461					    pGeneratedKeyBuffer,
2462					    cmdId);
2463	if (CPA_STATUS_SUCCESS != status)
2464		return status;
2465	return LacSymKey_KeyGenSslTls_GenCommon(instanceHandle,
2466						pKeyGenCb,
2467						pCallbackTag,
2468						cmdId,
2469						LAC_CONST_PTR_CAST(
2470						    pKeyGenOpData),
2471						hashAlgorithm,
2472						pGeneratedKeyBuffer);
2473}
2474
2475/**
2476 * @ingroup LacSymKey
2477 *      SSL Key Generation Function.
2478 * @description
2479 *      This function is used for SSL key generation.  It implements the key
2480 *      generation function defined in section 6.2.2 of the SSL 3.0
2481 *      specification as described in
2482 *      http://www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt.
2483 *
2484 *      The input seed is taken as a flat buffer and the generated key is
2485 *      returned to caller in a flat destination data buffer.
2486 *
2487 * @param[in] instanceHandle_in          Instance handle.
2488 * @param[in] pKeyGenCb                  Pointer to callback function to be
2489 *                                       invoked when the operation is complete.
2490 *                                       If this is set to a NULL value the
2491 *                                       function will operate synchronously.
2492 * @param[in] pCallbackTag               Opaque User Data for this specific
2493 *                                       call. Will be returned unchanged in the
2494 *                                       callback.
2495 * @param[in] pKeyGenSslOpData           Pointer to a structure containing all
2496 *                                       the data needed to perform the SSL key
2497 *                                       generation operation. The client code
2498 *                                       allocates the memory for this
2499 *                                       structure. This component takes
2500 *                                       ownership of the memory until it is
2501 *                                       returned in the callback.
2502 * @param[out] pGeneratedKeyBuffer       Caller MUST allocate a sufficient
2503 *                                       buffer to hold the key generation
2504 *                                       output. The data pointer SHOULD be
2505 *                                       aligned on an 8-byte boundary. The
2506 *                                       length field passed in represents the
2507 *                                       size of the buffer in bytes. The value
2508 *                                       that is returned is the size of the
2509 *                                       result key in bytes.
2510 *                                       On invocation the callback function
2511 *                                       will contain this parameter in the
2512 *                                       pOut parameter.
2513 *
2514 * @retval CPA_STATUS_SUCCESS            Function executed successfully.
2515 * @retval CPA_STATUS_FAIL               Function failed.
2516 * @retval CPA_STATUS_RETRY              Resubmit the request.
2517 * @retval CPA_STATUS_INVALID_PARAM      Invalid parameter passed in.
2518 * @retval CPA_STATUS_RESOURCE           Error related to system resources.
2519 */
2520CpaStatus
2521cpaCyKeyGenSsl(const CpaInstanceHandle instanceHandle_in,
2522	       const CpaCyGenFlatBufCbFunc pKeyGenCb,
2523	       void *pCallbackTag,
2524	       const CpaCyKeyGenSslOpData *pKeyGenSslOpData,
2525	       CpaFlatBuffer *pGeneratedKeyBuffer)
2526{
2527	CpaInstanceHandle instanceHandle = NULL;
2528
2529	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
2530		instanceHandle =
2531		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
2532	} else {
2533		instanceHandle = instanceHandle_in;
2534	}
2535
2536	return LacSymKey_KeyGenSslTls(instanceHandle,
2537				      pKeyGenCb,
2538				      pCallbackTag,
2539				      LAC_CONST_PTR_CAST(pKeyGenSslOpData),
2540				      CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
2541				      pGeneratedKeyBuffer,
2542				      ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE);
2543}
2544
2545/**
2546 * @ingroup LacSymKey
2547 *      TLS Key Generation Function.
2548 * @description
2549 *      This function is used for TLS key generation.  It implements the
2550 *      TLS PRF (Pseudo Random Function) as defined by RFC2246 (TLS v1.0)
2551 *      and RFC4346 (TLS v1.1).
2552 *
2553 *      The input seed is taken as a flat buffer and the generated key is
2554 *      returned to caller in a flat destination data buffer.
2555 *
2556 * @param[in]  instanceHandle_in         Instance handle.
2557 * @param[in]  pKeyGenCb                 Pointer to callback function to be
2558 *                                       invoked when the operation is complete.
2559 *                                       If this is set to a NULL value the
2560 *                                       function will operate synchronously.
2561 * @param[in]  pCallbackTag              Opaque User Data for this specific
2562 *                                       call. Will be returned unchanged in the
2563 *                                       callback.
2564 * @param[in]  pKeyGenTlsOpData          Pointer to a structure containing all
2565 *                                       the data needed to perform the TLS key
2566 *                                       generation operation. The client code
2567 *                                       allocates the memory for this
2568 *                                       structure. This component takes
2569 *                                       ownership of the memory until it is
2570 *                                       returned in the callback.
2571 * @param[out] pGeneratedKeyBuffer       Caller MUST allocate a sufficient
2572 *                                       buffer to hold the key generation
2573 *                                       output. The data pointer SHOULD be
2574 *                                       aligned on an 8-byte boundary. The
2575 *                                       length field passed in represents the
2576 *                                       size of the buffer in bytes. The value
2577 *                                       that is returned is the size of the
2578 *                                       result key in bytes.
2579 *                                       On invocation the callback function
2580 *                                       will contain this parameter in the
2581 *                                       pOut parameter.
2582 *
2583 * @retval CPA_STATUS_SUCCESS            Function executed successfully.
2584 * @retval CPA_STATUS_FAIL               Function failed.
2585 * @retval CPA_STATUS_RETRY              Resubmit the request.
2586 * @retval CPA_STATUS_INVALID_PARAM      Invalid parameter passed in.
2587 * @retval CPA_STATUS_RESOURCE           Error related to system resources.
2588 *
2589 */
2590CpaStatus
2591cpaCyKeyGenTls(const CpaInstanceHandle instanceHandle_in,
2592	       const CpaCyGenFlatBufCbFunc pKeyGenCb,
2593	       void *pCallbackTag,
2594	       const CpaCyKeyGenTlsOpData *pKeyGenTlsOpData,
2595	       CpaFlatBuffer *pGeneratedKeyBuffer)
2596{
2597	CpaInstanceHandle instanceHandle = NULL;
2598
2599
2600	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
2601		instanceHandle =
2602		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
2603	} else {
2604		instanceHandle = instanceHandle_in;
2605	}
2606
2607	return LacSymKey_KeyGenSslTls(instanceHandle,
2608				      pKeyGenCb,
2609				      pCallbackTag,
2610				      LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
2611				      CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
2612				      pGeneratedKeyBuffer,
2613				      ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE);
2614}
2615
2616/**
2617 * @ingroup LacSymKey
2618 * @description
2619 *      This function is used for TLS key generation.  It implements the
2620 *      TLS PRF (Pseudo Random Function) as defined by RFC5246 (TLS v1.2).
2621 *
2622 *      The input seed is taken as a flat buffer and the generated key is
2623 *      returned to caller in a flat destination data buffer.
2624 *
2625 * @param[in]  instanceHandle_in         Instance handle.
2626 * @param[in]  pKeyGenCb                 Pointer to callback function to be
2627 *                                       invoked when the operation is complete.
2628 *                                       If this is set to a NULL value the
2629 *                                       function will operate synchronously.
2630 * @param[in]  pCallbackTag              Opaque User Data for this specific
2631 *                                       call. Will be returned unchanged in the
2632 *                                       callback.
2633 * @param[in]  pKeyGenTlsOpData          Pointer to a structure containing all
2634 *                                       the data needed to perform the TLS key
2635 *                                       generation operation. The client code
2636 *                                       allocates the memory for this
2637 *                                       structure. This component takes
2638 *                                       ownership of the memory until it is
2639 *                                       returned in the callback.
2640 * @param[in]  hashAlgorithm             Specifies the hash algorithm to use.
2641 *                                       According to RFC5246, this should be
2642 *                                       "SHA-256 or a stronger standard hash
2643 *                                       function."
2644 * @param[out] pGeneratedKeyBuffer       Caller MUST allocate a sufficient
2645 *                                       buffer to hold the key generation
2646 *                                       output. The data pointer SHOULD be
2647 *                                       aligned on an 8-byte boundary. The
2648 *                                       length field passed in represents the
2649 *                                       size of the buffer in bytes. The value
2650 *                                       that is returned is the size of the
2651 *                                       result key in bytes.
2652 *                                       On invocation the callback function
2653 *                                       will contain this parameter in the
2654 *                                       pOut parameter.
2655 *
2656 * @retval CPA_STATUS_SUCCESS            Function executed successfully.
2657 * @retval CPA_STATUS_FAIL               Function failed.
2658 * @retval CPA_STATUS_RETRY              Resubmit the request.
2659 * @retval CPA_STATUS_INVALID_PARAM      Invalid parameter passed in.
2660 * @retval CPA_STATUS_RESOURCE           Error related to system resources.
2661 */
2662CpaStatus
2663cpaCyKeyGenTls2(const CpaInstanceHandle instanceHandle_in,
2664		const CpaCyGenFlatBufCbFunc pKeyGenCb,
2665		void *pCallbackTag,
2666		const CpaCyKeyGenTlsOpData *pKeyGenTlsOpData,
2667		CpaCySymHashAlgorithm hashAlgorithm,
2668		CpaFlatBuffer *pGeneratedKeyBuffer)
2669{
2670	CpaInstanceHandle instanceHandle = NULL;
2671
2672
2673	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
2674		instanceHandle =
2675		    Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
2676	} else {
2677		instanceHandle = instanceHandle_in;
2678	}
2679
2680	return LacSymKey_KeyGenSslTls(instanceHandle,
2681				      pKeyGenCb,
2682				      pCallbackTag,
2683				      LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
2684				      hashAlgorithm,
2685				      pGeneratedKeyBuffer,
2686				      ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE);
2687}
2688
2689/**
2690 * @ingroup LacSymKey
2691 * @description
2692 *      This function is used for TLS1.3  HKDF key generation.  It implements
2693 *      the "extract-then-expand" paradigm as defined by RFC 5869.
2694 *
2695 *      The input seed/secret/info is taken as a flat buffer and the generated
2696 *      key(s)/labels are returned to caller in a flat data buffer.
2697 *
2698 * @param[in]  instanceHandle_in         Instance handle.
2699 * @param[in]  pKeyGenCb                 Pointer to callback function to be
2700 *                                       invoked when the operation is complete.
2701 *                                       If this is set to a NULL value the
2702 *                                       function will operate synchronously.
2703 * @param[in]  pCallbackTag              Opaque User Data for this specific
2704 *                                       call. Will be returned unchanged in the
2705 *                                       callback.
2706 * @param[in]  pKeyGenTlsOpData          Pointer to a structure containing
2707 *                                       the data needed to perform the HKDF key
2708 *                                       generation operation.
2709 *                                       The client code allocates the memory
2710 *                                       for this structure as contiguous
2711 *                                       pinned memory.
2712 *                                       This component takes ownership of the
2713 *                                       memory until it is returned in the
2714 *                                       callback.
2715 * @param[in]  hashAlgorithm             Specifies the hash algorithm to use.
2716 *                                       According to RFC5246, this should be
2717 *                                       "SHA-256 or a stronger standard hash
2718 *                                       function."
2719 * @param[out] pGeneratedKeyBuffer       Caller MUST allocate a sufficient
2720 *                                       buffer to hold the key generation
2721 *                                       output. The data pointer SHOULD be
2722 *                                       aligned on an 8-byte boundary. The
2723 *                                       length field passed in represents the
2724 *                                       size of the buffer in bytes. The value
2725 *                                       that is returned is the size of the
2726 *                                       result key in bytes.
2727 *                                       On invocation the callback function
2728 *                                       will contain this parameter in the
2729 *                                       pOut parameter.
2730 *
2731 * @retval CPA_STATUS_SUCCESS            Function executed successfully.
2732 * @retval CPA_STATUS_FAIL               Function failed.
2733 * @retval CPA_STATUS_RETRY              Resubmit the request.
2734 * @retval CPA_STATUS_INVALID_PARAM      Invalid parameter passed in.
2735 * @retval CPA_STATUS_RESOURCE           Error related to system resources.
2736 */
2737CpaStatus
2738cpaCyKeyGenTls3(const CpaInstanceHandle instanceHandle_in,
2739		const CpaCyGenFlatBufCbFunc pKeyGenCb,
2740		void *pCallbackTag,
2741		const CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData,
2742		CpaCyKeyHKDFCipherSuite cipherSuite,
2743		CpaFlatBuffer *pGeneratedKeyBuffer)
2744{
2745
2746	LAC_CHECK_NULL_PARAM(pKeyGenTlsOpData);
2747	switch (pKeyGenTlsOpData->hkdfKeyOp) {
2748	case CPA_CY_HKDF_KEY_EXTRACT: /* Fall through */
2749	case CPA_CY_HKDF_KEY_EXPAND:
2750	case CPA_CY_HKDF_KEY_EXTRACT_EXPAND:
2751	case CPA_CY_HKDF_KEY_EXPAND_LABEL:
2752	case CPA_CY_HKDF_KEY_EXTRACT_EXPAND_LABEL:
2753		break;
2754	default:
2755		LAC_INVALID_PARAM_LOG("HKDF operation not supported");
2756		return CPA_STATUS_INVALID_PARAM;
2757	}
2758
2759
2760	return LacSymKey_KeyGenSslTls(instanceHandle_in,
2761				      pKeyGenCb,
2762				      pCallbackTag,
2763				      LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
2764				      cipherSuite,
2765				      pGeneratedKeyBuffer,
2766				      (icp_qat_fw_la_cmd_id_t)
2767					  pKeyGenTlsOpData->hkdfKeyOp);
2768}
2769
2770/*
2771 * LacSymKey_Init
2772 */
2773CpaStatus
2774LacSymKey_Init(CpaInstanceHandle instanceHandle_in)
2775{
2776	CpaStatus status = CPA_STATUS_SUCCESS;
2777	CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
2778	sal_crypto_service_t *pService = NULL;
2779
2780	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
2781
2782	pService = (sal_crypto_service_t *)instanceHandle;
2783
2784	pService->pLacKeyStats =
2785	    LAC_OS_MALLOC(LAC_KEY_NUM_STATS * sizeof(QatUtilsAtomic));
2786
2787	if (NULL != pService->pLacKeyStats) {
2788		LAC_OS_BZERO((void *)pService->pLacKeyStats,
2789			     LAC_KEY_NUM_STATS * sizeof(QatUtilsAtomic));
2790
2791		status = LAC_OS_CAMALLOC(&pService->pSslLabel,
2792					 ICP_QAT_FW_LA_SSL_LABEL_LEN_MAX,
2793					 LAC_8BYTE_ALIGNMENT,
2794					 pService->nodeAffinity);
2795	} else {
2796		status = CPA_STATUS_RESOURCE;
2797	}
2798
2799	if (CPA_STATUS_SUCCESS == status) {
2800		Cpa32U i = 0;
2801		Cpa32U offset = 0;
2802
2803		/* Initialise SSL label ABBCCC..... */
2804		for (i = 0; i < ICP_QAT_FW_LA_SSL_ITERATES_LEN_MAX; i++) {
2805			memset(pService->pSslLabel + offset, 'A' + i, i + 1);
2806			offset += (i + 1);
2807		}
2808
2809		/* Allocate memory for TLS labels */
2810		status = LAC_OS_CAMALLOC(&pService->pTlsLabel,
2811					 sizeof(lac_sym_key_tls_labels_t),
2812					 LAC_8BYTE_ALIGNMENT,
2813					 pService->nodeAffinity);
2814	}
2815
2816	if (CPA_STATUS_SUCCESS == status) {
2817		/* Allocate memory for HKDF sub_labels */
2818		status =
2819		    LAC_OS_CAMALLOC(&pService->pTlsHKDFSubLabel,
2820				    sizeof(lac_sym_key_tls_hkdf_sub_labels_t),
2821				    LAC_8BYTE_ALIGNMENT,
2822				    pService->nodeAffinity);
2823	}
2824
2825	if (CPA_STATUS_SUCCESS == status) {
2826		LAC_OS_BZERO(pService->pTlsLabel,
2827			     sizeof(lac_sym_key_tls_labels_t));
2828
2829		/* Copy the TLS v1.2 labels into the dynamically allocated
2830		 * structure */
2831		memcpy(pService->pTlsLabel->masterSecret,
2832		       LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL,
2833		       sizeof(LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL) - 1);
2834
2835		memcpy(pService->pTlsLabel->keyMaterial,
2836		       LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL,
2837		       sizeof(LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL) - 1);
2838
2839		memcpy(pService->pTlsLabel->clientFinished,
2840		       LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL,
2841		       sizeof(LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL) - 1);
2842
2843		memcpy(pService->pTlsLabel->serverFinished,
2844		       LAC_SYM_KEY_TLS_SERVER_FIN_LABEL,
2845		       sizeof(LAC_SYM_KEY_TLS_SERVER_FIN_LABEL) - 1);
2846
2847		LAC_OS_BZERO(pService->pTlsHKDFSubLabel,
2848			     sizeof(lac_sym_key_tls_hkdf_sub_labels_t));
2849
2850		/* Copy the TLS v1.3 subLabels into the dynamically allocated
2851		 * struct */
2852		/* KEY SHA-256 */
2853		memcpy(&pService->pTlsHKDFSubLabel->keySublabel256,
2854		       &key256,
2855		       HKDF_SUB_LABEL_KEY_LENGTH);
2856		pService->pTlsHKDFSubLabel->keySublabel256.labelLen =
2857		    HKDF_SUB_LABEL_KEY_LENGTH;
2858		pService->pTlsHKDFSubLabel->keySublabel256.sublabelFlag = 1
2859		    << QAT_FW_HKDF_INNER_SUBLABEL_16_BYTE_OKM_BITPOS;
2860		/* KEY SHA-384 */
2861		memcpy(&pService->pTlsHKDFSubLabel->keySublabel384,
2862		       &key384,
2863		       HKDF_SUB_LABEL_KEY_LENGTH);
2864		pService->pTlsHKDFSubLabel->keySublabel384.labelLen =
2865		    HKDF_SUB_LABEL_KEY_LENGTH;
2866		pService->pTlsHKDFSubLabel->keySublabel384.sublabelFlag = 1
2867		    << QAT_FW_HKDF_INNER_SUBLABEL_32_BYTE_OKM_BITPOS;
2868		/* KEY CHACHAPOLY */
2869		memcpy(&pService->pTlsHKDFSubLabel->keySublabelChaChaPoly,
2870		       &keyChaChaPoly,
2871		       HKDF_SUB_LABEL_KEY_LENGTH);
2872		pService->pTlsHKDFSubLabel->keySublabelChaChaPoly.labelLen =
2873		    HKDF_SUB_LABEL_KEY_LENGTH;
2874		pService->pTlsHKDFSubLabel->keySublabelChaChaPoly.sublabelFlag =
2875		    1 << QAT_FW_HKDF_INNER_SUBLABEL_32_BYTE_OKM_BITPOS;
2876		/* IV SHA-256 */
2877		memcpy(&pService->pTlsHKDFSubLabel->ivSublabel256,
2878		       &iv256,
2879		       HKDF_SUB_LABEL_IV_LENGTH);
2880		pService->pTlsHKDFSubLabel->ivSublabel256.labelLen =
2881		    HKDF_SUB_LABEL_IV_LENGTH;
2882		pService->pTlsHKDFSubLabel->ivSublabel256.sublabelFlag = 1
2883		    << QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
2884		/* IV SHA-384 */
2885		memcpy(&pService->pTlsHKDFSubLabel->ivSublabel384,
2886		       &iv384,
2887		       HKDF_SUB_LABEL_IV_LENGTH);
2888		pService->pTlsHKDFSubLabel->ivSublabel384.labelLen =
2889		    HKDF_SUB_LABEL_IV_LENGTH;
2890		pService->pTlsHKDFSubLabel->ivSublabel384.sublabelFlag = 1
2891		    << QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
2892		/* IV CHACHAPOLY */
2893		memcpy(&pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly,
2894		       &iv256,
2895		       HKDF_SUB_LABEL_IV_LENGTH);
2896		pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly.labelLen =
2897		    HKDF_SUB_LABEL_IV_LENGTH;
2898		pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly.sublabelFlag =
2899		    1 << QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
2900		/* RESUMPTION SHA-256 */
2901		memcpy(&pService->pTlsHKDFSubLabel->resumptionSublabel256,
2902		       &resumption256,
2903		       HKDF_SUB_LABEL_RESUMPTION_LENGTH);
2904		pService->pTlsHKDFSubLabel->resumptionSublabel256.labelLen =
2905		    HKDF_SUB_LABEL_RESUMPTION_LENGTH;
2906		/* RESUMPTION SHA-384 */
2907		memcpy(&pService->pTlsHKDFSubLabel->resumptionSublabel384,
2908		       &resumption384,
2909		       HKDF_SUB_LABEL_RESUMPTION_LENGTH);
2910		pService->pTlsHKDFSubLabel->resumptionSublabel384.labelLen =
2911		    HKDF_SUB_LABEL_RESUMPTION_LENGTH;
2912		/* RESUMPTION CHACHAPOLY */
2913		memcpy(
2914		    &pService->pTlsHKDFSubLabel->resumptionSublabelChaChaPoly,
2915		    &resumption256,
2916		    HKDF_SUB_LABEL_RESUMPTION_LENGTH);
2917		pService->pTlsHKDFSubLabel->resumptionSublabelChaChaPoly
2918		    .labelLen = HKDF_SUB_LABEL_RESUMPTION_LENGTH;
2919		/* FINISHED SHA-256 */
2920		memcpy(&pService->pTlsHKDFSubLabel->finishedSublabel256,
2921		       &finished256,
2922		       HKDF_SUB_LABEL_FINISHED_LENGTH);
2923		pService->pTlsHKDFSubLabel->finishedSublabel256.labelLen =
2924		    HKDF_SUB_LABEL_FINISHED_LENGTH;
2925		/* FINISHED SHA-384 */
2926		memcpy(&pService->pTlsHKDFSubLabel->finishedSublabel384,
2927		       &finished384,
2928		       HKDF_SUB_LABEL_FINISHED_LENGTH);
2929		pService->pTlsHKDFSubLabel->finishedSublabel384.labelLen =
2930		    HKDF_SUB_LABEL_FINISHED_LENGTH;
2931		/* FINISHED CHACHAPOLY */
2932		memcpy(&pService->pTlsHKDFSubLabel->finishedSublabelChaChaPoly,
2933		       &finished256,
2934		       HKDF_SUB_LABEL_FINISHED_LENGTH);
2935		pService->pTlsHKDFSubLabel->finishedSublabelChaChaPoly
2936		    .labelLen = HKDF_SUB_LABEL_FINISHED_LENGTH;
2937
2938		/* Set physical address of sublabels */
2939		pService->pTlsHKDFSubLabel->sublabelPhysAddr256 =
2940		    LAC_OS_VIRT_TO_PHYS_INTERNAL(
2941			&pService->pTlsHKDFSubLabel->keySublabel256);
2942		pService->pTlsHKDFSubLabel->sublabelPhysAddr384 =
2943		    LAC_OS_VIRT_TO_PHYS_INTERNAL(
2944			&pService->pTlsHKDFSubLabel->keySublabel384);
2945		pService->pTlsHKDFSubLabel->sublabelPhysAddrChaChaPoly =
2946		    LAC_OS_VIRT_TO_PHYS_INTERNAL(
2947			&pService->pTlsHKDFSubLabel->keySublabelChaChaPoly);
2948
2949		/* Register request handlers */
2950		LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE,
2951					      LacSymKey_SslTlsHandleResponse);
2952
2953		LacSymQat_RespHandlerRegister(
2954		    ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE,
2955		    LacSymKey_SslTlsHandleResponse);
2956
2957		LacSymQat_RespHandlerRegister(
2958		    ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE,
2959		    LacSymKey_SslTlsHandleResponse);
2960
2961		LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_HKDF_EXTRACT,
2962					      LacSymKey_SslTlsHandleResponse);
2963
2964		LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_HKDF_EXPAND,
2965					      LacSymKey_SslTlsHandleResponse);
2966
2967		LacSymQat_RespHandlerRegister(
2968		    ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND,
2969		    LacSymKey_SslTlsHandleResponse);
2970
2971		LacSymQat_RespHandlerRegister(
2972		    ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL,
2973		    LacSymKey_SslTlsHandleResponse);
2974
2975		LacSymQat_RespHandlerRegister(
2976		    ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL,
2977		    LacSymKey_SslTlsHandleResponse);
2978
2979		LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_MGF1,
2980					      LacSymKey_MgfHandleResponse);
2981	}
2982
2983	if (CPA_STATUS_SUCCESS != status) {
2984		LAC_OS_FREE(pService->pLacKeyStats);
2985		LAC_OS_CAFREE(pService->pSslLabel);
2986		LAC_OS_CAFREE(pService->pTlsLabel);
2987		LAC_OS_CAFREE(pService->pTlsHKDFSubLabel);
2988	}
2989
2990	return status;
2991}
2992
2993/*
2994 * LacSymKey_Shutdown
2995 */
2996CpaStatus
2997LacSymKey_Shutdown(CpaInstanceHandle instanceHandle_in)
2998{
2999	CpaStatus status = CPA_STATUS_SUCCESS;
3000	CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
3001	sal_crypto_service_t *pService = NULL;
3002
3003	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
3004
3005	pService = (sal_crypto_service_t *)instanceHandle;
3006
3007	if (NULL != pService->pLacKeyStats) {
3008		LAC_OS_FREE(pService->pLacKeyStats);
3009	}
3010
3011	LAC_OS_CAFREE(pService->pSslLabel);
3012	LAC_OS_CAFREE(pService->pTlsLabel);
3013	LAC_OS_CAFREE(pService->pTlsHKDFSubLabel);
3014
3015	return status;
3016}
3017