예제 #1
0
/* 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;

}
예제 #2
0
/*
 * 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;
}
예제 #3
0
파일: nlmrsa.c 프로젝트: JabirTech/Source
/*
 * 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);
}
예제 #4
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);
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
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;
}