rename target/linux/generic-2.6 to generic
[openwrt.git] / 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*/
76 static void
77 icp_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*/
85 static int
86 icp_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*/
91 static 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*/
95 static int
96 icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
97 CpaCySymSessionSetupData * lacSessCtx);
98
99 /*This function is used to free an OCF->OCF_DRV session object*/
100 static 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 */
115 static void
116 icp_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 */
203 int 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 */
312 static int
313 icp_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 */
527 static 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 */
561 int 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 */
620 static 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 */
644 int 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 */
953 static 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 */
1113 uint8_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 }
This page took 0.106732 seconds and 5 git commands to generate.