icp_sym.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  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. #include "icp_ocf.h"
  71. /*This is the call back function for all symmetric cryptographic processes.
  72. Its main functionality is to free driver crypto operation structure and to
  73. call back to OCF*/
  74. static void
  75. icp_ocfDrvSymCallBack(void *callbackTag,
  76. CpaStatus status,
  77. const CpaCySymOp operationType,
  78. void *pOpData,
  79. CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
  80. /*This function is used to extract crypto processing information from the OCF
  81. inputs, so as that it may be passed onto LAC*/
  82. static int
  83. icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  84. struct cryptodesc *crp_desc);
  85. /*This function checks whether the crp_desc argument pertains to a digest or a
  86. cipher operation*/
  87. static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
  88. /*This function copies all the passed in session context information and stores
  89. it in a LAC context structure*/
  90. static int
  91. icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  92. CpaCySymSessionSetupData * lacSessCtx);
  93. /*This function is used to free an OCF->OCF_DRV session object*/
  94. static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
  95. /*max IOV buffs supported in a UIO structure*/
  96. #define NUM_IOV_SUPPORTED (1)
  97. /* Name : icp_ocfDrvSymCallBack
  98. *
  99. * Description : When this function returns it signifies that the LAC
  100. * component has completed the relevant symmetric operation.
  101. *
  102. * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
  103. * object was passed to LAC for the cryptographic processing and contains all
  104. * the relevant information for cleaning up buffer handles etc. so that the
  105. * OCF EP80579 Driver portion of this crypto operation can be fully completed.
  106. */
  107. static void
  108. icp_ocfDrvSymCallBack(void *callbackTag,
  109. CpaStatus status,
  110. const CpaCySymOp operationType,
  111. void *pOpData,
  112. CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
  113. {
  114. struct cryptop *crp = NULL;
  115. struct icp_drvOpData *temp_drvOpData =
  116. (struct icp_drvOpData *)callbackTag;
  117. uint64_t *tempBasePtr = NULL;
  118. uint32_t tempLen = 0;
  119. if (NULL == temp_drvOpData) {
  120. DPRINTK("%s(): The callback from the LAC component"
  121. " has failed due to Null userOpaque data"
  122. "(status == %d).\n", __FUNCTION__, status);
  123. DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
  124. return;
  125. }
  126. crp = temp_drvOpData->crp;
  127. crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
  128. if (NULL == pOpData) {
  129. DPRINTK("%s(): The callback from the LAC component"
  130. " has failed due to Null Symmetric Op data"
  131. "(status == %d).\n", __FUNCTION__, status);
  132. crp->crp_etype = ECANCELED;
  133. crypto_done(crp);
  134. return;
  135. }
  136. if (NULL == pDstBuffer) {
  137. DPRINTK("%s(): The callback from the LAC component"
  138. " has failed due to Null Dst Bufferlist data"
  139. "(status == %d).\n", __FUNCTION__, status);
  140. crp->crp_etype = ECANCELED;
  141. crypto_done(crp);
  142. return;
  143. }
  144. if (CPA_STATUS_SUCCESS == status) {
  145. if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
  146. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  147. icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
  148. (icp_packet_buffer_t
  149. **)
  150. & (crp->crp_buf))) {
  151. EPRINTK("%s(): BufferList to SkBuff "
  152. "conversion error.\n", __FUNCTION__);
  153. crp->crp_etype = EPERM;
  154. }
  155. } else {
  156. icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
  157. (void **)&tempBasePtr,
  158. &tempLen);
  159. crp->crp_olen = (int)tempLen;
  160. }
  161. } else {
  162. DPRINTK("%s(): The callback from the LAC component has failed"
  163. "(status == %d).\n", __FUNCTION__, status);
  164. crp->crp_etype = ECANCELED;
  165. }
  166. if (temp_drvOpData->numBufferListArray >
  167. ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  168. icp_kfree(pDstBuffer->pBuffers);
  169. }
  170. icp_ocfDrvFreeMetaData(pDstBuffer);
  171. ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
  172. /* Invoke the OCF callback function */
  173. crypto_done(crp);
  174. return;
  175. }
  176. /* Name : icp_ocfDrvNewSession
  177. *
  178. * Description : This function will create a new Driver<->OCF session
  179. *
  180. * Notes : LAC session registration happens during the first perform call.
  181. * That is the first time we know all information about a given session.
  182. */
  183. int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
  184. struct cryptoini *cri)
  185. {
  186. struct icp_drvSessionData *sessionData = NULL;
  187. uint32_t delete_session = 0;
  188. /* The SID passed in should be our driver ID. We can return the */
  189. /* local ID (LID) which is a unique identifier which we can use */
  190. /* to differentiate between the encrypt/decrypt LAC session handles */
  191. if (NULL == sid) {
  192. EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
  193. __FUNCTION__);
  194. return EINVAL;
  195. }
  196. if (NULL == cri) {
  197. EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
  198. __FUNCTION__);
  199. return EINVAL;
  200. }
  201. if (icp_ocfDrvDriverId != *sid) {
  202. EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
  203. __FUNCTION__);
  204. EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
  205. return EINVAL;
  206. }
  207. sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);
  208. if (NULL == sessionData) {
  209. DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
  210. return ENOMEM;
  211. }
  212. /*ENTER CRITICAL SECTION */
  213. icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  214. /*put this check in the spinlock so no new sessions can be added to the
  215. linked list when we are exiting */
  216. if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  217. delete_session++;
  218. } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
  219. if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
  220. (max_sessions -
  221. icp_atomic_read(&lac_session_failed_dereg_count))) {
  222. delete_session++;
  223. } else {
  224. icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
  225. /* Add to session data linked list */
  226. ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  227. listNode);
  228. }
  229. } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
  230. ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  231. listNode);
  232. }
  233. sessionData->inUse = ICP_SESSION_INITIALISED;
  234. /*EXIT CRITICAL SECTION */
  235. icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  236. if (delete_session) {
  237. DPRINTK("%s():No Session handles available\n", __FUNCTION__);
  238. ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  239. return EPERM;
  240. }
  241. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  242. icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
  243. DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
  244. icp_ocfDrvFreeOCFSession(sessionData);
  245. return EINVAL;
  246. }
  247. if (cri->cri_next) {
  248. if (cri->cri_next->cri_next != NULL) {
  249. DPRINTK("%s():only two chained algorithms supported\n",
  250. __FUNCTION__);
  251. icp_ocfDrvFreeOCFSession(sessionData);
  252. return EPERM;
  253. }
  254. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  255. icp_ocfDrvAlgorithmSetup(cri->cri_next,
  256. &(sessionData->lacSessCtx))) {
  257. DPRINTK("%s():second algorithm not supported\n",
  258. __FUNCTION__);
  259. icp_ocfDrvFreeOCFSession(sessionData);
  260. return EINVAL;
  261. }
  262. sessionData->lacSessCtx.symOperation =
  263. CPA_CY_SYM_OP_ALGORITHM_CHAINING;
  264. }
  265. *sid = (uint32_t) sessionData;
  266. return ICP_OCF_DRV_STATUS_SUCCESS;
  267. }
  268. /* Name : icp_ocfDrvAlgorithmSetup
  269. *
  270. * Description : This function builds the session context data from the
  271. * information supplied through OCF. Algorithm chain order and whether the
  272. * session is Encrypt/Decrypt can only be found out at perform time however, so
  273. * the session is registered with LAC at that time.
  274. */
  275. static int
  276. icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  277. CpaCySymSessionSetupData * lacSessCtx)
  278. {
  279. lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
  280. switch (cri->cri_alg) {
  281. case CRYPTO_NULL_CBC:
  282. DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
  283. lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  284. lacSessCtx->cipherSetupData.cipherAlgorithm =
  285. CPA_CY_SYM_CIPHER_NULL;
  286. lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  287. cri->cri_klen / NUM_BITS_IN_BYTE;
  288. lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  289. break;
  290. case CRYPTO_DES_CBC:
  291. DPRINTK("%s(): DES CBC\n", __FUNCTION__);
  292. lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  293. lacSessCtx->cipherSetupData.cipherAlgorithm =
  294. CPA_CY_SYM_CIPHER_DES_CBC;
  295. lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  296. cri->cri_klen / NUM_BITS_IN_BYTE;
  297. lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  298. break;
  299. case CRYPTO_3DES_CBC:
  300. DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
  301. lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  302. lacSessCtx->cipherSetupData.cipherAlgorithm =
  303. CPA_CY_SYM_CIPHER_3DES_CBC;
  304. lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  305. cri->cri_klen / NUM_BITS_IN_BYTE;
  306. lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  307. break;
  308. case CRYPTO_AES_CBC:
  309. DPRINTK("%s(): AES CBC\n", __FUNCTION__);
  310. lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  311. lacSessCtx->cipherSetupData.cipherAlgorithm =
  312. CPA_CY_SYM_CIPHER_AES_CBC;
  313. lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  314. cri->cri_klen / NUM_BITS_IN_BYTE;
  315. lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  316. break;
  317. case CRYPTO_ARC4:
  318. DPRINTK("%s(): ARC4\n", __FUNCTION__);
  319. lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  320. lacSessCtx->cipherSetupData.cipherAlgorithm =
  321. CPA_CY_SYM_CIPHER_ARC4;
  322. lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  323. cri->cri_klen / NUM_BITS_IN_BYTE;
  324. lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  325. break;
  326. case CRYPTO_SHA1:
  327. DPRINTK("%s(): SHA1\n", __FUNCTION__);
  328. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  329. lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  330. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  331. lacSessCtx->hashSetupData.digestResultLenInBytes =
  332. (cri->cri_mlen ?
  333. cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  334. break;
  335. case CRYPTO_SHA1_HMAC:
  336. DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
  337. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  338. lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  339. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  340. lacSessCtx->hashSetupData.digestResultLenInBytes =
  341. (cri->cri_mlen ?
  342. cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  343. lacSessCtx->hashSetupData.authModeSetupData.authKey =
  344. cri->cri_key;
  345. lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  346. cri->cri_klen / NUM_BITS_IN_BYTE;
  347. lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  348. break;
  349. case CRYPTO_SHA2_256:
  350. DPRINTK("%s(): SHA256\n", __FUNCTION__);
  351. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  352. lacSessCtx->hashSetupData.hashAlgorithm =
  353. CPA_CY_SYM_HASH_SHA256;
  354. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  355. lacSessCtx->hashSetupData.digestResultLenInBytes =
  356. (cri->cri_mlen ?
  357. cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  358. break;
  359. case CRYPTO_SHA2_256_HMAC:
  360. DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
  361. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  362. lacSessCtx->hashSetupData.hashAlgorithm =
  363. CPA_CY_SYM_HASH_SHA256;
  364. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  365. lacSessCtx->hashSetupData.digestResultLenInBytes =
  366. (cri->cri_mlen ?
  367. cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  368. lacSessCtx->hashSetupData.authModeSetupData.authKey =
  369. cri->cri_key;
  370. lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  371. cri->cri_klen / NUM_BITS_IN_BYTE;
  372. lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  373. break;
  374. case CRYPTO_SHA2_384:
  375. DPRINTK("%s(): SHA384\n", __FUNCTION__);
  376. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  377. lacSessCtx->hashSetupData.hashAlgorithm =
  378. CPA_CY_SYM_HASH_SHA384;
  379. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  380. lacSessCtx->hashSetupData.digestResultLenInBytes =
  381. (cri->cri_mlen ?
  382. cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  383. break;
  384. case CRYPTO_SHA2_384_HMAC:
  385. DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
  386. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  387. lacSessCtx->hashSetupData.hashAlgorithm =
  388. CPA_CY_SYM_HASH_SHA384;
  389. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  390. lacSessCtx->hashSetupData.digestResultLenInBytes =
  391. (cri->cri_mlen ?
  392. cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  393. lacSessCtx->hashSetupData.authModeSetupData.authKey =
  394. cri->cri_key;
  395. lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  396. cri->cri_klen / NUM_BITS_IN_BYTE;
  397. lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  398. break;
  399. case CRYPTO_SHA2_512:
  400. DPRINTK("%s(): SHA512\n", __FUNCTION__);
  401. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  402. lacSessCtx->hashSetupData.hashAlgorithm =
  403. CPA_CY_SYM_HASH_SHA512;
  404. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  405. lacSessCtx->hashSetupData.digestResultLenInBytes =
  406. (cri->cri_mlen ?
  407. cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  408. break;
  409. case CRYPTO_SHA2_512_HMAC:
  410. DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
  411. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  412. lacSessCtx->hashSetupData.hashAlgorithm =
  413. CPA_CY_SYM_HASH_SHA512;
  414. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  415. lacSessCtx->hashSetupData.digestResultLenInBytes =
  416. (cri->cri_mlen ?
  417. cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  418. lacSessCtx->hashSetupData.authModeSetupData.authKey =
  419. cri->cri_key;
  420. lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  421. cri->cri_klen / NUM_BITS_IN_BYTE;
  422. lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  423. break;
  424. case CRYPTO_MD5:
  425. DPRINTK("%s(): MD5\n", __FUNCTION__);
  426. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  427. lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  428. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  429. lacSessCtx->hashSetupData.digestResultLenInBytes =
  430. (cri->cri_mlen ?
  431. cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  432. break;
  433. case CRYPTO_MD5_HMAC:
  434. DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
  435. lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  436. lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  437. lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  438. lacSessCtx->hashSetupData.digestResultLenInBytes =
  439. (cri->cri_mlen ?
  440. cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  441. lacSessCtx->hashSetupData.authModeSetupData.authKey =
  442. cri->cri_key;
  443. lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  444. cri->cri_klen / NUM_BITS_IN_BYTE;
  445. lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  446. break;
  447. default:
  448. DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
  449. return ICP_OCF_DRV_STATUS_FAIL;
  450. }
  451. return ICP_OCF_DRV_STATUS_SUCCESS;
  452. }
  453. /* Name : icp_ocfDrvFreeOCFSession
  454. *
  455. * Description : This function deletes all existing Session data representing
  456. * the Cryptographic session established between OCF and this driver. This
  457. * also includes freeing the memory allocated for the session context. The
  458. * session object is also removed from the session linked list.
  459. */
  460. static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
  461. {
  462. sessionData->inUse = ICP_SESSION_DEREGISTERED;
  463. /*ENTER CRITICAL SECTION */
  464. icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  465. if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  466. /*If the Driver is exiting, allow that process to
  467. handle any deletions */
  468. /*EXIT CRITICAL SECTION */
  469. icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  470. return;
  471. }
  472. icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
  473. ICP_LIST_DEL(sessionData, listNode);
  474. /*EXIT CRITICAL SECTION */
  475. icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  476. if (NULL != sessionData->sessHandle) {
  477. icp_kfree(sessionData->sessHandle);
  478. }
  479. ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  480. }
  481. /* Name : icp_ocfDrvFreeLACSession
  482. *
  483. * Description : This attempts to deregister a LAC session. If it fails, the
  484. * deregistation retry function is called.
  485. */
  486. int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
  487. {
  488. CpaCySymSessionCtx sessionToDeregister = NULL;
  489. struct icp_drvSessionData *sessionData = NULL;
  490. CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  491. int retval = 0;
  492. sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
  493. if (NULL == sessionData) {
  494. EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
  495. __FUNCTION__);
  496. return EINVAL;
  497. }
  498. sessionToDeregister = sessionData->sessHandle;
  499. if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&
  500. (ICP_SESSION_RUNNING != sessionData->inUse) &&
  501. (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {
  502. DPRINTK("%s() Session not initialised.\n", __FUNCTION__);
  503. return EINVAL;
  504. }
  505. if (ICP_SESSION_RUNNING == sessionData->inUse) {
  506. lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  507. sessionToDeregister);
  508. if (CPA_STATUS_RETRY == lacStatus) {
  509. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  510. icp_ocfDrvDeregRetry(&sessionToDeregister)) {
  511. /* the retry function increments the
  512. dereg failed count */
  513. DPRINTK("%s(): LAC failed to deregister the "
  514. "session. (localSessionId= %p)\n",
  515. __FUNCTION__, sessionToDeregister);
  516. retval = EPERM;
  517. }
  518. } else if (CPA_STATUS_SUCCESS != lacStatus) {
  519. DPRINTK("%s(): LAC failed to deregister the session. "
  520. "localSessionId= %p, lacStatus = %d\n",
  521. __FUNCTION__, sessionToDeregister, lacStatus);
  522. icp_atomic_inc(&lac_session_failed_dereg_count);
  523. retval = EPERM;
  524. }
  525. } else {
  526. DPRINTK("%s() Session not registered with LAC.\n",
  527. __FUNCTION__);
  528. }
  529. icp_ocfDrvFreeOCFSession(sessionData);
  530. return retval;
  531. }
  532. /* Name : icp_ocfDrvAlgCheck
  533. *
  534. * Description : This function checks whether the cryptodesc argument pertains
  535. * to a sym or hash function
  536. */
  537. static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
  538. {
  539. if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
  540. crp_desc->crd_alg == CRYPTO_AES_CBC ||
  541. crp_desc->crd_alg == CRYPTO_DES_CBC ||
  542. crp_desc->crd_alg == CRYPTO_NULL_CBC ||
  543. crp_desc->crd_alg == CRYPTO_ARC4) {
  544. return ICP_OCF_DRV_ALG_CIPHER;
  545. }
  546. return ICP_OCF_DRV_ALG_HASH;
  547. }
  548. /* Name : icp_ocfDrvSymProcess
  549. *
  550. * Description : This function will map symmetric functionality calls from OCF
  551. * to the LAC API. It will also allocate memory to store the session context.
  552. *
  553. * Notes: If it is the first perform call for a given session, then a LAC
  554. * session is registered. After the session is registered, no checks as
  555. * to whether session paramaters have changed (e.g. alg chain order) are
  556. * done.
  557. */
  558. int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
  559. {
  560. struct icp_drvSessionData *sessionData = NULL;
  561. struct icp_drvOpData *drvOpData = NULL;
  562. CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  563. Cpa32U sessionCtxSizeInBytes = 0;
  564. if (NULL == crp) {
  565. DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
  566. __FUNCTION__);
  567. return EINVAL;
  568. }
  569. if (NULL == crp->crp_desc) {
  570. DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
  571. "to crp\n", __FUNCTION__);
  572. crp->crp_etype = EINVAL;
  573. return EINVAL;
  574. }
  575. if (NULL == crp->crp_buf) {
  576. DPRINTK("%s(): Invalid input parameters, no buffer attached "
  577. "to crp\n", __FUNCTION__);
  578. crp->crp_etype = EINVAL;
  579. return EINVAL;
  580. }
  581. if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  582. crp->crp_etype = EFAULT;
  583. return EFAULT;
  584. }
  585. sessionData = (struct icp_drvSessionData *)
  586. (CRYPTO_SESID2LID(crp->crp_sid));
  587. if (NULL == sessionData) {
  588. DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
  589. __FUNCTION__);
  590. crp->crp_etype = EINVAL;
  591. return EINVAL;
  592. }
  593. /*If we get a request against a deregisted session, cancel operation*/
  594. if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
  595. DPRINTK("%s(): Session ID %d was deregistered \n",
  596. __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  597. crp->crp_etype = EFAULT;
  598. return EFAULT;
  599. }
  600. /*If none of the session states are set, then the session structure was either
  601. not initialised properly or we are reading from a freed memory area (possible
  602. due to OCF batch mode not removing queued requests against deregistered
  603. sessions*/
  604. if (ICP_SESSION_INITIALISED != sessionData->inUse &&
  605. ICP_SESSION_RUNNING != sessionData->inUse) {
  606. DPRINTK("%s(): Session - ID %d - not properly initialised or "
  607. "memory freed back to the kernel \n",
  608. __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  609. crp->crp_etype = EINVAL;
  610. return EINVAL;
  611. }
  612. /*For the below checks, remember error checking is already done in LAC.
  613. We're not validating inputs subsequent to registration */
  614. if (sessionData->inUse == ICP_SESSION_INITIALISED) {
  615. DPRINTK("%s(): Initialising session\n", __FUNCTION__);
  616. if (NULL != crp->crp_desc->crd_next) {
  617. if (ICP_OCF_DRV_ALG_CIPHER ==
  618. icp_ocfDrvAlgCheck(crp->crp_desc)) {
  619. sessionData->lacSessCtx.algChainOrder =
  620. CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
  621. if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  622. sessionData->lacSessCtx.cipherSetupData.
  623. cipherDirection =
  624. CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  625. } else {
  626. sessionData->lacSessCtx.cipherSetupData.
  627. cipherDirection =
  628. CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  629. }
  630. } else {
  631. sessionData->lacSessCtx.algChainOrder =
  632. CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  633. if (crp->crp_desc->crd_next->crd_flags &
  634. CRD_F_ENCRYPT) {
  635. sessionData->lacSessCtx.cipherSetupData.
  636. cipherDirection =
  637. CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  638. } else {
  639. sessionData->lacSessCtx.cipherSetupData.
  640. cipherDirection =
  641. CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  642. }
  643. }
  644. } else if (ICP_OCF_DRV_ALG_CIPHER ==
  645. icp_ocfDrvAlgCheck(crp->crp_desc)) {
  646. if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  647. sessionData->lacSessCtx.cipherSetupData.
  648. cipherDirection =
  649. CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  650. } else {
  651. sessionData->lacSessCtx.cipherSetupData.
  652. cipherDirection =
  653. CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  654. }
  655. }
  656. /*No action required for standalone Auth here */
  657. /* Allocate memory for SymSessionCtx before the Session Registration */
  658. lacStatus =
  659. cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
  660. &(sessionData->lacSessCtx),
  661. &sessionCtxSizeInBytes);
  662. if (CPA_STATUS_SUCCESS != lacStatus) {
  663. EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
  664. __FUNCTION__, lacStatus);
  665. crp->crp_etype = EINVAL;
  666. return EINVAL;
  667. }
  668. sessionData->sessHandle =
  669. icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
  670. if (NULL == sessionData->sessHandle) {
  671. EPRINTK
  672. ("%s(): Failed to get memory for SymSessionCtx\n",
  673. __FUNCTION__);
  674. crp->crp_etype = ENOMEM;
  675. return ENOMEM;
  676. }
  677. lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
  678. icp_ocfDrvSymCallBack,
  679. &(sessionData->lacSessCtx),
  680. sessionData->sessHandle);
  681. if (CPA_STATUS_SUCCESS != lacStatus) {
  682. EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
  683. __FUNCTION__, lacStatus);
  684. crp->crp_etype = EFAULT;
  685. return EFAULT;
  686. }
  687. sessionData->inUse = ICP_SESSION_RUNNING;
  688. }
  689. drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);
  690. if (NULL == drvOpData) {
  691. EPRINTK("%s():Failed to get memory for drvOpData\n",
  692. __FUNCTION__);
  693. crp->crp_etype = ENOMEM;
  694. return ENOMEM;
  695. }
  696. drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
  697. drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
  698. digestResultLenInBytes;
  699. drvOpData->crp = crp;
  700. /* Set the default buffer list array memory allocation */
  701. drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
  702. drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
  703. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  704. icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
  705. crp->crp_etype = EINVAL;
  706. goto err;
  707. }
  708. if (drvOpData->crp->crp_desc->crd_next != NULL) {
  709. if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
  710. crp_desc->crd_next)) {
  711. crp->crp_etype = EINVAL;
  712. goto err;
  713. }
  714. }
  715. /*
  716. * Allocate buffer list array memory if the data fragment is more than
  717. * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
  718. * calculated already
  719. */
  720. if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  721. if (NULL == drvOpData->lacOpData.pDigestResult) {
  722. drvOpData->numBufferListArray =
  723. icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)
  724. crp->crp_buf);
  725. }
  726. if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
  727. drvOpData->numBufferListArray) {
  728. DPRINTK("%s() numBufferListArray more than default\n",
  729. __FUNCTION__);
  730. drvOpData->srcBuffer.pBuffers = NULL;
  731. drvOpData->srcBuffer.pBuffers =
  732. icp_kmalloc(drvOpData->numBufferListArray *
  733. sizeof(CpaFlatBuffer), ICP_M_NOWAIT);
  734. if (NULL == drvOpData->srcBuffer.pBuffers) {
  735. EPRINTK("%s() Failed to get memory for "
  736. "pBuffers\n", __FUNCTION__);
  737. ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  738. crp->crp_etype = ENOMEM;
  739. return ENOMEM;
  740. }
  741. }
  742. }
  743. /*
  744. * Check the type of buffer structure we got and convert it into
  745. * CpaBufferList format.
  746. */
  747. if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  748. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  749. icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
  750. crp->crp_buf,
  751. &(drvOpData->srcBuffer))) {
  752. EPRINTK("%s():Failed to translate from packet buffer "
  753. "to bufferlist\n", __FUNCTION__);
  754. crp->crp_etype = EINVAL;
  755. goto err;
  756. }
  757. drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;
  758. } else if (crp->crp_flags & CRYPTO_F_IOV) {
  759. /* OCF only supports IOV of one entry. */
  760. if (NUM_IOV_SUPPORTED ==
  761. ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
  762. icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
  763. crp_buf))->
  764. uio_iov[0].iov_base,
  765. ((struct uio *)(crp->
  766. crp_buf))->
  767. uio_iov[0].iov_len,
  768. &(drvOpData->
  769. srcBuffer));
  770. drvOpData->bufferType = CRYPTO_F_IOV;
  771. } else {
  772. DPRINTK("%s():Unable to handle IOVs with lengths of "
  773. "greater than one!\n", __FUNCTION__);
  774. crp->crp_etype = EINVAL;
  775. goto err;
  776. }
  777. } else {
  778. icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
  779. crp->crp_ilen,
  780. &(drvOpData->srcBuffer));
  781. drvOpData->bufferType = CRYPTO_BUF_CONTIG;
  782. }
  783. /* Allocate srcBuffer's private meta data */
  784. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  785. icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
  786. EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
  787. memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  788. crp->crp_etype = EINVAL;
  789. goto err;
  790. }
  791. /* Perform "in-place" crypto operation */
  792. lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
  793. (void *)drvOpData,
  794. &(drvOpData->lacOpData),
  795. &(drvOpData->srcBuffer),
  796. &(drvOpData->srcBuffer),
  797. &(drvOpData->verifyResult));
  798. if (CPA_STATUS_RETRY == lacStatus) {
  799. DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
  800. __FUNCTION__, lacStatus);
  801. memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  802. crp->crp_etype = ERESTART;
  803. goto err;
  804. }
  805. if (CPA_STATUS_SUCCESS != lacStatus) {
  806. EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
  807. __FUNCTION__, lacStatus);
  808. memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  809. crp->crp_etype = EINVAL;
  810. goto err;
  811. }
  812. return 0; //OCF success status value
  813. err:
  814. if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  815. icp_kfree(drvOpData->srcBuffer.pBuffers);
  816. }
  817. icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
  818. ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  819. return crp->crp_etype;
  820. }
  821. /* Name : icp_ocfDrvProcessDataSetup
  822. *
  823. * Description : This function will setup all the cryptographic operation data
  824. * that is required by LAC to execute the operation.
  825. */
  826. static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  827. struct cryptodesc *crp_desc)
  828. {
  829. CpaCyRandGenOpData randGenOpData;
  830. CpaFlatBuffer randData;
  831. drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  832. /* Convert from the cryptop to the ICP LAC crypto parameters */
  833. switch (crp_desc->crd_alg) {
  834. case CRYPTO_NULL_CBC:
  835. drvOpData->lacOpData.
  836. cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  837. drvOpData->lacOpData.
  838. messageLenToCipherInBytes = crp_desc->crd_len;
  839. drvOpData->verifyResult = CPA_FALSE;
  840. drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
  841. break;
  842. case CRYPTO_DES_CBC:
  843. drvOpData->lacOpData.
  844. cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  845. drvOpData->lacOpData.
  846. messageLenToCipherInBytes = crp_desc->crd_len;
  847. drvOpData->verifyResult = CPA_FALSE;
  848. drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
  849. break;
  850. case CRYPTO_3DES_CBC:
  851. drvOpData->lacOpData.
  852. cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  853. drvOpData->lacOpData.
  854. messageLenToCipherInBytes = crp_desc->crd_len;
  855. drvOpData->verifyResult = CPA_FALSE;
  856. drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
  857. break;
  858. case CRYPTO_ARC4:
  859. drvOpData->lacOpData.
  860. cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  861. drvOpData->lacOpData.
  862. messageLenToCipherInBytes = crp_desc->crd_len;
  863. drvOpData->verifyResult = CPA_FALSE;
  864. drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
  865. break;
  866. case CRYPTO_AES_CBC:
  867. drvOpData->lacOpData.
  868. cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  869. drvOpData->lacOpData.
  870. messageLenToCipherInBytes = crp_desc->crd_len;
  871. drvOpData->verifyResult = CPA_FALSE;
  872. drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
  873. break;
  874. case CRYPTO_SHA1:
  875. case CRYPTO_SHA1_HMAC:
  876. case CRYPTO_SHA2_256:
  877. case CRYPTO_SHA2_256_HMAC:
  878. case CRYPTO_SHA2_384:
  879. case CRYPTO_SHA2_384_HMAC:
  880. case CRYPTO_SHA2_512:
  881. case CRYPTO_SHA2_512_HMAC:
  882. case CRYPTO_MD5:
  883. case CRYPTO_MD5_HMAC:
  884. drvOpData->lacOpData.
  885. hashStartSrcOffsetInBytes = crp_desc->crd_skip;
  886. drvOpData->lacOpData.
  887. messageLenToHashInBytes = crp_desc->crd_len;
  888. drvOpData->lacOpData.
  889. pDigestResult =
  890. icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
  891. if (NULL == drvOpData->lacOpData.pDigestResult) {
  892. DPRINTK("%s(): ERROR - could not calculate "
  893. "Digest Result memory address\n", __FUNCTION__);
  894. return ICP_OCF_DRV_STATUS_FAIL;
  895. }
  896. drvOpData->lacOpData.digestVerify = CPA_FALSE;
  897. break;
  898. default:
  899. DPRINTK("%s(): Crypto process error - algorithm not "
  900. "found \n", __FUNCTION__);
  901. return ICP_OCF_DRV_STATUS_FAIL;
  902. }
  903. /* Figure out what the IV is supposed to be */
  904. if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
  905. (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
  906. (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
  907. /*ARC4 doesn't use an IV */
  908. if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
  909. /* Explicit IV provided to OCF */
  910. drvOpData->lacOpData.pIv = crp_desc->crd_iv;
  911. } else {
  912. /* IV is not explicitly provided to OCF */
  913. /* Point the LAC OP Data IV pointer to our allocated
  914. storage location for this session. */
  915. drvOpData->lacOpData.pIv = drvOpData->ivData;
  916. if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
  917. ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
  918. /* Encrypting - need to create IV */
  919. randGenOpData.generateBits = CPA_TRUE;
  920. randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
  921. icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
  922. drvOpData->
  923. ivData,
  924. MAX_IV_LEN_IN_BYTES,
  925. &randData);
  926. if (CPA_STATUS_SUCCESS !=
  927. cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  928. NULL, NULL,
  929. &randGenOpData, &randData)) {
  930. DPRINTK("%s(): ERROR - Failed to"
  931. " generate"
  932. " Initialisation Vector\n",
  933. __FUNCTION__);
  934. return ICP_OCF_DRV_STATUS_FAIL;
  935. }
  936. crypto_copyback(drvOpData->crp->
  937. crp_flags,
  938. drvOpData->crp->crp_buf,
  939. crp_desc->crd_inject,
  940. drvOpData->lacOpData.
  941. ivLenInBytes,
  942. (caddr_t) (drvOpData->lacOpData.
  943. pIv));
  944. } else {
  945. /* Reading IV from buffer */
  946. crypto_copydata(drvOpData->crp->
  947. crp_flags,
  948. drvOpData->crp->crp_buf,
  949. crp_desc->crd_inject,
  950. drvOpData->lacOpData.
  951. ivLenInBytes,
  952. (caddr_t) (drvOpData->lacOpData.
  953. pIv));
  954. }
  955. }
  956. }
  957. return ICP_OCF_DRV_STATUS_SUCCESS;
  958. }
  959. /* Name : icp_ocfDrvDigestPointerFind
  960. *
  961. * Description : This function is used to find the memory address of where the
  962. * digest information shall be stored in. Input buffer types are an skbuff, iov
  963. * or flat buffer. The address is found using the buffer data start address and
  964. * an offset.
  965. *
  966. * Note: In the case of a linux skbuff, the digest address may exist within
  967. * a memory space linked to from the start buffer. These linked memory spaces
  968. * must be traversed by the data length offset in order to find the digest start
  969. * address. Whether there is enough space for the digest must also be checked.
  970. */
  971. uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
  972. struct cryptodesc * crp_desc)
  973. {
  974. int offsetInBytes = crp_desc->crd_inject;
  975. uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
  976. uint8_t *flat_buffer_base = NULL;
  977. int flat_buffer_length = 0;
  978. if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  979. return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
  980. offsetInBytes,
  981. digestSizeInBytes);
  982. } else {
  983. /* IOV or flat buffer */
  984. if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
  985. /*single IOV check has already been done */
  986. flat_buffer_base = ((struct uio *)
  987. (drvOpData->crp->crp_buf))->
  988. uio_iov[0].iov_base;
  989. flat_buffer_length = ((struct uio *)
  990. (drvOpData->crp->crp_buf))->
  991. uio_iov[0].iov_len;
  992. } else {
  993. flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
  994. flat_buffer_length = drvOpData->crp->crp_ilen;
  995. }
  996. if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
  997. DPRINTK("%s() Not enough space for Digest "
  998. "(IOV/Flat Buffer) \n", __FUNCTION__);
  999. return NULL;
  1000. } else {
  1001. return (uint8_t *) (flat_buffer_base + offsetInBytes);
  1002. }
  1003. }
  1004. DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
  1005. return NULL;
  1006. }