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__);