⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hifn7751.c

📁 linux下基于加密芯片的加密设备
💻 C
📖 第 1 页 / 共 5 页
字号:
			hifn_callback(sc, cmd, macbuf);			hifnstats.hst_opackets++;			u--;		}		if (++i == (HIFN_D_RES_RSIZE + 1))			i = 0;	}	dma->resk = i; dma->resu = u;	i = dma->srck; u = dma->srcu;	while (u != 0) {		if (i == HIFN_D_SRC_RSIZE)			i = 0;		HIFN_SRCR_SYNC(sc, i,		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);		if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {			HIFN_SRCR_SYNC(sc, i,			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			break;		}		i++, u--;	}	dma->srck = i; dma->srcu = u;	i = dma->cmdk; u = dma->cmdu;	while (u != 0) {		HIFN_CMDR_SYNC(sc, i,		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);		if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {			HIFN_CMDR_SYNC(sc, i,			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			break;		}		if (i != HIFN_D_CMD_RSIZE) {			u--;			HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);		}		if (++i == (HIFN_D_CMD_RSIZE + 1))			i = 0;	}	dma->cmdk = i; dma->cmdu = u;	HIFN_UNLOCK(sc);	if (sc->sc_needwakeup) {		/* XXX check high watermark */		int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);#ifdef HIFN_DEBUG		if (hifn_debug)			device_printf(sc->sc_dev,				"wakeup crypto (%x) u %d/%d/%d/%d\n",				sc->sc_needwakeup,				dma->cmdu, dma->srcu, dma->dstu, dma->resu);#endif		sc->sc_needwakeup &= ~wakeup;		crypto_unblock(sc->sc_cid, wakeup);	}	return IRQ_HANDLED;}/* * Allocate a new 'session' and return an encoded session id.  'sidp' * contains our registration id, and should contain an encoded session * id on successful allocation. */static inthifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri){	struct cryptoini *c;	struct hifn_softc *sc = arg;	int mac = 0, cry = 0, sesn;	struct hifn_session *ses = NULL;	DPRINTF("%s()\n", __FUNCTION__);	KASSERT(sc != NULL, ("hifn_newsession: null softc"));	if (sidp == NULL || cri == NULL || sc == NULL)		return (EINVAL);	if (sc->sc_sessions == NULL) {		ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),				GFP_ATOMIC);		if (ses == NULL)			return (ENOMEM);		sesn = 0;		sc->sc_nsessions = 1;	} else {		for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {			if (!sc->sc_sessions[sesn].hs_used) {				ses = &sc->sc_sessions[sesn];				break;			}		}		if (ses == NULL) {			sesn = sc->sc_nsessions;			ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),					GFP_ATOMIC);			if (ses == NULL)				return (ENOMEM);			bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));			bzero(sc->sc_sessions, sesn * sizeof(*ses));			kfree(sc->sc_sessions);			sc->sc_sessions = ses;			ses = &sc->sc_sessions[sesn];			sc->sc_nsessions++;		}	}	bzero(ses, sizeof(*ses));	ses->hs_used = 1;	for (c = cri; c != NULL; c = c->cri_next) {		switch (c->cri_alg) {		case CRYPTO_MD5:		case CRYPTO_SHA1:		case CRYPTO_MD5_HMAC:		case CRYPTO_SHA1_HMAC:			if (mac)				return (EINVAL);			mac = 1;			break;		case CRYPTO_DES_CBC:		case CRYPTO_3DES_CBC:		case CRYPTO_AES_CBC:			/* XXX this may read fewer, does it matter? */			read_random(ses->hs_iv,				c->cri_alg == CRYPTO_AES_CBC ?					HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);			/*FALLTHROUGH*/		case CRYPTO_ARC4:			if (cry)				return (EINVAL);			cry = 1;			break;		default:			return (EINVAL);		}	}	if (mac == 0 && cry == 0)		return (EINVAL);	*sidp = HIFN_SID(sc->sc_num, sesn);	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 inthifn_freesession(void *arg, u_int64_t tid){	struct hifn_softc *sc = arg;	int session;	u_int32_t sid = CRYPTO_SESID2LID(tid);	DPRINTF("%s()\n", __FUNCTION__);	KASSERT(sc != NULL, ("hifn_freesession: null softc"));	if (sc == NULL)		return (EINVAL);	session = HIFN_SESSION(sid);	if (session >= sc->sc_nsessions)		return (EINVAL);	bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));	return (0);}static inthifn_process(void *arg, struct cryptop *crp, int hint){	struct hifn_softc *sc = arg;	struct hifn_command *cmd = NULL;	int session, err, ivlen;	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;	DPRINTF("%s()\n", __FUNCTION__);	if (crp == NULL || crp->crp_callback == NULL) {		hifnstats.hst_invalid++;		return (EINVAL);	}	session = HIFN_SESSION(crp->crp_sid);	if (sc == NULL || session >= sc->sc_nsessions) {		err = EINVAL;		goto errout;	}	cmd = kmalloc(sizeof(struct hifn_command), GFP_KERNEL);	if (cmd == NULL) {		hifnstats.hst_nomem++;		err = ENOMEM;		goto errout;	}	memset(cmd, 0, sizeof(*cmd));	if (crp->crp_flags & CRYPTO_F_IMBUF) {#if NOTYET		cmd->src_m = (struct mbuf *)crp->crp_buf;		cmd->dst_m = (struct mbuf *)crp->crp_buf;#else		device_printf(sc->sc_dev, "CRYPTO_F_IMBUF no implemented\n");#endif	} else if (crp->crp_flags & CRYPTO_F_IOV) {		cmd->src_io = (struct uio *)crp->crp_buf;		cmd->dst_io = (struct uio *)crp->crp_buf;	} else {		err = EINVAL;		goto errout;	/* XXX we don't handle contiguous buffers! */	}	crd1 = crp->crp_desc;	if (crd1 == NULL) {		err = EINVAL;		goto errout;	}	crd2 = crd1->crd_next;	if (crd2 == NULL) {		if (crd1->crd_alg == CRYPTO_MD5_HMAC ||		    crd1->crd_alg == CRYPTO_SHA1_HMAC ||		    crd1->crd_alg == CRYPTO_SHA1 ||		    crd1->crd_alg == CRYPTO_MD5) {			maccrd = crd1;			enccrd = NULL;		} else if (crd1->crd_alg == CRYPTO_DES_CBC ||		    crd1->crd_alg == CRYPTO_3DES_CBC ||		    crd1->crd_alg == CRYPTO_AES_CBC ||		    crd1->crd_alg == CRYPTO_ARC4) {			if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)				cmd->base_masks |= HIFN_BASE_CMD_DECODE;			maccrd = NULL;			enccrd = crd1;		} else {			err = EINVAL;			goto errout;		}	} else {		if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||                     crd1->crd_alg == CRYPTO_SHA1_HMAC ||                     crd1->crd_alg == CRYPTO_MD5 ||                     crd1->crd_alg == CRYPTO_SHA1) &&		    (crd2->crd_alg == CRYPTO_DES_CBC ||		     crd2->crd_alg == CRYPTO_3DES_CBC ||		     crd2->crd_alg == CRYPTO_AES_CBC ||		     crd2->crd_alg == CRYPTO_ARC4) &&		    ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {			cmd->base_masks = HIFN_BASE_CMD_DECODE;			maccrd = crd1;			enccrd = crd2;		} else if ((crd1->crd_alg == CRYPTO_DES_CBC ||		     crd1->crd_alg == CRYPTO_ARC4 ||		     crd1->crd_alg == CRYPTO_3DES_CBC ||		     crd1->crd_alg == CRYPTO_AES_CBC) &&		    (crd2->crd_alg == CRYPTO_MD5_HMAC ||                     crd2->crd_alg == CRYPTO_SHA1_HMAC ||                     crd2->crd_alg == CRYPTO_MD5 ||                     crd2->crd_alg == CRYPTO_SHA1) &&		    (crd1->crd_flags & CRD_F_ENCRYPT)) {			enccrd = crd1;			maccrd = crd2;		} else {			/*			 * We cannot order the 7751 as requested			 */			err = EINVAL;			goto errout;		}	}	if (enccrd) {		cmd->enccrd = enccrd;		cmd->base_masks |= HIFN_BASE_CMD_CRYPT;		switch (enccrd->crd_alg) {		case CRYPTO_ARC4:			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;			break;		case CRYPTO_DES_CBC:			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |			    HIFN_CRYPT_CMD_MODE_CBC |			    HIFN_CRYPT_CMD_NEW_IV;			break;		case CRYPTO_3DES_CBC:			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |			    HIFN_CRYPT_CMD_MODE_CBC |			    HIFN_CRYPT_CMD_NEW_IV;			break;		case CRYPTO_AES_CBC:			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |			    HIFN_CRYPT_CMD_MODE_CBC |			    HIFN_CRYPT_CMD_NEW_IV;			break;		default:			err = EINVAL;			goto errout;		}		if (enccrd->crd_alg != CRYPTO_ARC4) {			ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?				HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);			if (enccrd->crd_flags & CRD_F_ENCRYPT) {				if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)					bcopy(enccrd->crd_iv, cmd->iv, ivlen);				else					bcopy(sc->sc_sessions[session].hs_iv,					    cmd->iv, ivlen);				if ((enccrd->crd_flags & CRD_F_IV_PRESENT)				    == 0) {					if (crp->crp_flags & CRYPTO_F_IMBUF)#if NOTYET						m_copyback(cmd->src_m,						    enccrd->crd_inject,						    ivlen, cmd->iv);#else						device_printf(sc->sc_dev,								"CRYPTO_F_IMBUF no implemented\n");#endif					else if (crp->crp_flags & CRYPTO_F_IOV)						cuio_copyback(cmd->src_io,						    enccrd->crd_inject,						    ivlen, cmd->iv);				}			} else {				if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)					bcopy(enccrd->crd_iv, cmd->iv, ivlen);				else if (crp->crp_flags & CRYPTO_F_IMBUF)#if NOTYET					m_copydata(cmd->src_m,					    enccrd->crd_inject, ivlen, cmd->iv);#else					device_printf(sc->sc_dev,							"CRYPTO_F_IMBUF no implemented\n");#endif				else if (crp->crp_flags & CRYPTO_F_IOV)					cuio_copydata(cmd->src_io,					    enccrd->crd_inject, ivlen, cmd->iv);			}		}		if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)			cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;		cmd->ck = enccrd->crd_key;		cmd->cklen = enccrd->crd_klen >> 3;		cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;		/* 		 * Need to specify the size for the AES key in the masks.		 */		if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==		    HIFN_CRYPT_CMD_ALG_AES) {			switch (cmd->cklen) {			case 16:				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;				break;			case 24:				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;				break;			case 32:				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;				break;			default:				err = EINVAL;				goto errout;			}		}	}	if (maccrd) {		cmd->maccrd = maccrd;		cmd->base_masks |= HIFN_BASE_CMD_MAC;		switch (maccrd->crd_alg) {		case CRYPTO_MD5:			cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |			    HIFN_MAC_CMD_POS_IPSEC;                       break;		case CRYPTO_MD5_HMAC:			cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |			    HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;			break;		case CRYPTO_SHA1:			cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |			    HIFN_MAC_CMD_POS_IPSEC;			break;		case CRYPTO_SHA1_HMAC:			cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |			    HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;			break;		}		if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||		     maccrd->crd_alg == CRYPTO_MD5_HMAC) {			cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;			bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);			bzero(cmd->mac + (maccrd->crd_klen >> 3),			    HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));		}	}	cmd->crp = crp;	cmd->session_num = session;	cmd->softc = sc;	err = hifn_crypto(sc, cmd, crp, hint);	if (!err) {		return 0;	} else if (err == ERESTART) {		/*		 * There weren't enough resources to dispatch the request		 * to the part.  Notify the caller so they'll requeue this		 * request and resubmit it again soon.		 */#ifdef HIFN_DEBUG		if (hifn_debug)			device_printf(sc->sc_dev, "requeue request\n");#endif		kfree(cmd);		sc->sc_needwakeup |= CRYPTO_SYMQ;		return (err);	}errout:	if (cmd != NULL)		kfree(cmd);	if (err == EINVAL)		hifnstats.hst_invalid++;	else		hifnstats.hst_nomem++;	crp->crp_etype = err;	crypto_done(crp);	return (err);}static voidhifn_abort(struct hifn_softc *sc){	struct hifn_dma *dma = sc->sc_dma;	struct hifn_command *cmd;	struct cryptop *crp;	int i, u;	DPRINTF("%s()\n", __FUNCTION__);	i = dma->resk; u = dma->resu;	while (u != 0) {		cmd = dma->hifn_commands[i];		KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));		dma->hifn_commands[i] = NULL;		crp = cmd->crp;		if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {			/* Salvage what we can. */			u_int8_t *macbuf;			if (cmd->base_masks & HIFN_BASE_CMD_MAC) {				macbuf = dma->result_bufs[i];				macbuf += 12;			} else				macbuf = NULL;			hifnstats.hst_opackets++;			hifn_callback(sc, cmd, macbuf);		} else {#if 0			if (cmd->src_map == cmd->dst_map) {				bus_dmamap_sync(sc->sc_dmat, cmd->src_map,				    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);			} else {				bus_dmamap_sync(sc->sc_dmat, cmd->src_map,				    BUS_DMASYNC_POSTWRITE);				bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,				    BUS_DMASYNC_POSTREAD);			}#endif#ifdef NOTYET			if (cmd->src_m != cmd->dst_m) {				m_freem(cmd->s

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -