1/* SPDX-License-Identifier: BSD-3-Clause */
2/* Copyright(c) 2007-2022 Intel Corporation */
3/* System headers */
4#include <sys/param.h>
5#include <sys/systm.h>
6#include <sys/bus.h>
7#include <sys/kernel.h>
8#include <sys/mutex.h>
9#include <sys/timespec.h>
10
11/* QAT specific headers */
12#include "qat_ocf_utils.h"
13#include "cpa.h"
14#include "lac_common.h"
15#include "lac_log.h"
16#include "lac_mem.h"
17#include "lac_mem_pools.h"
18#include "lac_list.h"
19#include "lac_sym.h"
20#include "lac_sym_qat.h"
21#include "lac_sal.h"
22#include "lac_sal_ctrl.h"
23#include "lac_session.h"
24#include "lac_sym_cipher.h"
25#include "lac_sym_hash.h"
26#include "lac_sym_alg_chain.h"
27#include "lac_sym_stats.h"
28#include "lac_sym_partial.h"
29#include "lac_sym_qat_hash_defs_lookup.h"
30
31#define QAT_OCF_AAD_NOCHANGE (-1)
32
33CpaStatus
34qat_ocf_wait_for_session(CpaCySymSessionCtx sessionCtx, Cpa32U timeoutMS)
35{
36	CpaBoolean sessionInUse = CPA_TRUE;
37	CpaStatus status;
38	struct timespec start_ts;
39	struct timespec current_ts;
40	struct timespec delta;
41	u64 delta_ms;
42
43	nanotime(&start_ts);
44	for (;;) {
45		status = cpaCySymSessionInUse(sessionCtx, &sessionInUse);
46		if (CPA_STATUS_SUCCESS != status)
47			return CPA_STATUS_FAIL;
48		if (CPA_FALSE == sessionInUse)
49			break;
50		nanotime(&current_ts);
51		delta = timespec_sub(current_ts, start_ts);
52		delta_ms = (delta.tv_sec * 1000) +
53			   (delta.tv_nsec / NSEC_PER_MSEC);
54		if (delta_ms > (timeoutMS))
55			return CPA_STATUS_RESOURCE;
56		qatUtilsYield();
57	}
58
59	return CPA_STATUS_SUCCESS;
60}
61
62static CpaStatus
63qat_ocf_session_update(struct qat_ocf_session *ocf_session,
64		       Cpa8U *newCipher,
65		       Cpa8U *newAuth,
66		       Cpa32U newAADLength)
67{
68	lac_session_desc_t *pSessionDesc = NULL;
69	CpaStatus status = CPA_STATUS_SUCCESS;
70	CpaBoolean sessionInUse = CPA_TRUE;
71
72	if (!ocf_session->sessionCtx)
73		return CPA_STATUS_SUCCESS;
74
75	status = cpaCySymSessionInUse(ocf_session->sessionCtx, &sessionInUse);
76	if (CPA_TRUE == sessionInUse)
77		return CPA_STATUS_RESOURCE;
78
79	pSessionDesc =
80	    LAC_SYM_SESSION_DESC_FROM_CTX_GET(ocf_session->sessionCtx);
81
82	if (newAADLength != QAT_OCF_AAD_NOCHANGE) {
83		ocf_session->aadLen = newAADLength;
84		status =
85		    LacAlgChain_SessionAADUpdate(pSessionDesc, newAADLength);
86		if (CPA_STATUS_SUCCESS != status)
87			return status;
88	}
89
90	if (newCipher) {
91		status =
92		    LacAlgChain_SessionCipherKeyUpdate(pSessionDesc, newCipher);
93		if (CPA_STATUS_SUCCESS != status)
94			return status;
95	}
96
97	if (newAuth) {
98		status =
99		    LacAlgChain_SessionAuthKeyUpdate(pSessionDesc, newAuth);
100		if (CPA_STATUS_SUCCESS != status)
101			return status;
102	}
103
104	return status;
105}
106
107CpaStatus
108qat_ocf_handle_session_update(struct qat_ocf_dsession *ocf_dsession,
109			      struct cryptop *crp)
110{
111	Cpa32U newAADLength = QAT_OCF_AAD_NOCHANGE;
112	Cpa8U *cipherKey;
113	Cpa8U *authKey;
114	crypto_session_t cses;
115	const struct crypto_session_params *csp;
116	CpaStatus status = CPA_STATUS_SUCCESS;
117
118	if (!ocf_dsession)
119		return CPA_STATUS_FAIL;
120
121	cses = crp->crp_session;
122	if (!cses)
123		return CPA_STATUS_FAIL;
124	csp = crypto_get_params(cses);
125	if (!csp)
126		return CPA_STATUS_FAIL;
127
128	cipherKey = crp->crp_cipher_key;
129	authKey = crp->crp_auth_key;
130
131	if (is_sep_aad_supported(csp)) {
132		/* Determine if AAD has change */
133		if ((ocf_dsession->encSession.sessionCtx &&
134		     ocf_dsession->encSession.aadLen != crp->crp_aad_length) ||
135		    (ocf_dsession->decSession.sessionCtx &&
136		     ocf_dsession->decSession.aadLen != crp->crp_aad_length)) {
137			newAADLength = crp->crp_aad_length;
138
139			/* Get auth and cipher keys from session if not present
140			 * in the request. Update keys is required to update
141			 * AAD.
142			 */
143			if (!authKey)
144				authKey = csp->csp_auth_key;
145			if (!cipherKey)
146				cipherKey = csp->csp_cipher_key;
147		}
148		if (!authKey)
149			authKey = cipherKey;
150	}
151
152	if (crp->crp_cipher_key || crp->crp_auth_key ||
153	    newAADLength != QAT_OCF_AAD_NOCHANGE) {
154		/* Update encryption session */
155		status = qat_ocf_session_update(&ocf_dsession->encSession,
156						cipherKey,
157						authKey,
158						newAADLength);
159		if (CPA_STATUS_SUCCESS != status)
160			return status;
161		/* Update decryption session */
162		status = qat_ocf_session_update(&ocf_dsession->decSession,
163						cipherKey,
164						authKey,
165						newAADLength);
166		if (CPA_STATUS_SUCCESS != status)
167			return status;
168	}
169
170	return status;
171}
172