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

📄 z90main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
 * these capabilities. */int ext_bitlens = 1; // This is global#define PCIXCC_MIN_MOD_SIZE	 16	//  128 bits#define OLD_PCIXCC_MIN_MOD_SIZE	 64	//  512 bits#define PCICC_MIN_MOD_SIZE	 64	//  512 bits#define OLD_PCICC_MAX_MOD_SIZE	128	// 1024 bits#define MAX_MOD_SIZE		256	// 2048 bitsstatic inline intselect_device_type(int *dev_type_p, int bytelength){	static int count = 0;	int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, index_to_use;	struct status *stat;	if ((*dev_type_p != PCICC) && (*dev_type_p != PCICA) &&	    (*dev_type_p != PCIXCC_MCL2) && (*dev_type_p != PCIXCC_MCL3) &&	    (*dev_type_p != CEX2C) && (*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;	}	/* Assumption: PCICA, PCIXCC_MCL3, and CEX2C are all similar in speed */	stat = &z90crypt.hdware_info->type_mask[PCICA];	PCICA_avail = stat->st_count -			(stat->disabled_count + stat->user_disabled_count);	stat = &z90crypt.hdware_info->type_mask[PCIXCC_MCL3];	PCIXCC_MCL3_avail = stat->st_count -			(stat->disabled_count + stat->user_disabled_count);	stat = &z90crypt.hdware_info->type_mask[CEX2C];	CEX2C_avail = stat->st_count -			(stat->disabled_count + stat->user_disabled_count);	if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail) {		/**		 * bitlength is a factor, PCICA is the most capable, even with		 * the new MCL for PCIXCC.		 */		if ((bytelength < PCIXCC_MIN_MOD_SIZE) ||		    (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) {			if (!PCICA_avail)				return -1;			else {				*dev_type_p = PCICA;				return 0;			}		}		index_to_use = count % (PCICA_avail + PCIXCC_MCL3_avail +					CEX2C_avail);		if (index_to_use < PCICA_avail)			*dev_type_p = PCICA;		else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail))			*dev_type_p = PCIXCC_MCL3;		else			*dev_type_p = CEX2C;		count++;		return 0;	}	/* Less than OLD_PCIXCC_MIN_MOD_SIZE cannot go to a PCIXCC_MCL2 */	if (bytelength < OLD_PCIXCC_MIN_MOD_SIZE)		return -1;	stat = &z90crypt.hdware_info->type_mask[PCIXCC_MCL2];	if (stat->st_count >	    (stat->disabled_count + stat->user_disabled_count)) {		*dev_type_p = PCIXCC_MCL2;		return 0;	}	/**	 * Less than PCICC_MIN_MOD_SIZE or more than OLD_PCICC_MAX_MOD_SIZE	 * (if we don't have the MCL applied and the newer bitlengths enabled)	 * cannot go to a PCICC	 */	if ((bytelength < PCICC_MIN_MOD_SIZE) ||	    (!ext_bitlens && (bytelength > OLD_PCICC_MAX_MOD_SIZE))) {		return -1;	}	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 bytelength){	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, bytelength) == -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;	int bytelen = ((struct ica_rsa_modexpo *)we_p->buffer)->inputdatalength;	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, bytelen) == -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};/** * 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_MCL2) && (we_p->devtype != PCIXCC_MCL3) &&	    (we_p->devtype != CEX2C))		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_init(&caller_p->caller_liste);			device_p->dev_caller_count--;		}	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_MCL2) && (we_p->devtype != PCIXCC_MCL3) &&	    (we_p->devtype != CEX2C) && (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, mex_p->inputdatalength) < 0)		return SEN_NOT_AVAIL;

⌨️ 快捷键说明

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