/* Name : icp_ocfDrvFreeLACSession * * Description : This attempts to deregister a LAC session. If it fails, the * deregistation retry function is called. */ int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid) { CpaCySymSessionCtx sessionToDeregister = NULL; struct icp_drvSessionData *sessionData = NULL; CpaStatus lacStatus = CPA_STATUS_SUCCESS; int retval = 0; sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid); if (NULL == sessionData) { EPRINTK("%s(): OCF Free session called with Null Session ID.\n", __FUNCTION__); return EINVAL; } sessionToDeregister = sessionData->sessHandle; if ((ICP_SESSION_INITIALISED != sessionData->inUse) && (ICP_SESSION_RUNNING != sessionData->inUse) && (ICP_SESSION_DEREGISTERED != sessionData->inUse)) { DPRINTK("%s() Session not initialised.\n", __FUNCTION__); return EINVAL; } if (ICP_SESSION_RUNNING == sessionData->inUse) { lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE, sessionToDeregister); if (CPA_STATUS_RETRY == lacStatus) { if (ICP_OCF_DRV_STATUS_SUCCESS != icp_ocfDrvDeregRetry(&sessionToDeregister)) { /* the retry function increments the dereg failed count */ DPRINTK("%s(): LAC failed to deregister the " "session. (localSessionId= %p)\n", __FUNCTION__, sessionToDeregister); retval = EPERM; } } else if (CPA_STATUS_SUCCESS != lacStatus) { DPRINTK("%s(): LAC failed to deregister the session. " "localSessionId= %p, lacStatus = %d\n", __FUNCTION__, sessionToDeregister, lacStatus); icp_atomic_inc(&lac_session_failed_dereg_count); retval = EPERM; } } else { DPRINTK("%s() Session not registered with LAC.\n", __FUNCTION__); } icp_ocfDrvFreeOCFSession(sessionData); return retval; }
/* * Free a session. */ static int null_freesession(device_t arg, u_int64_t tid) { u_int32_t sid = CRYPTO_SESID2LID(tid); dprintk("%s()\n", __FUNCTION__); if (sid > null_sesnum) { dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); return EINVAL; } /* Silently accept and return */ if (sid == 0) return 0; return 0; }
/* * Deallocate a session. * XXX this routine should run a zero'd mac/encrypt key into context ram. * XXX to blow away any keys already stored there. */ static int xlp_rsa_freesession(device_t dev, u_int64_t tid) { struct xlp_rsa_softc *sc = device_get_softc(dev); int session; u_int32_t sid = CRYPTO_SESID2LID(tid); if (sc == NULL) return (EINVAL); session = XLP_RSA_SESSION(sid); if (session >= sc->sc_nsessions) return (EINVAL); sc->sc_sessions[session].hs_used = 0; return (0); }
/* * Deallocate a session. * XXX this routine should run a zero'd mac/encrypt key into context ram. * XXX to blow away any keys already stored there. */ static int xlr_sec_freesession(void *arg, u_int64_t tid) { struct xlr_sec_softc *sc = arg; int session; u_int32_t sid = CRYPTO_SESID2LID(tid); if (sc == NULL) return (EINVAL); session = XLR_SEC_SESSION(sid); if (session >= sc->sc_nsessions) return (EINVAL); sc->sc_sessions[session].hs_used = 0; return (0); }
/* * Free a session. */ static int cesa_ocf_freesession(device_t dev, u_int64_t tid) { struct cesa_ocf_data *cesa_ocf_cur_ses; u_int32_t sid = CRYPTO_SESID2LID(tid); //unsigned long flags; dprintk("%s() %d \n", __FUNCTION__, sid); if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) { printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid); return(EINVAL); } /* Silently accept and return */ if (sid == 0) return(0); /* release session from HAL */ cesa_ocf_cur_ses = cesa_ocf_sessions[sid]; if (cesa_ocf_cur_ses->sid_encrypt != -1) { mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt); } if (cesa_ocf_cur_ses->sid_decrypt != -1) { mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt); } if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) { mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt); } if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) { mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt); } if (cesa_ocf_cur_ses->frag_wa_auth != -1) { mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth); } kfree(cesa_ocf_cur_ses); cesa_ocf_sessions[sid] = NULL; return 0; }
/* * Free a session. */ static int cryptocteon_freesession(device_t dev, u_int64_t tid) { struct cryptocteon_softc *sc; u_int32_t sid = CRYPTO_SESID2LID(tid); sc = device_get_softc(dev); if (sc == NULL) return (EINVAL); if (sid > sc->sc_sesnum || sc->sc_sessions == NULL || sc->sc_sessions[sid] == NULL) return (EINVAL); /* Silently accept and return */ if (sid == 0) return(0); if (sc->sc_sessions[sid]) free(sc->sc_sessions[sid], M_DEVBUF); sc->sc_sessions[sid] = NULL; return 0; }
/* Name : icp_ocfDrvSymProcess * * Description : This function will map symmetric functionality calls from OCF * to the LAC API. It will also allocate memory to store the session context. * * Notes: If it is the first perform call for a given session, then a LAC * session is registered. After the session is registered, no checks as * to whether session paramaters have changed (e.g. alg chain order) are * done. */ int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint) { struct icp_drvSessionData *sessionData = NULL; struct icp_drvOpData *drvOpData = NULL; CpaStatus lacStatus = CPA_STATUS_SUCCESS; Cpa32U sessionCtxSizeInBytes = 0; if (NULL == crp) { DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n", __FUNCTION__); return EINVAL; } if (NULL == crp->crp_desc) { DPRINTK("%s(): Invalid input parameters, no crp_desc attached " "to crp\n", __FUNCTION__); crp->crp_etype = EINVAL; return EINVAL; } if (NULL == crp->crp_buf) { DPRINTK("%s(): Invalid input parameters, no buffer attached " "to crp\n", __FUNCTION__); crp->crp_etype = EINVAL; return EINVAL; } if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) { crp->crp_etype = EFAULT; return EFAULT; } sessionData = (struct icp_drvSessionData *) (CRYPTO_SESID2LID(crp->crp_sid)); if (NULL == sessionData) { DPRINTK("%s(): Invalid input parameters, Null Session ID \n", __FUNCTION__); crp->crp_etype = EINVAL; return EINVAL; } /*If we get a request against a deregisted session, cancel operation*/ if (ICP_SESSION_DEREGISTERED == sessionData->inUse) { DPRINTK("%s(): Session ID %d was deregistered \n", __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid))); crp->crp_etype = EFAULT; return EFAULT; } /*If none of the session states are set, then the session structure was either not initialised properly or we are reading from a freed memory area (possible due to OCF batch mode not removing queued requests against deregistered sessions*/ if (ICP_SESSION_INITIALISED != sessionData->inUse && ICP_SESSION_RUNNING != sessionData->inUse) { DPRINTK("%s(): Session - ID %d - not properly initialised or " "memory freed back to the kernel \n", __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid))); crp->crp_etype = EINVAL; return EINVAL; } /*For the below checks, remember error checking is already done in LAC. We're not validating inputs subsequent to registration */ if (sessionData->inUse == ICP_SESSION_INITIALISED) { DPRINTK("%s(): Initialising session\n", __FUNCTION__); if (NULL != crp->crp_desc->crd_next) { if (ICP_OCF_DRV_ALG_CIPHER == icp_ocfDrvAlgCheck(crp->crp_desc)) { sessionData->lacSessCtx.algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) { sessionData->lacSessCtx.cipherSetupData. cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT; } else { sessionData->lacSessCtx.cipherSetupData. cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; } } else { sessionData->lacSessCtx.algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER; if (crp->crp_desc->crd_next->crd_flags & CRD_F_ENCRYPT) { sessionData->lacSessCtx.cipherSetupData. cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT; } else { sessionData->lacSessCtx.cipherSetupData. cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; } } } else if (ICP_OCF_DRV_ALG_CIPHER == icp_ocfDrvAlgCheck(crp->crp_desc)) { if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) { sessionData->lacSessCtx.cipherSetupData. cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT; } else { sessionData->lacSessCtx.cipherSetupData. cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; } } /*No action required for standalone Auth here */ /* Allocate memory for SymSessionCtx before the Session Registration */ lacStatus = cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE, &(sessionData->lacSessCtx), &sessionCtxSizeInBytes); if (CPA_STATUS_SUCCESS != lacStatus) { EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n", __FUNCTION__, lacStatus); crp->crp_etype = EINVAL; return EINVAL; } sessionData->sessHandle = icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT); if (NULL == sessionData->sessHandle) { EPRINTK ("%s(): Failed to get memory for SymSessionCtx\n", __FUNCTION__); crp->crp_etype = ENOMEM; return ENOMEM; } lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE, icp_ocfDrvSymCallBack, &(sessionData->lacSessCtx), sessionData->sessHandle); if (CPA_STATUS_SUCCESS != lacStatus) { EPRINTK("%s(): cpaCySymInitSession failed -%d \n", __FUNCTION__, lacStatus); crp->crp_etype = EFAULT; return EFAULT; } sessionData->inUse = ICP_SESSION_RUNNING; } drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT); if (NULL == drvOpData) { EPRINTK("%s():Failed to get memory for drvOpData\n", __FUNCTION__); crp->crp_etype = ENOMEM; return ENOMEM; } drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle; drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData. digestResultLenInBytes; drvOpData->crp = crp; /* Set the default buffer list array memory allocation */ drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray; drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS; if (ICP_OCF_DRV_STATUS_SUCCESS != icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) { crp->crp_etype = EINVAL; goto err; } if (drvOpData->crp->crp_desc->crd_next != NULL) { if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp-> crp_desc->crd_next)) { crp->crp_etype = EINVAL; goto err; } } /* * Allocate buffer list array memory if the data fragment is more than * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not * calculated already */ if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) { if (NULL == drvOpData->lacOpData.pDigestResult) { drvOpData->numBufferListArray = icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *) crp->crp_buf); } if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < drvOpData->numBufferListArray) { DPRINTK("%s() numBufferListArray more than default\n", __FUNCTION__); drvOpData->srcBuffer.pBuffers = NULL; drvOpData->srcBuffer.pBuffers = icp_kmalloc(drvOpData->numBufferListArray * sizeof(CpaFlatBuffer), ICP_M_NOWAIT); if (NULL == drvOpData->srcBuffer.pBuffers) { EPRINTK("%s() Failed to get memory for " "pBuffers\n", __FUNCTION__); ICP_CACHE_FREE(drvOpData_zone, drvOpData); crp->crp_etype = ENOMEM; return ENOMEM; } } } /* * Check the type of buffer structure we got and convert it into * CpaBufferList format. */ if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) { if (ICP_OCF_DRV_STATUS_SUCCESS != icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *) crp->crp_buf, &(drvOpData->srcBuffer))) { EPRINTK("%s():Failed to translate from packet buffer " "to bufferlist\n", __FUNCTION__); crp->crp_etype = EINVAL; goto err; } drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF; } else if (crp->crp_flags & CRYPTO_F_IOV) { /* OCF only supports IOV of one entry. */ if (NUM_IOV_SUPPORTED == ((struct uio *)(crp->crp_buf))->uio_iovcnt) { icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp-> crp_buf))-> uio_iov[0].iov_base, ((struct uio *)(crp-> crp_buf))-> uio_iov[0].iov_len, &(drvOpData-> srcBuffer)); drvOpData->bufferType = CRYPTO_F_IOV; } else { DPRINTK("%s():Unable to handle IOVs with lengths of " "greater than one!\n", __FUNCTION__); crp->crp_etype = EINVAL; goto err; } } else { icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf, crp->crp_ilen, &(drvOpData->srcBuffer)); drvOpData->bufferType = CRYPTO_BUF_CONTIG; } /* Allocate srcBuffer's private meta data */ if (ICP_OCF_DRV_STATUS_SUCCESS != icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) { EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__); memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData)); crp->crp_etype = EINVAL; goto err; } /* Perform "in-place" crypto operation */ lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE, (void *)drvOpData, &(drvOpData->lacOpData), &(drvOpData->srcBuffer), &(drvOpData->srcBuffer), &(drvOpData->verifyResult)); if (CPA_STATUS_RETRY == lacStatus) { DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n", __FUNCTION__, lacStatus); memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData)); crp->crp_etype = ERESTART; goto err; } if (CPA_STATUS_SUCCESS != lacStatus) { EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n", __FUNCTION__, lacStatus); memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData)); crp->crp_etype = EINVAL; goto err; } return 0; //OCF success status value err: if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) { icp_kfree(drvOpData->srcBuffer.pBuffers); } icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer)); ICP_CACHE_FREE(drvOpData_zone, drvOpData); return crp->crp_etype; }