1 /***************************************************************************
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
8 * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22 * The full GNU General Public License is included in this distribution
23 * in the file called LICENSE.GPL.
25 * Contact Information:
30 * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
31 * All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
37 * * Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * * Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in
41 * the documentation and/or other materials provided with the
43 * * Neither the name of Intel Corporation nor the names of its
44 * contributors may be used to endorse or promote products derived
45 * from this software without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
50 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
51 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
54 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
55 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
57 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 * version: Security.L.1.0.2-229
62 ***************************************************************************/
64 * An OCF module that uses the API for IntelĀ® QuickAssist Technology to do the
67 * This driver requires the ICP Access Library that is available from Intel in
73 /*This is the call back function for all symmetric cryptographic processes.
74 Its main functionality is to free driver crypto operation structure and to
77 icp_ocfDrvSymCallBack(void *callbackTag
,
79 const CpaCySymOp operationType
,
81 CpaBufferList
* pDstBuffer
, CpaBoolean verifyResult
);
83 /*This function is used to extract crypto processing information from the OCF
84 inputs, so as that it may be passed onto LAC*/
86 icp_ocfDrvProcessDataSetup(struct icp_drvOpData
*drvOpData
,
87 struct cryptodesc
*crp_desc
);
89 /*This function checks whether the crp_desc argument pertains to a digest or a
91 static int icp_ocfDrvAlgCheck(struct cryptodesc
*crp_desc
);
93 /*This function copies all the passed in session context information and stores
94 it in a LAC context structure*/
96 icp_ocfDrvAlgorithmSetup(struct cryptoini
*cri
,
97 CpaCySymSessionSetupData
* lacSessCtx
);
99 /*This function is used to free an OCF->OCF_DRV session object*/
100 static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData
*sessionData
);
102 /*max IOV buffs supported in a UIO structure*/
103 #define NUM_IOV_SUPPORTED (1)
105 /* Name : icp_ocfDrvSymCallBack
107 * Description : When this function returns it signifies that the LAC
108 * component has completed the relevant symmetric operation.
110 * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
111 * object was passed to LAC for the cryptographic processing and contains all
112 * the relevant information for cleaning up buffer handles etc. so that the
113 * OCF EP80579 Driver portion of this crypto operation can be fully completed.
116 icp_ocfDrvSymCallBack(void *callbackTag
,
118 const CpaCySymOp operationType
,
120 CpaBufferList
* pDstBuffer
, CpaBoolean verifyResult
)
122 struct cryptop
*crp
= NULL
;
123 struct icp_drvOpData
*temp_drvOpData
=
124 (struct icp_drvOpData
*)callbackTag
;
125 uint64_t *tempBasePtr
= NULL
;
126 uint32_t tempLen
= 0;
128 if (NULL
== temp_drvOpData
) {
129 DPRINTK("%s(): The callback from the LAC component"
130 " has failed due to Null userOpaque data"
131 "(status == %d).\n", __FUNCTION__
, status
);
132 DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__
);
136 crp
= temp_drvOpData
->crp
;
137 crp
->crp_etype
= ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR
;
139 if (NULL
== pOpData
) {
140 DPRINTK("%s(): The callback from the LAC component"
141 " has failed due to Null Symmetric Op data"
142 "(status == %d).\n", __FUNCTION__
, status
);
143 crp
->crp_etype
= ECANCELED
;
148 if (NULL
== pDstBuffer
) {
149 DPRINTK("%s(): The callback from the LAC component"
150 " has failed due to Null Dst Bufferlist data"
151 "(status == %d).\n", __FUNCTION__
, status
);
152 crp
->crp_etype
= ECANCELED
;
157 if (CPA_STATUS_SUCCESS
== status
) {
159 if (temp_drvOpData
->bufferType
== ICP_CRYPTO_F_PACKET_BUF
) {
160 if (ICP_OCF_DRV_STATUS_SUCCESS
!=
161 icp_ocfDrvBufferListToPacketBuff(pDstBuffer
,
165 EPRINTK("%s(): BufferList to SkBuff "
166 "conversion error.\n", __FUNCTION__
);
167 crp
->crp_etype
= EPERM
;
170 icp_ocfDrvBufferListToPtrAndLen(pDstBuffer
,
171 (void **)&tempBasePtr
,
173 crp
->crp_olen
= (int)tempLen
;
177 DPRINTK("%s(): The callback from the LAC component has failed"
178 "(status == %d).\n", __FUNCTION__
, status
);
180 crp
->crp_etype
= ECANCELED
;
183 if (temp_drvOpData
->numBufferListArray
>
184 ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS
) {
185 icp_kfree(pDstBuffer
->pBuffers
);
187 icp_ocfDrvFreeMetaData(pDstBuffer
);
188 ICP_CACHE_FREE(drvOpData_zone
, temp_drvOpData
);
190 /* Invoke the OCF callback function */
196 /* Name : icp_ocfDrvNewSession
198 * Description : This function will create a new Driver<->OCF session
200 * Notes : LAC session registration happens during the first perform call.
201 * That is the first time we know all information about a given session.
203 int icp_ocfDrvNewSession(icp_device_t dev
, uint32_t * sid
,
204 struct cryptoini
*cri
)
206 struct icp_drvSessionData
*sessionData
= NULL
;
207 uint32_t delete_session
= 0;
209 /* The SID passed in should be our driver ID. We can return the */
210 /* local ID (LID) which is a unique identifier which we can use */
211 /* to differentiate between the encrypt/decrypt LAC session handles */
213 EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
219 EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
224 if (icp_ocfDrvDriverId
!= *sid
) {
225 EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
227 EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid
, cri
);
231 sessionData
= icp_kmem_cache_zalloc(drvSessionData_zone
, ICP_M_NOWAIT
);
232 if (NULL
== sessionData
) {
233 DPRINTK("%s():No memory for Session Data\n", __FUNCTION__
);
237 /*ENTER CRITICAL SECTION */
238 icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock
);
239 /*put this check in the spinlock so no new sessions can be added to the
240 linked list when we are exiting */
241 if (CPA_TRUE
== icp_atomic_read(&icp_ocfDrvIsExiting
)) {
244 } else if (NO_OCF_TO_DRV_MAX_SESSIONS
!= max_sessions
) {
245 if (icp_atomic_read(&num_ocf_to_drv_registered_sessions
) >=
247 icp_atomic_read(&lac_session_failed_dereg_count
))) {
250 icp_atomic_inc(&num_ocf_to_drv_registered_sessions
);
251 /* Add to session data linked list */
252 ICP_LIST_ADD(sessionData
, &icp_ocfDrvGlobalSymListHead
,
256 } else if (NO_OCF_TO_DRV_MAX_SESSIONS
== max_sessions
) {
257 ICP_LIST_ADD(sessionData
, &icp_ocfDrvGlobalSymListHead
,
261 sessionData
->inUse
= ICP_SESSION_INITIALISED
;
263 /*EXIT CRITICAL SECTION */
264 icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock
);
266 if (delete_session
) {
267 DPRINTK("%s():No Session handles available\n", __FUNCTION__
);
268 ICP_CACHE_FREE(drvSessionData_zone
, sessionData
);
272 if (ICP_OCF_DRV_STATUS_SUCCESS
!=
273 icp_ocfDrvAlgorithmSetup(cri
, &(sessionData
->lacSessCtx
))) {
274 DPRINTK("%s():algorithm not supported\n", __FUNCTION__
);
275 icp_ocfDrvFreeOCFSession(sessionData
);
280 if (cri
->cri_next
->cri_next
!= NULL
) {
281 DPRINTK("%s():only two chained algorithms supported\n",
283 icp_ocfDrvFreeOCFSession(sessionData
);
287 if (ICP_OCF_DRV_STATUS_SUCCESS
!=
288 icp_ocfDrvAlgorithmSetup(cri
->cri_next
,
289 &(sessionData
->lacSessCtx
))) {
290 DPRINTK("%s():second algorithm not supported\n",
292 icp_ocfDrvFreeOCFSession(sessionData
);
296 sessionData
->lacSessCtx
.symOperation
=
297 CPA_CY_SYM_OP_ALGORITHM_CHAINING
;
300 *sid
= (uint32_t) sessionData
;
302 return ICP_OCF_DRV_STATUS_SUCCESS
;
305 /* Name : icp_ocfDrvAlgorithmSetup
307 * Description : This function builds the session context data from the
308 * information supplied through OCF. Algorithm chain order and whether the
309 * session is Encrypt/Decrypt can only be found out at perform time however, so
310 * the session is registered with LAC at that time.
313 icp_ocfDrvAlgorithmSetup(struct cryptoini
*cri
,
314 CpaCySymSessionSetupData
* lacSessCtx
)
317 lacSessCtx
->sessionPriority
= CPA_CY_PRIORITY_NORMAL
;
319 switch (cri
->cri_alg
) {
321 case CRYPTO_NULL_CBC
:
322 DPRINTK("%s(): NULL CBC\n", __FUNCTION__
);
323 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_CIPHER
;
324 lacSessCtx
->cipherSetupData
.cipherAlgorithm
=
325 CPA_CY_SYM_CIPHER_NULL
;
326 lacSessCtx
->cipherSetupData
.cipherKeyLenInBytes
=
327 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
328 lacSessCtx
->cipherSetupData
.pCipherKey
= cri
->cri_key
;
332 DPRINTK("%s(): DES CBC\n", __FUNCTION__
);
333 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_CIPHER
;
334 lacSessCtx
->cipherSetupData
.cipherAlgorithm
=
335 CPA_CY_SYM_CIPHER_DES_CBC
;
336 lacSessCtx
->cipherSetupData
.cipherKeyLenInBytes
=
337 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
338 lacSessCtx
->cipherSetupData
.pCipherKey
= cri
->cri_key
;
341 case CRYPTO_3DES_CBC
:
342 DPRINTK("%s(): 3DES CBC\n", __FUNCTION__
);
343 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_CIPHER
;
344 lacSessCtx
->cipherSetupData
.cipherAlgorithm
=
345 CPA_CY_SYM_CIPHER_3DES_CBC
;
346 lacSessCtx
->cipherSetupData
.cipherKeyLenInBytes
=
347 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
348 lacSessCtx
->cipherSetupData
.pCipherKey
= cri
->cri_key
;
352 DPRINTK("%s(): AES CBC\n", __FUNCTION__
);
353 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_CIPHER
;
354 lacSessCtx
->cipherSetupData
.cipherAlgorithm
=
355 CPA_CY_SYM_CIPHER_AES_CBC
;
356 lacSessCtx
->cipherSetupData
.cipherKeyLenInBytes
=
357 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
358 lacSessCtx
->cipherSetupData
.pCipherKey
= cri
->cri_key
;
362 DPRINTK("%s(): ARC4\n", __FUNCTION__
);
363 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_CIPHER
;
364 lacSessCtx
->cipherSetupData
.cipherAlgorithm
=
365 CPA_CY_SYM_CIPHER_ARC4
;
366 lacSessCtx
->cipherSetupData
.cipherKeyLenInBytes
=
367 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
368 lacSessCtx
->cipherSetupData
.pCipherKey
= cri
->cri_key
;
372 DPRINTK("%s(): SHA1\n", __FUNCTION__
);
373 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
374 lacSessCtx
->hashSetupData
.hashAlgorithm
= CPA_CY_SYM_HASH_SHA1
;
375 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_PLAIN
;
376 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
378 cri
->cri_mlen
: ICP_SHA1_DIGEST_SIZE_IN_BYTES
);
382 case CRYPTO_SHA1_HMAC
:
383 DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__
);
384 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
385 lacSessCtx
->hashSetupData
.hashAlgorithm
= CPA_CY_SYM_HASH_SHA1
;
386 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_AUTH
;
387 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
389 cri
->cri_mlen
: ICP_SHA1_DIGEST_SIZE_IN_BYTES
);
390 lacSessCtx
->hashSetupData
.authModeSetupData
.authKey
=
392 lacSessCtx
->hashSetupData
.authModeSetupData
.authKeyLenInBytes
=
393 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
394 lacSessCtx
->hashSetupData
.authModeSetupData
.aadLenInBytes
= 0;
398 case CRYPTO_SHA2_256
:
399 DPRINTK("%s(): SHA256\n", __FUNCTION__
);
400 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
401 lacSessCtx
->hashSetupData
.hashAlgorithm
=
402 CPA_CY_SYM_HASH_SHA256
;
403 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_PLAIN
;
404 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
406 cri
->cri_mlen
: ICP_SHA256_DIGEST_SIZE_IN_BYTES
);
410 case CRYPTO_SHA2_256_HMAC
:
411 DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__
);
412 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
413 lacSessCtx
->hashSetupData
.hashAlgorithm
=
414 CPA_CY_SYM_HASH_SHA256
;
415 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_AUTH
;
416 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
418 cri
->cri_mlen
: ICP_SHA256_DIGEST_SIZE_IN_BYTES
);
419 lacSessCtx
->hashSetupData
.authModeSetupData
.authKey
=
421 lacSessCtx
->hashSetupData
.authModeSetupData
.authKeyLenInBytes
=
422 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
423 lacSessCtx
->hashSetupData
.authModeSetupData
.aadLenInBytes
= 0;
427 case CRYPTO_SHA2_384
:
428 DPRINTK("%s(): SHA384\n", __FUNCTION__
);
429 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
430 lacSessCtx
->hashSetupData
.hashAlgorithm
=
431 CPA_CY_SYM_HASH_SHA384
;
432 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_PLAIN
;
433 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
435 cri
->cri_mlen
: ICP_SHA384_DIGEST_SIZE_IN_BYTES
);
439 case CRYPTO_SHA2_384_HMAC
:
440 DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__
);
441 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
442 lacSessCtx
->hashSetupData
.hashAlgorithm
=
443 CPA_CY_SYM_HASH_SHA384
;
444 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_AUTH
;
445 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
447 cri
->cri_mlen
: ICP_SHA384_DIGEST_SIZE_IN_BYTES
);
448 lacSessCtx
->hashSetupData
.authModeSetupData
.authKey
=
450 lacSessCtx
->hashSetupData
.authModeSetupData
.authKeyLenInBytes
=
451 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
452 lacSessCtx
->hashSetupData
.authModeSetupData
.aadLenInBytes
= 0;
456 case CRYPTO_SHA2_512
:
457 DPRINTK("%s(): SHA512\n", __FUNCTION__
);
458 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
459 lacSessCtx
->hashSetupData
.hashAlgorithm
=
460 CPA_CY_SYM_HASH_SHA512
;
461 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_PLAIN
;
462 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
464 cri
->cri_mlen
: ICP_SHA512_DIGEST_SIZE_IN_BYTES
);
468 case CRYPTO_SHA2_512_HMAC
:
469 DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__
);
470 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
471 lacSessCtx
->hashSetupData
.hashAlgorithm
=
472 CPA_CY_SYM_HASH_SHA512
;
473 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_AUTH
;
474 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
476 cri
->cri_mlen
: ICP_SHA512_DIGEST_SIZE_IN_BYTES
);
477 lacSessCtx
->hashSetupData
.authModeSetupData
.authKey
=
479 lacSessCtx
->hashSetupData
.authModeSetupData
.authKeyLenInBytes
=
480 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
481 lacSessCtx
->hashSetupData
.authModeSetupData
.aadLenInBytes
= 0;
486 DPRINTK("%s(): MD5\n", __FUNCTION__
);
487 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
488 lacSessCtx
->hashSetupData
.hashAlgorithm
= CPA_CY_SYM_HASH_MD5
;
489 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_PLAIN
;
490 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
492 cri
->cri_mlen
: ICP_MD5_DIGEST_SIZE_IN_BYTES
);
496 case CRYPTO_MD5_HMAC
:
497 DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__
);
498 lacSessCtx
->symOperation
= CPA_CY_SYM_OP_HASH
;
499 lacSessCtx
->hashSetupData
.hashAlgorithm
= CPA_CY_SYM_HASH_MD5
;
500 lacSessCtx
->hashSetupData
.hashMode
= CPA_CY_SYM_HASH_MODE_AUTH
;
501 lacSessCtx
->hashSetupData
.digestResultLenInBytes
=
503 cri
->cri_mlen
: ICP_MD5_DIGEST_SIZE_IN_BYTES
);
504 lacSessCtx
->hashSetupData
.authModeSetupData
.authKey
=
506 lacSessCtx
->hashSetupData
.authModeSetupData
.authKeyLenInBytes
=
507 cri
->cri_klen
/ NUM_BITS_IN_BYTE
;
508 lacSessCtx
->hashSetupData
.authModeSetupData
.aadLenInBytes
= 0;
513 DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__
);
514 return ICP_OCF_DRV_STATUS_FAIL
;
517 return ICP_OCF_DRV_STATUS_SUCCESS
;
520 /* Name : icp_ocfDrvFreeOCFSession
522 * Description : This function deletes all existing Session data representing
523 * the Cryptographic session established between OCF and this driver. This
524 * also includes freeing the memory allocated for the session context. The
525 * session object is also removed from the session linked list.
527 static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData
*sessionData
)
530 sessionData
->inUse
= ICP_SESSION_DEREGISTERED
;
532 /*ENTER CRITICAL SECTION */
533 icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock
);
535 if (CPA_TRUE
== icp_atomic_read(&icp_ocfDrvIsExiting
)) {
536 /*If the Driver is exiting, allow that process to
537 handle any deletions */
538 /*EXIT CRITICAL SECTION */
539 icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock
);
543 icp_atomic_dec(&num_ocf_to_drv_registered_sessions
);
545 ICP_LIST_DEL(sessionData
, listNode
);
547 /*EXIT CRITICAL SECTION */
548 icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock
);
550 if (NULL
!= sessionData
->sessHandle
) {
551 icp_kfree(sessionData
->sessHandle
);
553 ICP_CACHE_FREE(drvSessionData_zone
, sessionData
);
556 /* Name : icp_ocfDrvFreeLACSession
558 * Description : This attempts to deregister a LAC session. If it fails, the
559 * deregistation retry function is called.
561 int icp_ocfDrvFreeLACSession(icp_device_t dev
, uint64_t sid
)
563 CpaCySymSessionCtx sessionToDeregister
= NULL
;
564 struct icp_drvSessionData
*sessionData
= NULL
;
565 CpaStatus lacStatus
= CPA_STATUS_SUCCESS
;
568 sessionData
= (struct icp_drvSessionData
*)CRYPTO_SESID2LID(sid
);
569 if (NULL
== sessionData
) {
570 EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
575 sessionToDeregister
= sessionData
->sessHandle
;
577 if ((ICP_SESSION_INITIALISED
!= sessionData
->inUse
) &&
578 (ICP_SESSION_RUNNING
!= sessionData
->inUse
) &&
579 (ICP_SESSION_DEREGISTERED
!= sessionData
->inUse
)) {
580 DPRINTK("%s() Session not initialised.\n", __FUNCTION__
);
584 if (ICP_SESSION_RUNNING
== sessionData
->inUse
) {
585 lacStatus
= cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE
,
586 sessionToDeregister
);
587 if (CPA_STATUS_RETRY
== lacStatus
) {
588 if (ICP_OCF_DRV_STATUS_SUCCESS
!=
589 icp_ocfDrvDeregRetry(&sessionToDeregister
)) {
590 /* the retry function increments the
591 dereg failed count */
592 DPRINTK("%s(): LAC failed to deregister the "
593 "session. (localSessionId= %p)\n",
594 __FUNCTION__
, sessionToDeregister
);
598 } else if (CPA_STATUS_SUCCESS
!= lacStatus
) {
599 DPRINTK("%s(): LAC failed to deregister the session. "
600 "localSessionId= %p, lacStatus = %d\n",
601 __FUNCTION__
, sessionToDeregister
, lacStatus
);
602 icp_atomic_inc(&lac_session_failed_dereg_count
);
606 DPRINTK("%s() Session not registered with LAC.\n",
610 icp_ocfDrvFreeOCFSession(sessionData
);
615 /* Name : icp_ocfDrvAlgCheck
617 * Description : This function checks whether the cryptodesc argument pertains
618 * to a sym or hash function
620 static int icp_ocfDrvAlgCheck(struct cryptodesc
*crp_desc
)
623 if (crp_desc
->crd_alg
== CRYPTO_3DES_CBC
||
624 crp_desc
->crd_alg
== CRYPTO_AES_CBC
||
625 crp_desc
->crd_alg
== CRYPTO_DES_CBC
||
626 crp_desc
->crd_alg
== CRYPTO_NULL_CBC
||
627 crp_desc
->crd_alg
== CRYPTO_ARC4
) {
628 return ICP_OCF_DRV_ALG_CIPHER
;
631 return ICP_OCF_DRV_ALG_HASH
;
634 /* Name : icp_ocfDrvSymProcess
636 * Description : This function will map symmetric functionality calls from OCF
637 * to the LAC API. It will also allocate memory to store the session context.
639 * Notes: If it is the first perform call for a given session, then a LAC
640 * session is registered. After the session is registered, no checks as
641 * to whether session paramaters have changed (e.g. alg chain order) are
644 int icp_ocfDrvSymProcess(icp_device_t dev
, struct cryptop
*crp
, int hint
)
646 struct icp_drvSessionData
*sessionData
= NULL
;
647 struct icp_drvOpData
*drvOpData
= NULL
;
648 CpaStatus lacStatus
= CPA_STATUS_SUCCESS
;
649 Cpa32U sessionCtxSizeInBytes
= 0;
652 DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
657 if (NULL
== crp
->crp_desc
) {
658 DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
659 "to crp\n", __FUNCTION__
);
660 crp
->crp_etype
= EINVAL
;
664 if (NULL
== crp
->crp_buf
) {
665 DPRINTK("%s(): Invalid input parameters, no buffer attached "
666 "to crp\n", __FUNCTION__
);
667 crp
->crp_etype
= EINVAL
;
671 if (CPA_TRUE
== icp_atomic_read(&icp_ocfDrvIsExiting
)) {
672 crp
->crp_etype
= EFAULT
;
676 sessionData
= (struct icp_drvSessionData
*)
677 (CRYPTO_SESID2LID(crp
->crp_sid
));
678 if (NULL
== sessionData
) {
679 DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
681 crp
->crp_etype
= EINVAL
;
685 /*If we get a request against a deregisted session, cancel operation*/
686 if (ICP_SESSION_DEREGISTERED
== sessionData
->inUse
) {
687 DPRINTK("%s(): Session ID %d was deregistered \n",
688 __FUNCTION__
, (int)(CRYPTO_SESID2LID(crp
->crp_sid
)));
689 crp
->crp_etype
= EFAULT
;
693 /*If none of the session states are set, then the session structure was either
694 not initialised properly or we are reading from a freed memory area (possible
695 due to OCF batch mode not removing queued requests against deregistered
697 if (ICP_SESSION_INITIALISED
!= sessionData
->inUse
&&
698 ICP_SESSION_RUNNING
!= sessionData
->inUse
) {
699 DPRINTK("%s(): Session - ID %d - not properly initialised or "
700 "memory freed back to the kernel \n",
701 __FUNCTION__
, (int)(CRYPTO_SESID2LID(crp
->crp_sid
)));
702 crp
->crp_etype
= EINVAL
;
706 /*For the below checks, remember error checking is already done in LAC.
707 We're not validating inputs subsequent to registration */
708 if (sessionData
->inUse
== ICP_SESSION_INITIALISED
) {
709 DPRINTK("%s(): Initialising session\n", __FUNCTION__
);
711 if (NULL
!= crp
->crp_desc
->crd_next
) {
712 if (ICP_OCF_DRV_ALG_CIPHER
==
713 icp_ocfDrvAlgCheck(crp
->crp_desc
)) {
715 sessionData
->lacSessCtx
.algChainOrder
=
716 CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH
;
718 if (crp
->crp_desc
->crd_flags
& CRD_F_ENCRYPT
) {
719 sessionData
->lacSessCtx
.cipherSetupData
.
721 CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT
;
723 sessionData
->lacSessCtx
.cipherSetupData
.
725 CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT
;
728 sessionData
->lacSessCtx
.algChainOrder
=
729 CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER
;
731 if (crp
->crp_desc
->crd_next
->crd_flags
&
733 sessionData
->lacSessCtx
.cipherSetupData
.
735 CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT
;
737 sessionData
->lacSessCtx
.cipherSetupData
.
739 CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT
;
744 } else if (ICP_OCF_DRV_ALG_CIPHER
==
745 icp_ocfDrvAlgCheck(crp
->crp_desc
)) {
746 if (crp
->crp_desc
->crd_flags
& CRD_F_ENCRYPT
) {
747 sessionData
->lacSessCtx
.cipherSetupData
.
749 CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT
;
751 sessionData
->lacSessCtx
.cipherSetupData
.
753 CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT
;
758 /*No action required for standalone Auth here */
760 /* Allocate memory for SymSessionCtx before the Session Registration */
762 cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE
,
763 &(sessionData
->lacSessCtx
),
764 &sessionCtxSizeInBytes
);
765 if (CPA_STATUS_SUCCESS
!= lacStatus
) {
766 EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
767 __FUNCTION__
, lacStatus
);
768 crp
->crp_etype
= EINVAL
;
771 sessionData
->sessHandle
=
772 icp_kmalloc(sessionCtxSizeInBytes
, ICP_M_NOWAIT
);
773 if (NULL
== sessionData
->sessHandle
) {
775 ("%s(): Failed to get memory for SymSessionCtx\n",
777 crp
->crp_etype
= ENOMEM
;
781 lacStatus
= cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE
,
782 icp_ocfDrvSymCallBack
,
783 &(sessionData
->lacSessCtx
),
784 sessionData
->sessHandle
);
786 if (CPA_STATUS_SUCCESS
!= lacStatus
) {
787 EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
788 __FUNCTION__
, lacStatus
);
789 crp
->crp_etype
= EFAULT
;
793 sessionData
->inUse
= ICP_SESSION_RUNNING
;
796 drvOpData
= icp_kmem_cache_zalloc(drvOpData_zone
, ICP_M_NOWAIT
);
797 if (NULL
== drvOpData
) {
798 EPRINTK("%s():Failed to get memory for drvOpData\n",
800 crp
->crp_etype
= ENOMEM
;
804 drvOpData
->lacOpData
.pSessionCtx
= sessionData
->sessHandle
;
805 drvOpData
->digestSizeInBytes
= sessionData
->lacSessCtx
.hashSetupData
.
806 digestResultLenInBytes
;
807 drvOpData
->crp
= crp
;
809 /* Set the default buffer list array memory allocation */
810 drvOpData
->srcBuffer
.pBuffers
= drvOpData
->bufferListArray
;
811 drvOpData
->numBufferListArray
= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS
;
813 if (ICP_OCF_DRV_STATUS_SUCCESS
!=
814 icp_ocfDrvProcessDataSetup(drvOpData
, drvOpData
->crp
->crp_desc
)) {
815 crp
->crp_etype
= EINVAL
;
819 if (drvOpData
->crp
->crp_desc
->crd_next
!= NULL
) {
820 if (icp_ocfDrvProcessDataSetup(drvOpData
, drvOpData
->crp
->
821 crp_desc
->crd_next
)) {
822 crp
->crp_etype
= EINVAL
;
829 * Allocate buffer list array memory if the data fragment is more than
830 * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
833 if (crp
->crp_flags
& ICP_CRYPTO_F_PACKET_BUF
) {
834 if (NULL
== drvOpData
->lacOpData
.pDigestResult
) {
835 drvOpData
->numBufferListArray
=
836 icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t
*)
840 if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS
<
841 drvOpData
->numBufferListArray
) {
842 DPRINTK("%s() numBufferListArray more than default\n",
844 drvOpData
->srcBuffer
.pBuffers
= NULL
;
845 drvOpData
->srcBuffer
.pBuffers
=
846 icp_kmalloc(drvOpData
->numBufferListArray
*
847 sizeof(CpaFlatBuffer
), ICP_M_NOWAIT
);
848 if (NULL
== drvOpData
->srcBuffer
.pBuffers
) {
849 EPRINTK("%s() Failed to get memory for "
850 "pBuffers\n", __FUNCTION__
);
851 ICP_CACHE_FREE(drvOpData_zone
, drvOpData
);
852 crp
->crp_etype
= ENOMEM
;
859 * Check the type of buffer structure we got and convert it into
860 * CpaBufferList format.
862 if (crp
->crp_flags
& ICP_CRYPTO_F_PACKET_BUF
) {
863 if (ICP_OCF_DRV_STATUS_SUCCESS
!=
864 icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t
*)
866 &(drvOpData
->srcBuffer
))) {
867 EPRINTK("%s():Failed to translate from packet buffer "
868 "to bufferlist\n", __FUNCTION__
);
869 crp
->crp_etype
= EINVAL
;
873 drvOpData
->bufferType
= ICP_CRYPTO_F_PACKET_BUF
;
874 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
875 /* OCF only supports IOV of one entry. */
876 if (NUM_IOV_SUPPORTED
==
877 ((struct uio
*)(crp
->crp_buf
))->uio_iovcnt
) {
879 icp_ocfDrvPtrAndLenToBufferList(((struct uio
*)(crp
->
882 ((struct uio
*)(crp
->
888 drvOpData
->bufferType
= CRYPTO_F_IOV
;
891 DPRINTK("%s():Unable to handle IOVs with lengths of "
892 "greater than one!\n", __FUNCTION__
);
893 crp
->crp_etype
= EINVAL
;
898 icp_ocfDrvPtrAndLenToBufferList(crp
->crp_buf
,
900 &(drvOpData
->srcBuffer
));
902 drvOpData
->bufferType
= CRYPTO_BUF_CONTIG
;
905 /* Allocate srcBuffer's private meta data */
906 if (ICP_OCF_DRV_STATUS_SUCCESS
!=
907 icp_ocfDrvAllocMetaData(&(drvOpData
->srcBuffer
), drvOpData
)) {
908 EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__
);
909 memset(&(drvOpData
->lacOpData
), 0, sizeof(CpaCySymOpData
));
910 crp
->crp_etype
= EINVAL
;
914 /* Perform "in-place" crypto operation */
915 lacStatus
= cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE
,
917 &(drvOpData
->lacOpData
),
918 &(drvOpData
->srcBuffer
),
919 &(drvOpData
->srcBuffer
),
920 &(drvOpData
->verifyResult
));
921 if (CPA_STATUS_RETRY
== lacStatus
) {
922 DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
923 __FUNCTION__
, lacStatus
);
924 memset(&(drvOpData
->lacOpData
), 0, sizeof(CpaCySymOpData
));
925 crp
->crp_etype
= ERESTART
;
928 if (CPA_STATUS_SUCCESS
!= lacStatus
) {
929 EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
930 __FUNCTION__
, lacStatus
);
931 memset(&(drvOpData
->lacOpData
), 0, sizeof(CpaCySymOpData
));
932 crp
->crp_etype
= EINVAL
;
936 return 0; //OCF success status value
939 if (drvOpData
->numBufferListArray
> ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS
) {
940 icp_kfree(drvOpData
->srcBuffer
.pBuffers
);
942 icp_ocfDrvFreeMetaData(&(drvOpData
->srcBuffer
));
943 ICP_CACHE_FREE(drvOpData_zone
, drvOpData
);
945 return crp
->crp_etype
;
948 /* Name : icp_ocfDrvProcessDataSetup
950 * Description : This function will setup all the cryptographic operation data
951 * that is required by LAC to execute the operation.
953 static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData
*drvOpData
,
954 struct cryptodesc
*crp_desc
)
956 CpaCyRandGenOpData randGenOpData
;
957 CpaFlatBuffer randData
;
959 drvOpData
->lacOpData
.packetType
= CPA_CY_SYM_PACKET_TYPE_FULL
;
961 /* Convert from the cryptop to the ICP LAC crypto parameters */
962 switch (crp_desc
->crd_alg
) {
963 case CRYPTO_NULL_CBC
:
964 drvOpData
->lacOpData
.
965 cryptoStartSrcOffsetInBytes
= crp_desc
->crd_skip
;
966 drvOpData
->lacOpData
.
967 messageLenToCipherInBytes
= crp_desc
->crd_len
;
968 drvOpData
->verifyResult
= CPA_FALSE
;
969 drvOpData
->lacOpData
.ivLenInBytes
= NULL_BLOCK_LEN
;
972 drvOpData
->lacOpData
.
973 cryptoStartSrcOffsetInBytes
= crp_desc
->crd_skip
;
974 drvOpData
->lacOpData
.
975 messageLenToCipherInBytes
= crp_desc
->crd_len
;
976 drvOpData
->verifyResult
= CPA_FALSE
;
977 drvOpData
->lacOpData
.ivLenInBytes
= DES_BLOCK_LEN
;
979 case CRYPTO_3DES_CBC
:
980 drvOpData
->lacOpData
.
981 cryptoStartSrcOffsetInBytes
= crp_desc
->crd_skip
;
982 drvOpData
->lacOpData
.
983 messageLenToCipherInBytes
= crp_desc
->crd_len
;
984 drvOpData
->verifyResult
= CPA_FALSE
;
985 drvOpData
->lacOpData
.ivLenInBytes
= DES3_BLOCK_LEN
;
988 drvOpData
->lacOpData
.
989 cryptoStartSrcOffsetInBytes
= crp_desc
->crd_skip
;
990 drvOpData
->lacOpData
.
991 messageLenToCipherInBytes
= crp_desc
->crd_len
;
992 drvOpData
->verifyResult
= CPA_FALSE
;
993 drvOpData
->lacOpData
.ivLenInBytes
= ARC4_COUNTER_LEN
;
996 drvOpData
->lacOpData
.
997 cryptoStartSrcOffsetInBytes
= crp_desc
->crd_skip
;
998 drvOpData
->lacOpData
.
999 messageLenToCipherInBytes
= crp_desc
->crd_len
;
1000 drvOpData
->verifyResult
= CPA_FALSE
;
1001 drvOpData
->lacOpData
.ivLenInBytes
= RIJNDAEL128_BLOCK_LEN
;
1004 case CRYPTO_SHA1_HMAC
:
1005 case CRYPTO_SHA2_256
:
1006 case CRYPTO_SHA2_256_HMAC
:
1007 case CRYPTO_SHA2_384
:
1008 case CRYPTO_SHA2_384_HMAC
:
1009 case CRYPTO_SHA2_512
:
1010 case CRYPTO_SHA2_512_HMAC
:
1012 case CRYPTO_MD5_HMAC
:
1013 drvOpData
->lacOpData
.
1014 hashStartSrcOffsetInBytes
= crp_desc
->crd_skip
;
1015 drvOpData
->lacOpData
.
1016 messageLenToHashInBytes
= crp_desc
->crd_len
;
1017 drvOpData
->lacOpData
.
1019 icp_ocfDrvDigestPointerFind(drvOpData
, crp_desc
);
1021 if (NULL
== drvOpData
->lacOpData
.pDigestResult
) {
1022 DPRINTK("%s(): ERROR - could not calculate "
1023 "Digest Result memory address\n", __FUNCTION__
);
1024 return ICP_OCF_DRV_STATUS_FAIL
;
1027 drvOpData
->lacOpData
.digestVerify
= CPA_FALSE
;
1030 DPRINTK("%s(): Crypto process error - algorithm not "
1031 "found \n", __FUNCTION__
);
1032 return ICP_OCF_DRV_STATUS_FAIL
;
1035 /* Figure out what the IV is supposed to be */
1036 if ((crp_desc
->crd_alg
== CRYPTO_DES_CBC
) ||
1037 (crp_desc
->crd_alg
== CRYPTO_3DES_CBC
) ||
1038 (crp_desc
->crd_alg
== CRYPTO_AES_CBC
)) {
1039 /*ARC4 doesn't use an IV */
1040 if (crp_desc
->crd_flags
& CRD_F_IV_EXPLICIT
) {
1041 /* Explicit IV provided to OCF */
1042 drvOpData
->lacOpData
.pIv
= crp_desc
->crd_iv
;
1044 /* IV is not explicitly provided to OCF */
1046 /* Point the LAC OP Data IV pointer to our allocated
1047 storage location for this session. */
1048 drvOpData
->lacOpData
.pIv
= drvOpData
->ivData
;
1050 if ((crp_desc
->crd_flags
& CRD_F_ENCRYPT
) &&
1051 ((crp_desc
->crd_flags
& CRD_F_IV_PRESENT
) == 0)) {
1053 /* Encrypting - need to create IV */
1054 randGenOpData
.generateBits
= CPA_TRUE
;
1055 randGenOpData
.lenInBytes
= MAX_IV_LEN_IN_BYTES
;
1057 icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U
*)
1060 MAX_IV_LEN_IN_BYTES
,
1063 if (CPA_STATUS_SUCCESS
!=
1064 cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE
,
1066 &randGenOpData
, &randData
)) {
1067 DPRINTK("%s(): ERROR - Failed to"
1069 " Initialisation Vector\n",
1071 return ICP_OCF_DRV_STATUS_FAIL
;
1074 crypto_copyback(drvOpData
->crp
->
1076 drvOpData
->crp
->crp_buf
,
1077 crp_desc
->crd_inject
,
1078 drvOpData
->lacOpData
.
1080 (caddr_t
) (drvOpData
->lacOpData
.
1083 /* Reading IV from buffer */
1084 crypto_copydata(drvOpData
->crp
->
1086 drvOpData
->crp
->crp_buf
,
1087 crp_desc
->crd_inject
,
1088 drvOpData
->lacOpData
.
1090 (caddr_t
) (drvOpData
->lacOpData
.
1098 return ICP_OCF_DRV_STATUS_SUCCESS
;
1101 /* Name : icp_ocfDrvDigestPointerFind
1103 * Description : This function is used to find the memory address of where the
1104 * digest information shall be stored in. Input buffer types are an skbuff, iov
1105 * or flat buffer. The address is found using the buffer data start address and
1108 * Note: In the case of a linux skbuff, the digest address may exist within
1109 * a memory space linked to from the start buffer. These linked memory spaces
1110 * must be traversed by the data length offset in order to find the digest start
1111 * address. Whether there is enough space for the digest must also be checked.
1113 uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData
* drvOpData
,
1114 struct cryptodesc
* crp_desc
)
1117 int offsetInBytes
= crp_desc
->crd_inject
;
1118 uint32_t digestSizeInBytes
= drvOpData
->digestSizeInBytes
;
1119 uint8_t *flat_buffer_base
= NULL
;
1120 int flat_buffer_length
= 0;
1122 if (drvOpData
->crp
->crp_flags
& ICP_CRYPTO_F_PACKET_BUF
) {
1124 return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData
,
1129 /* IOV or flat buffer */
1130 if (drvOpData
->crp
->crp_flags
& CRYPTO_F_IOV
) {
1131 /*single IOV check has already been done */
1132 flat_buffer_base
= ((struct uio
*)
1133 (drvOpData
->crp
->crp_buf
))->
1134 uio_iov
[0].iov_base
;
1135 flat_buffer_length
= ((struct uio
*)
1136 (drvOpData
->crp
->crp_buf
))->
1139 flat_buffer_base
= (uint8_t *) drvOpData
->crp
->crp_buf
;
1140 flat_buffer_length
= drvOpData
->crp
->crp_ilen
;
1143 if (flat_buffer_length
< (offsetInBytes
+ digestSizeInBytes
)) {
1144 DPRINTK("%s() Not enough space for Digest "
1145 "(IOV/Flat Buffer) \n", __FUNCTION__
);
1148 return (uint8_t *) (flat_buffer_base
+ offsetInBytes
);
1151 DPRINTK("%s() Should not reach this point\n", __FUNCTION__
);