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

📄 z90main.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	init_work_element(we_p, priv_data_p, pid);	*we_pp = we_p;	return 0;}static inline voidremove_device(struct device *device_p){	if (!device_p || device_p->disabled != 0)		return;	device_p->disabled = 1;	z90crypt.hdware_info->type_mask[device_p->dev_type].disabled_count++;	z90crypt.hdware_info->hdware_mask.disabled_count++;}static inline intselect_device_type(int *dev_type_p){	struct status *stat;	if ((*dev_type_p != PCICC) && (*dev_type_p != PCICA) &&	    (*dev_type_p != PCIXCC) && (*dev_type_p != ANYDEV))		return -1;	if (*dev_type_p != ANYDEV) {		stat = &z90crypt.hdware_info->type_mask[*dev_type_p];		if (stat->st_count >		    stat->disabled_count + stat->user_disabled_count)			return 0;		return -1;	}	stat = &z90crypt.hdware_info->type_mask[PCICA];	if (stat->st_count > stat->disabled_count + stat->user_disabled_count) {		*dev_type_p = PCICA;		return 0;	}	stat = &z90crypt.hdware_info->type_mask[PCIXCC];	if (stat->st_count > stat->disabled_count + stat->user_disabled_count) {		*dev_type_p = PCIXCC;		return 0;	}	stat = &z90crypt.hdware_info->type_mask[PCICC];	if (stat->st_count > stat->disabled_count + stat->user_disabled_count) {		*dev_type_p = PCICC;		return 0;	}	return -1;}/** * Try the selected number, then the selected type (can be ANYDEV) */static inline intselect_device(int *dev_type_p, int *device_nr_p){	int i, indx, devTp, low_count, low_indx;	struct device_x *index_p;	struct device *dev_ptr;	PDEBUG("device type = %d, index = %d\n", *dev_type_p, *device_nr_p);	if ((*device_nr_p >= 0) && (*device_nr_p < Z90CRYPT_NUM_DEVS)) {		PDEBUG("trying index = %d\n", *device_nr_p);		dev_ptr = z90crypt.device_p[*device_nr_p];		if (dev_ptr &&		    dev_ptr->dev_stat != DEV_GONE &&		    dev_ptr->disabled == 0 &&		    dev_ptr->user_disabled == 0) {			PDEBUG("selected by number, index = %d\n",			       *device_nr_p);			*dev_type_p = dev_ptr->dev_type;			return *device_nr_p;		}	}	*device_nr_p = -1;	PDEBUG("trying type = %d\n", *dev_type_p);	devTp = *dev_type_p;	if (select_device_type(&devTp) == -1) {		PDEBUG("failed to select by type\n");		return -1;	}	PDEBUG("selected type = %d\n", devTp);	index_p = &z90crypt.hdware_info->type_x_addr[devTp];	low_count = 0x0000FFFF;	low_indx = -1;	for (i = 0; i < z90crypt.hdware_info->type_mask[devTp].st_count; i++) {		indx = index_p->device_index[i];		dev_ptr = z90crypt.device_p[indx];		if (dev_ptr &&		    dev_ptr->dev_stat != DEV_GONE &&		    dev_ptr->disabled == 0 &&		    dev_ptr->user_disabled == 0 &&		    devTp == dev_ptr->dev_type &&		    low_count > dev_ptr->dev_caller_count) {			low_count = dev_ptr->dev_caller_count;			low_indx = indx;		}	}	*device_nr_p = low_indx;	return low_indx;}static inline intsend_to_crypto_device(struct work_element *we_p){	struct caller *caller_p;	struct device *device_p;	int dev_nr;	if (!we_p->requestptr)		return SEN_FATAL_ERROR;	caller_p = (struct caller *)we_p->requestptr;	dev_nr = we_p->devindex;	if (select_device(&we_p->devtype, &dev_nr) == -1) {		if (z90crypt.hdware_info->hdware_mask.st_count != 0)			return SEN_RETRY;		else			return SEN_NOT_AVAIL;	}	we_p->devindex = dev_nr;	device_p = z90crypt.device_p[dev_nr];	if (!device_p)		return SEN_NOT_AVAIL;	if (device_p->dev_type != we_p->devtype)		return SEN_RETRY;	if (device_p->dev_caller_count >= device_p->dev_q_depth)		return SEN_QUEUE_FULL;	PDEBUG("device number prior to send: %d\n", dev_nr);	switch (send_to_AP(dev_nr, z90crypt.cdx,			   caller_p->caller_dev_dep_req_l,			   caller_p->caller_dev_dep_req_p)) {	case DEV_SEN_EXCEPTION:		PRINTKC("Exception during send to device %d\n", dev_nr);		z90crypt.terminating = 1;		return SEN_FATAL_ERROR;	case DEV_GONE:		PRINTK("Device %d not available\n", dev_nr);		remove_device(device_p);		return SEN_NOT_AVAIL;	case DEV_EMPTY:		return SEN_NOT_AVAIL;	case DEV_NO_WORK:		return SEN_FATAL_ERROR;	case DEV_BAD_MESSAGE:		return SEN_USER_ERROR;	case DEV_QUEUE_FULL:		return SEN_QUEUE_FULL;	default:	case DEV_ONLINE:		break;	}	list_add_tail(&(caller_p->caller_liste), &(device_p->dev_caller_list));	device_p->dev_caller_count++;	return 0;}/** * Send puts the user's work on one of two queues: *   the pending queue if the send was successful *   the request queue if the send failed because device full or busy */static inline intz90crypt_send(struct work_element *we_p, const char *buf){	int rv;	PDEBUG("PID %d\n", PID());	if (CHK_RDWRMASK(we_p->status[0]) != STAT_NOWORK) {		PDEBUG("PID %d tried to send more work but has outstanding "		       "work.\n", PID());		return -EWORKPEND;	}	we_p->devindex = -1; // Reset device number	spin_lock_irq(&queuespinlock);	rv = send_to_crypto_device(we_p);	switch (rv) {	case 0:		we_p->requestsent = jiffies;		we_p->audit[0] |= FP_SENT;		list_add_tail(&we_p->liste, &pending_list);		++pendingq_count;		we_p->audit[0] |= FP_PENDING;		break;	case SEN_BUSY:	case SEN_QUEUE_FULL:		rv = 0;		we_p->devindex = -1; // any device will do		we_p->requestsent = jiffies;		list_add_tail(&we_p->liste, &request_list);		++requestq_count;		we_p->audit[0] |= FP_REQUEST;		break;	case SEN_RETRY:		rv = -ERESTARTSYS;		break;	case SEN_NOT_AVAIL:		PRINTK("*** No devices available.\n");		rv = we_p->retcode = -ENODEV;		we_p->status[0] |= STAT_FAILED;		break;	case REC_OPERAND_INV:	case REC_OPERAND_SIZE:	case REC_EVEN_MOD:	case REC_INVALID_PAD:		rv = we_p->retcode = -EINVAL;		we_p->status[0] |= STAT_FAILED;		break;	default:		we_p->retcode = rv;		we_p->status[0] |= STAT_FAILED;		break;	}	if (rv != -ERESTARTSYS)		SET_RDWRMASK(we_p->status[0], STAT_WRITTEN);	spin_unlock_irq(&queuespinlock);	if (rv == 0)		tasklet_schedule(&reader_tasklet);	return rv;}/** * process_results copies the user's work from kernel space. */static inline intz90crypt_process_results(struct work_element *we_p, char __user *buf){	int rv;	PDEBUG("we_p %p (PID %d)\n", we_p, PID());	LONG2DEVPTR(we_p->devindex)->dev_total_req_cnt++;	SET_RDWRMASK(we_p->status[0], STAT_READPEND);	rv = 0;	if (!we_p->buffer) {		PRINTK("we_p %p PID %d in STAT_READPEND: buffer NULL.\n",			we_p, PID());		rv = -ENOBUFF;	}	if (!rv)		if ((rv = copy_to_user(buf, we_p->buffer, we_p->buff_size))) {			PDEBUG("copy_to_user failed: rv = %d\n", rv);			rv = -EFAULT;		}	if (!rv)		rv = we_p->retcode;	if (!rv)		if (we_p->resp_buff_size		    &&	copy_to_user(we_p->resp_addr, we_p->resp_buff,				     we_p->resp_buff_size))			rv = -EFAULT;	SET_RDWRMASK(we_p->status[0], STAT_NOWORK);	return rv;}static unsigned char NULL_psmid[8] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};/** * MIN_MOD_SIZE is a PCICC and PCIXCC limit. * MAX_PCICC_MOD_SIZE is a hard limit for the PCICC. * MAX_MOD_SIZE is a hard limit for the PCIXCC and PCICA. */#define MIN_MOD_SIZE 64#define MAX_PCICC_MOD_SIZE 128#define MAX_MOD_SIZE 256/** * Used in device configuration functions */#define MAX_RESET 90/** * This is used only for PCICC support */static inline intis_PKCS11_padded(unsigned char *buffer, int length){	int i;	if ((buffer[0] != 0x00) || (buffer[1] != 0x01))		return 0;	for (i = 2; i < length; i++)		if (buffer[i] != 0xFF)			break;	if ((i < 10) || (i == length))		return 0;	if (buffer[i] != 0x00)		return 0;	return 1;}/** * This is used only for PCICC support */static inline intis_PKCS12_padded(unsigned char *buffer, int length){	int i;	if ((buffer[0] != 0x00) || (buffer[1] != 0x02))		return 0;	for (i = 2; i < length; i++)		if (buffer[i] == 0x00)			break;	if ((i < 10) || (i == length))		return 0;	if (buffer[i] != 0x00)		return 0;	return 1;}/** * builds struct caller and converts message from generic format to * device-dependent format * func is ICARSAMODEXPO or ICARSACRT * function is PCI_FUNC_KEY_ENCRYPT or PCI_FUNC_KEY_DECRYPT */static inline intbuild_caller(struct work_element *we_p, short function){	int rv;	struct caller *caller_p = (struct caller *)we_p->requestptr;	if ((we_p->devtype != PCICC) && (we_p->devtype != PCICA) &&	    (we_p->devtype != PCIXCC))		return SEN_NOT_AVAIL;	memcpy(caller_p->caller_id, we_p->caller_id,	       sizeof(caller_p->caller_id));	caller_p->caller_dev_dep_req_p = caller_p->caller_dev_dep_req;	caller_p->caller_dev_dep_req_l = MAX_RESPONSE_SIZE;	caller_p->caller_buf_p = we_p->buffer;	INIT_LIST_HEAD(&(caller_p->caller_liste));	rv = convert_request(we_p->buffer, we_p->funccode, function,			     z90crypt.cdx, we_p->devtype,			     &caller_p->caller_dev_dep_req_l,			     caller_p->caller_dev_dep_req_p);	if (rv) {		if (rv == SEN_NOT_AVAIL)			PDEBUG("request can't be processed on hdwr avail\n");		else			PRINTK("Error from convert_request: %d\n", rv);	}	else		memcpy(&(caller_p->caller_dev_dep_req_p[4]), we_p->caller_id,8);	return rv;}static inline voidunbuild_caller(struct device *device_p, struct caller *caller_p){	if (!caller_p)		return;	if (caller_p->caller_liste.next && caller_p->caller_liste.prev)		if (!list_empty(&caller_p->caller_liste)) {			list_del(&caller_p->caller_liste);			device_p->dev_caller_count--;			INIT_LIST_HEAD(&caller_p->caller_liste);		}	memset(caller_p->caller_id, 0, sizeof(caller_p->caller_id));}static inline intget_crypto_request_buffer(struct work_element *we_p){	struct ica_rsa_modexpo *mex_p;	struct ica_rsa_modexpo_crt *crt_p;	unsigned char *temp_buffer;	short function;	int rv;	mex_p =	(struct ica_rsa_modexpo *) we_p->buffer;	crt_p = (struct ica_rsa_modexpo_crt *) we_p->buffer;	PDEBUG("device type input = %d\n", we_p->devtype);	if (z90crypt.terminating)		return REC_NO_RESPONSE;	if (memcmp(we_p->caller_id, NULL_psmid, 8) == 0) {		PRINTK("psmid zeroes\n");		return SEN_FATAL_ERROR;	}	if (!we_p->buffer) {		PRINTK("buffer pointer NULL\n");		return SEN_USER_ERROR;	}	if (!we_p->requestptr) {		PRINTK("caller pointer NULL\n");		return SEN_USER_ERROR;	}	if ((we_p->devtype != PCICA) && (we_p->devtype != PCICC) &&	    (we_p->devtype != PCIXCC) && (we_p->devtype != ANYDEV)) {		PRINTK("invalid device type\n");		return SEN_USER_ERROR;	}	if ((mex_p->inputdatalength < 1) ||	    (mex_p->inputdatalength > MAX_MOD_SIZE)) {		PRINTK("inputdatalength[%d] is not valid\n",		       mex_p->inputdatalength);		return SEN_USER_ERROR;	}	if (mex_p->outputdatalength < mex_p->inputdatalength) {		PRINTK("outputdatalength[%d] < inputdatalength[%d]\n",		       mex_p->outputdatalength, mex_p->inputdatalength);		return SEN_USER_ERROR;	}	if (!mex_p->inputdata || !mex_p->outputdata) {		PRINTK("inputdata[%p] or outputdata[%p] is NULL\n",		       mex_p->outputdata, mex_p->inputdata);		return SEN_USER_ERROR;	}	/**	 * As long as outputdatalength is big enough, we can set the	 * outputdatalength equal to the inputdatalength, since that is the	 * number of bytes we will copy in any case	 */	mex_p->outputdatalength = mex_p->inputdatalength;	rv = 0;	switch (we_p->funccode) {	case ICARSAMODEXPO:		if (!mex_p->b_key || !mex_p->n_modulus)			rv = SEN_USER_ERROR;		break;	case ICARSACRT:		if (!IS_EVEN(crt_p->inputdatalength)) {			PRINTK("inputdatalength[%d] is odd, CRT form\n",			       crt_p->inputdatalength);			rv = SEN_USER_ERROR;			break;		}		if (!crt_p->bp_key ||		    !crt_p->bq_key ||		    !crt_p->np_prime ||		    !crt_p->nq_prime ||		    !crt_p->u_mult_inv) {			PRINTK("CRT form, bad data: %p/%p/%p/%p/%p\n",			       crt_p->bp_key, crt_p->bq_key,			       crt_p->np_prime, crt_p->nq_prime,			       crt_p->u_mult_inv);			rv = SEN_USER_ERROR;		}		break;	default:		PRINTK("bad func = %d\n", we_p->funccode);		rv = SEN_USER_ERROR;		break;	}	if (rv != 0)		return rv;	if (select_device_type(&we_p->devtype) < 0)		return SEN_NOT_AVAIL;	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 does all Mod-Expo form with a simple RSA mod-expo	 * operation, and all CRT forms with a PKCS-1.2 format decrypt.	 */	case PCIXCC:		/* Anything less than MIN_MOD_SIZE MUST go to a PCICA */		if (mex_p->inputdatalength < MIN_MOD_SIZE)			return SEN_NOT_AVAIL;		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:		/* Anything less than MIN_MOD_SIZE MUST go to a PCICA */		if (mex_p->inputdatalength < MIN_MOD_SIZE) {			return SEN_NOT_AVAIL;		}		/* Anythings over MAX_PCICC_MOD_SIZE MUST go to a PCICA */		if (mex_p->inputdatalength > MAX_PCICC_MOD_SIZE) {			return SEN_NOT_AVAIL;		}		/* 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;	}

⌨️ 快捷键说明

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