Root/target/linux/generic/files/crypto/ocf/ep80579/icp_sym.c

1/***************************************************************************
2 *
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.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
9 *
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.
13 *
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.
18 *
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.
24 *
25 * Contact Information:
26 * Intel Corporation
27 *
28 * BSD LICENSE
29 *
30 * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 *
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
42 * distribution.
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.
46 *
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.
58 *
59 *
60 * version: Security.L.1.0.2-229
61 *
62 ***************************************************************************/
63/*
64 * An OCF module that uses the API for IntelĀ® QuickAssist Technology to do the
65 * cryptography.
66 *
67 * This driver requires the ICP Access Library that is available from Intel in
68 * order to operate.
69 */
70
71#include "icp_ocf.h"
72
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
75  call back to OCF*/
76static void
77icp_ocfDrvSymCallBack(void *callbackTag,
78              CpaStatus status,
79              const CpaCySymOp operationType,
80              void *pOpData,
81              CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
82
83/*This function is used to extract crypto processing information from the OCF
84  inputs, so as that it may be passed onto LAC*/
85static int
86icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
87               struct cryptodesc *crp_desc);
88
89/*This function checks whether the crp_desc argument pertains to a digest or a
90  cipher operation*/
91static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
92
93/*This function copies all the passed in session context information and stores
94  it in a LAC context structure*/
95static int
96icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
97             CpaCySymSessionSetupData * lacSessCtx);
98
99/*This function is used to free an OCF->OCF_DRV session object*/
100static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
101
102/*max IOV buffs supported in a UIO structure*/
103#define NUM_IOV_SUPPORTED (1)
104
105/* Name : icp_ocfDrvSymCallBack
106 *
107 * Description : When this function returns it signifies that the LAC
108 * component has completed the relevant symmetric operation.
109 *
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.
114 */
115static void
116icp_ocfDrvSymCallBack(void *callbackTag,
117              CpaStatus status,
118              const CpaCySymOp operationType,
119              void *pOpData,
120              CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
121{
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;
127
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__);
133        return;
134    }
135
136    crp = temp_drvOpData->crp;
137    crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
138
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;
144        crypto_done(crp);
145        return;
146    }
147
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;
153        crypto_done(crp);
154        return;
155    }
156
157    if (CPA_STATUS_SUCCESS == status) {
158
159        if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
160            if (ICP_OCF_DRV_STATUS_SUCCESS !=
161                icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
162                                 (icp_packet_buffer_t
163                                  **)
164                                 & (crp->crp_buf))) {
165                EPRINTK("%s(): BufferList to SkBuff "
166                    "conversion error.\n", __FUNCTION__);
167                crp->crp_etype = EPERM;
168            }
169        } else {
170            icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
171                            (void **)&tempBasePtr,
172                            &tempLen);
173            crp->crp_olen = (int)tempLen;
174        }
175
176    } else {
177        DPRINTK("%s(): The callback from the LAC component has failed"
178            "(status == %d).\n", __FUNCTION__, status);
179
180        crp->crp_etype = ECANCELED;
181    }
182
183    if (temp_drvOpData->numBufferListArray >
184        ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
185        icp_kfree(pDstBuffer->pBuffers);
186    }
187    icp_ocfDrvFreeMetaData(pDstBuffer);
188    ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
189
190    /* Invoke the OCF callback function */
191    crypto_done(crp);
192
193    return;
194}
195
196/* Name : icp_ocfDrvNewSession
197 *
198 * Description : This function will create a new Driver<->OCF session
199 *
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.
202 */
203int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
204             struct cryptoini *cri)
205{
206    struct icp_drvSessionData *sessionData = NULL;
207    uint32_t delete_session = 0;
208
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 */
212    if (NULL == sid) {
213        EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
214            __FUNCTION__);
215        return EINVAL;
216    }
217
218    if (NULL == cri) {
219        EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
220            __FUNCTION__);
221        return EINVAL;
222    }
223
224    if (icp_ocfDrvDriverId != *sid) {
225        EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
226            __FUNCTION__);
227        EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
228        return EINVAL;
229    }
230
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__);
234        return ENOMEM;
235    }
236
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)) {
242        delete_session++;
243
244    } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
245        if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
246            (max_sessions -
247             icp_atomic_read(&lac_session_failed_dereg_count))) {
248            delete_session++;
249        } else {
250            icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
251            /* Add to session data linked list */
252            ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
253                     listNode);
254        }
255
256    } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
257        ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
258                 listNode);
259    }
260
261    sessionData->inUse = ICP_SESSION_INITIALISED;
262
263    /*EXIT CRITICAL SECTION */
264    icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
265
266    if (delete_session) {
267        DPRINTK("%s():No Session handles available\n", __FUNCTION__);
268        ICP_CACHE_FREE(drvSessionData_zone, sessionData);
269        return EPERM;
270    }
271
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);
276        return EINVAL;
277    }
278
279    if (cri->cri_next) {
280        if (cri->cri_next->cri_next != NULL) {
281            DPRINTK("%s():only two chained algorithms supported\n",
282                __FUNCTION__);
283            icp_ocfDrvFreeOCFSession(sessionData);
284            return EPERM;
285        }
286
287        if (ICP_OCF_DRV_STATUS_SUCCESS !=
288            icp_ocfDrvAlgorithmSetup(cri->cri_next,
289                         &(sessionData->lacSessCtx))) {
290            DPRINTK("%s():second algorithm not supported\n",
291                __FUNCTION__);
292            icp_ocfDrvFreeOCFSession(sessionData);
293            return EINVAL;
294        }
295
296        sessionData->lacSessCtx.symOperation =
297            CPA_CY_SYM_OP_ALGORITHM_CHAINING;
298    }
299
300    *sid = (uint32_t) sessionData;
301
302    return ICP_OCF_DRV_STATUS_SUCCESS;
303}
304
305/* Name : icp_ocfDrvAlgorithmSetup
306 *
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.
311 */
312static int
313icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
314             CpaCySymSessionSetupData * lacSessCtx)
315{
316
317    lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
318
319    switch (cri->cri_alg) {
320
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;
329        break;
330
331    case CRYPTO_DES_CBC:
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;
339        break;
340
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;
349        break;
350
351    case CRYPTO_AES_CBC:
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;
359        break;
360
361    case CRYPTO_ARC4:
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;
369        break;
370
371    case CRYPTO_SHA1:
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 =
377            (cri->cri_mlen ?
378             cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
379
380        break;
381
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 =
388            (cri->cri_mlen ?
389             cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
390        lacSessCtx->hashSetupData.authModeSetupData.authKey =
391            cri->cri_key;
392        lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
393            cri->cri_klen / NUM_BITS_IN_BYTE;
394        lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
395
396        break;
397
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 =
405            (cri->cri_mlen ?
406             cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
407
408        break;
409
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 =
417            (cri->cri_mlen ?
418             cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
419        lacSessCtx->hashSetupData.authModeSetupData.authKey =
420            cri->cri_key;
421        lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
422            cri->cri_klen / NUM_BITS_IN_BYTE;
423        lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
424
425        break;
426
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 =
434            (cri->cri_mlen ?
435             cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
436
437        break;
438
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 =
446            (cri->cri_mlen ?
447             cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
448        lacSessCtx->hashSetupData.authModeSetupData.authKey =
449            cri->cri_key;
450        lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
451            cri->cri_klen / NUM_BITS_IN_BYTE;
452        lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
453
454        break;
455
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 =
463            (cri->cri_mlen ?
464             cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
465
466        break;
467
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 =
475            (cri->cri_mlen ?
476             cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
477        lacSessCtx->hashSetupData.authModeSetupData.authKey =
478            cri->cri_key;
479        lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
480            cri->cri_klen / NUM_BITS_IN_BYTE;
481        lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
482
483        break;
484
485    case CRYPTO_MD5:
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 =
491            (cri->cri_mlen ?
492             cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
493
494        break;
495
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 =
502            (cri->cri_mlen ?
503             cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
504        lacSessCtx->hashSetupData.authModeSetupData.authKey =
505            cri->cri_key;
506        lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
507            cri->cri_klen / NUM_BITS_IN_BYTE;
508        lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
509
510        break;
511
512    default:
513        DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
514        return ICP_OCF_DRV_STATUS_FAIL;
515    }
516
517    return ICP_OCF_DRV_STATUS_SUCCESS;
518}
519
520/* Name : icp_ocfDrvFreeOCFSession
521 *
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.
526 */
527static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
528{
529
530    sessionData->inUse = ICP_SESSION_DEREGISTERED;
531
532    /*ENTER CRITICAL SECTION */
533    icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
534
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);
540        return;
541    }
542
543    icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
544
545    ICP_LIST_DEL(sessionData, listNode);
546
547    /*EXIT CRITICAL SECTION */
548    icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
549
550    if (NULL != sessionData->sessHandle) {
551        icp_kfree(sessionData->sessHandle);
552    }
553    ICP_CACHE_FREE(drvSessionData_zone, sessionData);
554}
555
556/* Name : icp_ocfDrvFreeLACSession
557 *
558 * Description : This attempts to deregister a LAC session. If it fails, the
559 * deregistation retry function is called.
560 */
561int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
562{
563    CpaCySymSessionCtx sessionToDeregister = NULL;
564    struct icp_drvSessionData *sessionData = NULL;
565    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
566    int retval = 0;
567
568    sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
569    if (NULL == sessionData) {
570        EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
571            __FUNCTION__);
572        return EINVAL;
573    }
574
575    sessionToDeregister = sessionData->sessHandle;
576
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__);
581        return EINVAL;
582    }
583
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);
595                retval = EPERM;
596            }
597
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);
603            retval = EPERM;
604        }
605    } else {
606        DPRINTK("%s() Session not registered with LAC.\n",
607            __FUNCTION__);
608    }
609
610    icp_ocfDrvFreeOCFSession(sessionData);
611    return retval;
612
613}
614
615/* Name : icp_ocfDrvAlgCheck
616 *
617 * Description : This function checks whether the cryptodesc argument pertains
618 * to a sym or hash function
619 */
620static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
621{
622
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;
629    }
630
631    return ICP_OCF_DRV_ALG_HASH;
632}
633
634/* Name : icp_ocfDrvSymProcess
635 *
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.
638 *
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
642 * done.
643 */
644int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
645{
646    struct icp_drvSessionData *sessionData = NULL;
647    struct icp_drvOpData *drvOpData = NULL;
648    CpaStatus lacStatus = CPA_STATUS_SUCCESS;
649    Cpa32U sessionCtxSizeInBytes = 0;
650
651    if (NULL == crp) {
652        DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
653            __FUNCTION__);
654        return EINVAL;
655    }
656
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;
661        return EINVAL;
662    }
663
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;
668        return EINVAL;
669    }
670
671    if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
672        crp->crp_etype = EFAULT;
673        return EFAULT;
674    }
675
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",
680            __FUNCTION__);
681        crp->crp_etype = EINVAL;
682        return EINVAL;
683    }
684
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;
690        return EFAULT;
691    }
692
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
696  sessions*/
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;
703        return EINVAL;
704    }
705
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__);
710
711        if (NULL != crp->crp_desc->crd_next) {
712            if (ICP_OCF_DRV_ALG_CIPHER ==
713                icp_ocfDrvAlgCheck(crp->crp_desc)) {
714
715                sessionData->lacSessCtx.algChainOrder =
716                    CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
717
718                if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
719                    sessionData->lacSessCtx.cipherSetupData.
720                        cipherDirection =
721                        CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
722                } else {
723                    sessionData->lacSessCtx.cipherSetupData.
724                        cipherDirection =
725                        CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
726                }
727            } else {
728                sessionData->lacSessCtx.algChainOrder =
729                    CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
730
731                if (crp->crp_desc->crd_next->crd_flags &
732                    CRD_F_ENCRYPT) {
733                    sessionData->lacSessCtx.cipherSetupData.
734                        cipherDirection =
735                        CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
736                } else {
737                    sessionData->lacSessCtx.cipherSetupData.
738                        cipherDirection =
739                        CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
740                }
741
742            }
743
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.
748                    cipherDirection =
749                    CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
750            } else {
751                sessionData->lacSessCtx.cipherSetupData.
752                    cipherDirection =
753                    CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
754            }
755
756        }
757
758        /*No action required for standalone Auth here */
759
760        /* Allocate memory for SymSessionCtx before the Session Registration */
761        lacStatus =
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;
769            return EINVAL;
770        }
771        sessionData->sessHandle =
772            icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
773        if (NULL == sessionData->sessHandle) {
774            EPRINTK
775                ("%s(): Failed to get memory for SymSessionCtx\n",
776                 __FUNCTION__);
777            crp->crp_etype = ENOMEM;
778            return ENOMEM;
779        }
780
781        lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
782                        icp_ocfDrvSymCallBack,
783                        &(sessionData->lacSessCtx),
784                        sessionData->sessHandle);
785
786        if (CPA_STATUS_SUCCESS != lacStatus) {
787            EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
788                __FUNCTION__, lacStatus);
789            crp->crp_etype = EFAULT;
790            return EFAULT;
791        }
792
793        sessionData->inUse = ICP_SESSION_RUNNING;
794    }
795
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",
799            __FUNCTION__);
800        crp->crp_etype = ENOMEM;
801        return ENOMEM;
802    }
803
804    drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
805    drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
806        digestResultLenInBytes;
807    drvOpData->crp = crp;
808
809    /* Set the default buffer list array memory allocation */
810    drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
811    drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
812
813    if (ICP_OCF_DRV_STATUS_SUCCESS !=
814        icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
815        crp->crp_etype = EINVAL;
816        goto err;
817    }
818
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;
823            goto err;
824        }
825
826    }
827
828    /*
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
831     * calculated already
832     */
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 *)
837                             crp->crp_buf);
838        }
839
840        if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
841            drvOpData->numBufferListArray) {
842            DPRINTK("%s() numBufferListArray more than default\n",
843                __FUNCTION__);
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;
853                return ENOMEM;
854            }
855        }
856    }
857
858    /*
859     * Check the type of buffer structure we got and convert it into
860     * CpaBufferList format.
861     */
862    if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
863        if (ICP_OCF_DRV_STATUS_SUCCESS !=
864            icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
865                             crp->crp_buf,
866                             &(drvOpData->srcBuffer))) {
867            EPRINTK("%s():Failed to translate from packet buffer "
868                "to bufferlist\n", __FUNCTION__);
869            crp->crp_etype = EINVAL;
870            goto err;
871        }
872
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) {
878
879            icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
880                                    crp_buf))->
881                            uio_iov[0].iov_base,
882                            ((struct uio *)(crp->
883                                    crp_buf))->
884                            uio_iov[0].iov_len,
885                            &(drvOpData->
886                              srcBuffer));
887
888            drvOpData->bufferType = CRYPTO_F_IOV;
889
890        } else {
891            DPRINTK("%s():Unable to handle IOVs with lengths of "
892                "greater than one!\n", __FUNCTION__);
893            crp->crp_etype = EINVAL;
894            goto err;
895        }
896
897    } else {
898        icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
899                        crp->crp_ilen,
900                        &(drvOpData->srcBuffer));
901
902        drvOpData->bufferType = CRYPTO_BUF_CONTIG;
903    }
904
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;
911        goto err;
912    }
913
914    /* Perform "in-place" crypto operation */
915    lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
916                      (void *)drvOpData,
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;
926        goto err;
927    }
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;
933        goto err;
934    }
935
936    return 0; //OCF success status value
937
938      err:
939    if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
940        icp_kfree(drvOpData->srcBuffer.pBuffers);
941    }
942    icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
943    ICP_CACHE_FREE(drvOpData_zone, drvOpData);
944
945    return crp->crp_etype;
946}
947
948/* Name : icp_ocfDrvProcessDataSetup
949 *
950 * Description : This function will setup all the cryptographic operation data
951 * that is required by LAC to execute the operation.
952 */
953static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
954                      struct cryptodesc *crp_desc)
955{
956    CpaCyRandGenOpData randGenOpData;
957    CpaFlatBuffer randData;
958
959    drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
960
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;
970        break;
971    case CRYPTO_DES_CBC:
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;
978        break;
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;
986        break;
987    case CRYPTO_ARC4:
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;
994        break;
995    case CRYPTO_AES_CBC:
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;
1002        break;
1003    case CRYPTO_SHA1:
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:
1011    case CRYPTO_MD5:
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.
1018            pDigestResult =
1019            icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
1020
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;
1025        }
1026
1027        drvOpData->lacOpData.digestVerify = CPA_FALSE;
1028        break;
1029    default:
1030        DPRINTK("%s(): Crypto process error - algorithm not "
1031            "found \n", __FUNCTION__);
1032        return ICP_OCF_DRV_STATUS_FAIL;
1033    }
1034
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;
1043        } else {
1044            /* IV is not explicitly provided to OCF */
1045
1046            /* Point the LAC OP Data IV pointer to our allocated
1047               storage location for this session. */
1048            drvOpData->lacOpData.pIv = drvOpData->ivData;
1049
1050            if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
1051                ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
1052
1053                /* Encrypting - need to create IV */
1054                randGenOpData.generateBits = CPA_TRUE;
1055                randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
1056
1057                icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
1058                                drvOpData->
1059                                ivData,
1060                                MAX_IV_LEN_IN_BYTES,
1061                                &randData);
1062
1063                if (CPA_STATUS_SUCCESS !=
1064                    cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
1065                         NULL, NULL,
1066                         &randGenOpData, &randData)) {
1067                    DPRINTK("%s(): ERROR - Failed to"
1068                        " generate"
1069                        " Initialisation Vector\n",
1070                        __FUNCTION__);
1071                    return ICP_OCF_DRV_STATUS_FAIL;
1072                }
1073
1074                crypto_copyback(drvOpData->crp->
1075                        crp_flags,
1076                        drvOpData->crp->crp_buf,
1077                        crp_desc->crd_inject,
1078                        drvOpData->lacOpData.
1079                        ivLenInBytes,
1080                        (caddr_t) (drvOpData->lacOpData.
1081                               pIv));
1082            } else {
1083                /* Reading IV from buffer */
1084                crypto_copydata(drvOpData->crp->
1085                        crp_flags,
1086                        drvOpData->crp->crp_buf,
1087                        crp_desc->crd_inject,
1088                        drvOpData->lacOpData.
1089                        ivLenInBytes,
1090                        (caddr_t) (drvOpData->lacOpData.
1091                               pIv));
1092            }
1093
1094        }
1095
1096    }
1097
1098    return ICP_OCF_DRV_STATUS_SUCCESS;
1099}
1100
1101/* Name : icp_ocfDrvDigestPointerFind
1102 *
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
1106 * an offset.
1107 *
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.
1112 */
1113uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
1114                     struct cryptodesc * crp_desc)
1115{
1116
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;
1121
1122    if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
1123
1124        return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
1125                                   offsetInBytes,
1126                                   digestSizeInBytes);
1127
1128    } else {
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))->
1137                uio_iov[0].iov_len;
1138        } else {
1139            flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
1140            flat_buffer_length = drvOpData->crp->crp_ilen;
1141        }
1142
1143        if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
1144            DPRINTK("%s() Not enough space for Digest "
1145                "(IOV/Flat Buffer) \n", __FUNCTION__);
1146            return NULL;
1147        } else {
1148            return (uint8_t *) (flat_buffer_base + offsetInBytes);
1149        }
1150    }
1151    DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
1152    return NULL;
1153}
1154

Archive Download this file



interactive