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

📄 z90main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	temp_buffer = (unsigned char *)we_p + sizeof(struct work_element) +		      sizeof(struct caller);	if (copy_from_user(temp_buffer, mex_p->inputdata,			   mex_p->inputdatalength) != 0)		return SEN_RELEASED;	function = PCI_FUNC_KEY_ENCRYPT;	switch (we_p->devtype) {	/* PCICA does everything with a simple RSA mod-expo operation */	case PCICA:		function = PCI_FUNC_KEY_ENCRYPT;		break;	/**	 * PCIXCC_MCL2 does all Mod-Expo form with a simple RSA mod-expo	 * operation, and all CRT forms with a PKCS-1.2 format decrypt.	 * PCIXCC_MCL3 and CEX2C do all Mod-Expo and CRT forms with a simple RSA	 * mod-expo operation	 */	case PCIXCC_MCL2:		if (we_p->funccode == ICARSAMODEXPO)			function = PCI_FUNC_KEY_ENCRYPT;		else			function = PCI_FUNC_KEY_DECRYPT;		break;	case PCIXCC_MCL3:	case CEX2C:		if (we_p->funccode == ICARSAMODEXPO)			function = PCI_FUNC_KEY_ENCRYPT;		else			function = PCI_FUNC_KEY_DECRYPT;		break;	/**	 * PCICC does everything as a PKCS-1.2 format request	 */	case PCICC:		/* PCICC cannot handle input that is is PKCS#1.1 padded */		if (is_PKCS11_padded(temp_buffer, mex_p->inputdatalength)) {			return SEN_NOT_AVAIL;		}		if (we_p->funccode == ICARSAMODEXPO) {			if (is_PKCS12_padded(temp_buffer,					     mex_p->inputdatalength))				function = PCI_FUNC_KEY_ENCRYPT;			else				function = PCI_FUNC_KEY_DECRYPT;		} else			/* all CRT forms are decrypts */			function = PCI_FUNC_KEY_DECRYPT;		break;	}	PDEBUG("function: %04x\n", function);	rv = build_caller(we_p, function);	PDEBUG("rv from build_caller = %d\n", rv);	return rv;}static inline intz90crypt_prepare(struct work_element *we_p, unsigned int funccode,		 const char __user *buffer){	int rv;	we_p->devindex = -1;	if (funccode == ICARSAMODEXPO)		we_p->buff_size = sizeof(struct ica_rsa_modexpo);	else		we_p->buff_size = sizeof(struct ica_rsa_modexpo_crt);	if (copy_from_user(we_p->buffer, buffer, we_p->buff_size))		return -EFAULT;	we_p->audit[0] |= FP_COPYFROM;	SET_RDWRMASK(we_p->status[0], STAT_WRITTEN);	we_p->funccode = funccode;	we_p->devtype = -1;	we_p->audit[0] |= FP_BUFFREQ;	rv = get_crypto_request_buffer(we_p);	switch (rv) {	case 0:		we_p->audit[0] |= FP_BUFFGOT;		break;	case SEN_USER_ERROR:		rv = -EINVAL;		break;	case SEN_QUEUE_FULL:		rv = 0;		break;	case SEN_RELEASED:		rv = -EFAULT;		break;	case REC_NO_RESPONSE:		rv = -ENODEV;		break;	case SEN_NOT_AVAIL:	case EGETBUFF:		rv = -EGETBUFF;		break;	default:		PRINTK("rv = %d\n", rv);		rv = -EGETBUFF;		break;	}	if (CHK_RDWRMASK(we_p->status[0]) == STAT_WRITTEN)		SET_RDWRMASK(we_p->status[0], STAT_DEFAULT);	return rv;}static inline voidpurge_work_element(struct work_element *we_p){	struct list_head *lptr;	spin_lock_irq(&queuespinlock);	list_for_each(lptr, &request_list) {		if (lptr == &we_p->liste) {			list_del_init(lptr);			requestq_count--;			break;		}	}	list_for_each(lptr, &pending_list) {		if (lptr == &we_p->liste) {			list_del_init(lptr);			pendingq_count--;			break;		}	}	spin_unlock_irq(&queuespinlock);}/** * Build the request and send it. */static inline intz90crypt_rsa(struct priv_data *private_data_p, pid_t pid,	     unsigned int cmd, unsigned long arg){	struct work_element *we_p;	int rv;	if ((rv = allocate_work_element(&we_p, private_data_p, pid))) {		PDEBUG("PID %d: allocate_work_element returned ENOMEM\n", pid);		return rv;	}	if ((rv = z90crypt_prepare(we_p, cmd, (const char __user *)arg)))		PDEBUG("PID %d: rv = %d from z90crypt_prepare\n", pid, rv);	if (!rv)		if ((rv = z90crypt_send(we_p, (const char *)arg)))			PDEBUG("PID %d: rv %d from z90crypt_send.\n", pid, rv);	if (!rv) {		we_p->audit[0] |= FP_ASLEEP;		wait_event(we_p->waitq, atomic_read(&we_p->alarmrung));		we_p->audit[0] |= FP_AWAKE;		rv = we_p->retcode;	}	if (!rv)		rv = z90crypt_process_results(we_p, (char __user *)arg);	if ((we_p->status[0] & STAT_FAILED)) {		switch (rv) {		/**		 * EINVAL *after* receive is almost always a padding error or		 * length error issued by a coprocessor (not an accelerator).		 * We convert this return value to -EGETBUFF which should		 * trigger a fallback to software.		 */		case -EINVAL:			if (we_p->devtype != PCICA)				rv = -EGETBUFF;			break;		case -ETIMEOUT:			if (z90crypt.mask.st_count > 0)				rv = -ERESTARTSYS; // retry with another			else				rv = -ENODEV; // no cards left		/* fall through to clean up request queue */		case -ERESTARTSYS:		case -ERELEASED:			switch (CHK_RDWRMASK(we_p->status[0])) {			case STAT_WRITTEN:				purge_work_element(we_p);				break;			case STAT_READPEND:			case STAT_NOWORK:			default:				break;			}			break;		default:			we_p->status[0] ^= STAT_FAILED;			break;		}	}	free_page((long)we_p);	return rv;}/** * This function is a little long, but it's really just one large switch * statement. */static longz90crypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){	struct priv_data *private_data_p = filp->private_data;	unsigned char *status;	unsigned char *qdepth;	unsigned int *reqcnt;	struct ica_z90_status *pstat;	int ret, i, loopLim, tempstat;	static int deprecated_msg_count1 = 0;	static int deprecated_msg_count2 = 0;	PDEBUG("filp %p (PID %d), cmd 0x%08X\n", filp, PID(), cmd);	PDEBUG("cmd 0x%08X: dir %s, size 0x%04X, type 0x%02X, nr 0x%02X\n",		cmd,		!_IOC_DIR(cmd) ? "NO"		: ((_IOC_DIR(cmd) == (_IOC_READ|_IOC_WRITE)) ? "RW"		: ((_IOC_DIR(cmd) == _IOC_READ) ? "RD"		: "WR")),		_IOC_SIZE(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd));	if (_IOC_TYPE(cmd) != Z90_IOCTL_MAGIC) {		PRINTK("cmd 0x%08X contains bad magic\n", cmd);		return -ENOTTY;	}	ret = 0;	switch (cmd) {	case ICARSAMODEXPO:	case ICARSACRT:		if (quiesce_z90crypt) {			ret = -EQUIESCE;			break;		}		ret = -ENODEV; // Default if no devices		loopLim = z90crypt.hdware_info->hdware_mask.st_count -			(z90crypt.hdware_info->hdware_mask.disabled_count +			 z90crypt.hdware_info->hdware_mask.user_disabled_count);		for (i = 0; i < loopLim; i++) {			ret = z90crypt_rsa(private_data_p, PID(), cmd, arg);			if (ret != -ERESTARTSYS)				break;		}		if (ret == -ERESTARTSYS)			ret = -ENODEV;		break;	case Z90STAT_TOTALCOUNT:		tempstat = get_status_totalcount();		if (copy_to_user((int __user *)arg, &tempstat,sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PCICACOUNT:		tempstat = get_status_PCICAcount();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PCICCCOUNT:		tempstat = get_status_PCICCcount();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PCIXCCMCL2COUNT:		tempstat = get_status_PCIXCCMCL2count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PCIXCCMCL3COUNT:		tempstat = get_status_PCIXCCMCL3count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_CEX2CCOUNT:		tempstat = get_status_CEX2Ccount();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_REQUESTQ_COUNT:		tempstat = get_status_requestq_count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PENDINGQ_COUNT:		tempstat = get_status_pendingq_count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_TOTALOPEN_COUNT:		tempstat = get_status_totalopen_count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_DOMAIN_INDEX:		tempstat = get_status_domain_index();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_STATUS_MASK:		status = kmalloc(Z90CRYPT_NUM_APS, GFP_KERNEL);		if (!status) {			PRINTK("kmalloc for status failed!\n");			ret = -ENOMEM;			break;		}		get_status_status_mask(status);		if (copy_to_user((char __user *) arg, status, Z90CRYPT_NUM_APS)									!= 0)			ret = -EFAULT;		kfree(status);		break;	case Z90STAT_QDEPTH_MASK:		qdepth = kmalloc(Z90CRYPT_NUM_APS, GFP_KERNEL);		if (!qdepth) {			PRINTK("kmalloc for qdepth failed!\n");			ret = -ENOMEM;			break;		}		get_status_qdepth_mask(qdepth);		if (copy_to_user((char __user *) arg, qdepth, Z90CRYPT_NUM_APS) != 0)			ret = -EFAULT;		kfree(qdepth);		break;	case Z90STAT_PERDEV_REQCNT:		reqcnt = kmalloc(sizeof(int) * Z90CRYPT_NUM_APS, GFP_KERNEL);		if (!reqcnt) {			PRINTK("kmalloc for reqcnt failed!\n");			ret = -ENOMEM;			break;		}		get_status_perdevice_reqcnt(reqcnt);		if (copy_to_user((char __user *) arg, reqcnt,				 Z90CRYPT_NUM_APS * sizeof(int)) != 0)			ret = -EFAULT;		kfree(reqcnt);		break;		/* THIS IS DEPRECATED.	USE THE NEW STATUS CALLS */	case ICAZ90STATUS:		if (deprecated_msg_count1 < 20) {			PRINTK("deprecated call to ioctl (ICAZ90STATUS)!\n");			deprecated_msg_count1++;			if (deprecated_msg_count1 == 20)				PRINTK("No longer issuing messages related to "				       "deprecated call to ICAZ90STATUS.\n");		}		pstat = kmalloc(sizeof(struct ica_z90_status), GFP_KERNEL);		if (!pstat) {			PRINTK("kmalloc for pstat failed!\n");			ret = -ENOMEM;			break;		}		pstat->totalcount	 = get_status_totalcount();		pstat->leedslitecount	 = get_status_PCICAcount();		pstat->leeds2count	 = get_status_PCICCcount();		pstat->requestqWaitCount = get_status_requestq_count();		pstat->pendingqWaitCount = get_status_pendingq_count();		pstat->totalOpenCount	 = get_status_totalopen_count();		pstat->cryptoDomain	 = get_status_domain_index();		get_status_status_mask(pstat->status);		get_status_qdepth_mask(pstat->qdepth);		if (copy_to_user((struct ica_z90_status __user *) arg, pstat,				 sizeof(struct ica_z90_status)) != 0)			ret = -EFAULT;		kfree(pstat);		break;		/* THIS IS DEPRECATED.	USE THE NEW STATUS CALLS */	case Z90STAT_PCIXCCCOUNT:		if (deprecated_msg_count2 < 20) {			PRINTK("deprecated ioctl (Z90STAT_PCIXCCCOUNT)!\n");			deprecated_msg_count2++;			if (deprecated_msg_count2 == 20)				PRINTK("No longer issuing messages about depre"				       "cated ioctl Z90STAT_PCIXCCCOUNT.\n");		}		tempstat = get_status_PCIXCCcount();		if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90QUIESCE:		if (current->euid != 0) {			PRINTK("QUIESCE fails: euid %d\n",			       current->euid);			ret = -EACCES;		} else {			PRINTK("QUIESCE device from PID %d\n", PID());			quiesce_z90crypt = 1;		}		break;	default:		/* user passed an invalid IOCTL number */		PDEBUG("cmd 0x%08X contains invalid ioctl code\n", cmd);		ret = -ENOTTY;		break;	}	return ret;}static inline intsprintcl(unsigned char *outaddr, unsigned char *addr, unsigned int len){	int hl, i;	hl = 0;	for (i = 0; i < len; i++)		hl += sprintf(outaddr+hl, "%01x", (unsigned int) addr[i]);	hl += sprintf(outaddr+hl, " ");	return hl;}static inline intsprintrw(unsigned char *outaddr, unsigned char *addr, unsigned int len){	int hl, inl, c, cx;	hl = sprintf(outaddr, "	   ");	inl = 0;	for (c = 0; c < (len / 16); c++) {		hl += sprintcl(outaddr+hl, addr+inl, 16);		inl += 16;	}	cx = len%16;	if (cx) {		hl += sprintcl(outaddr+hl, addr+inl, cx);		inl += cx;	}	hl += sprintf(outaddr+hl, "\n");	return hl;}static inline intsprinthx(unsigned char *title, unsigned char *outaddr,	 unsigned char *addr, unsigned int len){	int hl, inl, r, rx;	hl = sprintf(outaddr, "\n%s\n", title);	inl = 0;	for (r = 0; r < (len / 64); r++) {		hl += sprintrw(outaddr+hl, addr+inl, 64);		inl += 64;	}	rx = len % 64;	if (rx) {		hl += sprintrw(outaddr+hl, addr+inl, rx);		inl += rx;	}	hl += sprintf(outaddr+hl, "\n");	return hl;}static inline intsprinthx4(unsigned char *title, unsigned char *outaddr,	  unsigned int *array, unsigned int len){	int hl, r;	hl = sprintf(outaddr, "\n%s\n", title);	for (r = 0; r < len; r++) {		if ((r % 8) == 0)			hl += sprintf(outaddr+hl, "    ");		hl += sprintf(outaddr+hl, "%08X ", array[r]);		if ((r % 8) == 7)			hl += sprintf(outaddr+hl, "\n");	}	hl += sprintf(outaddr+hl, "\n");	return hl;}

⌨️ 快捷键说明

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