📄 z90main.c
字号:
sizeof(struct ica_rsa_modexpo_crt_32))) return -EFAULT; crt64 = compat_alloc_user_space(sizeof(struct ica_rsa_modexpo_crt)); if (!access_ok(VERIFY_WRITE, crt64, sizeof(struct ica_rsa_modexpo_crt))) return -EFAULT; if (copy_from_user(&crt32k, crt32u, sizeof(struct ica_rsa_modexpo_crt_32))) return -EFAULT; if (__put_user(compat_ptr(crt32k.inputdata), &crt64->inputdata) || __put_user(crt32k.inputdatalength, &crt64->inputdatalength) || __put_user(compat_ptr(crt32k.outputdata), &crt64->outputdata) || __put_user(crt32k.outputdatalength, &crt64->outputdatalength) || __put_user(compat_ptr(crt32k.bp_key), &crt64->bp_key) || __put_user(compat_ptr(crt32k.bq_key), &crt64->bq_key) || __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) || __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) || __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv)) return -EFAULT; ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)crt64); if (!ret) if (__get_user(i, &crt64->outputdatalength) || __put_user(i, &crt32u->outputdatalength)) ret = -EFAULT; return ret;}static longz90crypt_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ switch (cmd) { case ICAZ90STATUS: case Z90QUIESCE: case Z90STAT_TOTALCOUNT: case Z90STAT_PCICACOUNT: case Z90STAT_PCICCCOUNT: case Z90STAT_PCIXCCCOUNT: case Z90STAT_PCIXCCMCL2COUNT: case Z90STAT_PCIXCCMCL3COUNT: case Z90STAT_CEX2CCOUNT: case Z90STAT_REQUESTQ_COUNT: case Z90STAT_PENDINGQ_COUNT: case Z90STAT_TOTALOPEN_COUNT: case Z90STAT_DOMAIN_INDEX: case Z90STAT_STATUS_MASK: case Z90STAT_QDEPTH_MASK: case Z90STAT_PERDEV_REQCNT: return z90crypt_unlocked_ioctl(filp, cmd, arg); case ICARSAMODEXPO: return trans_modexpo32(filp, cmd, arg); case ICARSACRT: return trans_modexpo_crt32(filp, cmd, arg); default: return -ENOIOCTLCMD; }}#endif/** * The module initialization code. */static int __initz90crypt_init_module(void){ int result, nresult; struct proc_dir_entry *entry; PDEBUG("PID %d\n", PID()); if ((domain < -1) || (domain > 15)) { PRINTKW("Invalid param: domain = %d. Not loading.\n", domain); return -EINVAL; } /* Register as misc device with given minor (or get a dynamic one). */ result = misc_register(&z90crypt_misc_device); if (result < 0) { PRINTKW(KERN_ERR "misc_register (minor %d) failed with %d\n", z90crypt_misc_device.minor, result); return result; } PDEBUG("Registered " DEV_NAME " with result %d\n", result); result = create_z90crypt(&domain); if (result != 0) { PRINTKW("create_z90crypt (domain index %d) failed with %d.\n", domain, result); result = -ENOMEM; goto init_module_cleanup; } if (result == 0) { PRINTKN("Version %d.%d.%d loaded, built on %s %s\n", z90crypt_VERSION, z90crypt_RELEASE, z90crypt_VARIANT, __DATE__, __TIME__); PRINTKN("%s\n", z90main_version); PRINTKN("%s\n", z90hardware_version); PDEBUG("create_z90crypt (domain index %d) successful.\n", domain); } else PRINTK("No devices at startup\n"); /* Initialize globals. */ spin_lock_init(&queuespinlock); INIT_LIST_HEAD(&pending_list); pendingq_count = 0; INIT_LIST_HEAD(&request_list); requestq_count = 0; quiesce_z90crypt = 0; atomic_set(&total_open, 0); atomic_set(&z90crypt_step, 0); /* Set up the cleanup task. */ init_timer(&cleanup_timer); cleanup_timer.function = z90crypt_cleanup_task; cleanup_timer.data = 0; cleanup_timer.expires = jiffies + (CLEANUPTIME * HZ); add_timer(&cleanup_timer); /* Set up the proc file system */ entry = create_proc_entry("driver/z90crypt", 0644, 0); if (entry) { entry->nlink = 1; entry->data = 0; entry->read_proc = z90crypt_status; entry->write_proc = z90crypt_status_write; } else PRINTK("Couldn't create z90crypt proc entry\n"); z90crypt_entry = entry; /* Set up the configuration task. */ init_timer(&config_timer); config_timer.function = z90crypt_config_task; config_timer.data = 0; config_timer.expires = jiffies + (INITIAL_CONFIGTIME * HZ); add_timer(&config_timer); /* Set up the reader task */ tasklet_init(&reader_tasklet, z90crypt_reader_task, 0); init_timer(&reader_timer); reader_timer.function = z90crypt_schedule_reader_task; reader_timer.data = 0; reader_timer.expires = jiffies + (READERTIME * HZ / 1000); add_timer(&reader_timer); return 0; // successinit_module_cleanup: if ((nresult = misc_deregister(&z90crypt_misc_device))) PRINTK("misc_deregister failed with %d.\n", nresult); else PDEBUG("misc_deregister successful.\n"); return result; // failure}/** * The module termination code */static void __exitz90crypt_cleanup_module(void){ int nresult; PDEBUG("PID %d\n", PID()); remove_proc_entry("driver/z90crypt", 0); if ((nresult = misc_deregister(&z90crypt_misc_device))) PRINTK("misc_deregister failed with %d.\n", nresult); else PDEBUG("misc_deregister successful.\n"); /* Remove the tasks */ tasklet_kill(&reader_tasklet); del_timer(&reader_timer); del_timer(&config_timer); del_timer(&cleanup_timer); destroy_z90crypt(); PRINTKN("Unloaded.\n");}/** * Functions running under a process id * * The I/O functions: * z90crypt_open * z90crypt_release * z90crypt_read * z90crypt_write * z90crypt_unlocked_ioctl * z90crypt_status * z90crypt_status_write * disable_card * enable_card * * Helper functions: * z90crypt_rsa * z90crypt_prepare * z90crypt_send * z90crypt_process_results * */static intz90crypt_open(struct inode *inode, struct file *filp){ struct priv_data *private_data_p; if (quiesce_z90crypt) return -EQUIESCE; private_data_p = kmalloc(sizeof(struct priv_data), GFP_KERNEL); if (!private_data_p) { PRINTK("Memory allocate failed\n"); return -ENOMEM; } memset((void *)private_data_p, 0, sizeof(struct priv_data)); private_data_p->status = STAT_OPEN; private_data_p->opener_pid = PID(); filp->private_data = private_data_p; atomic_inc(&total_open); return 0;}static intz90crypt_release(struct inode *inode, struct file *filp){ struct priv_data *private_data_p = filp->private_data; PDEBUG("PID %d (filp %p)\n", PID(), filp); private_data_p->status = STAT_CLOSED; memset(private_data_p, 0, sizeof(struct priv_data)); kfree(private_data_p); atomic_dec(&total_open); return 0;}/* * there are two read functions, of which compile options will choose one * without USE_GET_RANDOM_BYTES * => read() always returns -EPERM; * otherwise * => read() uses get_random_bytes() kernel function */#ifndef USE_GET_RANDOM_BYTES/** * z90crypt_read will not be supported beyond z90crypt 1.3.1 */static ssize_tz90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos){ PDEBUG("filp %p (PID %d)\n", filp, PID()); return -EPERM;}#else // we want to use get_random_bytes/** * read() just returns a string of random bytes. Since we have no way * to generate these cryptographically, we just execute get_random_bytes * for the length specified. */#include <linux/random.h>static ssize_tz90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos){ unsigned char *temp_buff; PDEBUG("filp %p (PID %d)\n", filp, PID()); if (quiesce_z90crypt) return -EQUIESCE; if (count < 0) { PRINTK("Requested random byte count negative: %ld\n", count); return -EINVAL; } if (count > RESPBUFFSIZE) { PDEBUG("count[%d] > RESPBUFFSIZE", count); return -EINVAL; } if (count == 0) return 0; temp_buff = kmalloc(RESPBUFFSIZE, GFP_KERNEL); if (!temp_buff) { PRINTK("Memory allocate failed\n"); return -ENOMEM; } get_random_bytes(temp_buff, count); if (copy_to_user(buf, temp_buff, count) != 0) { kfree(temp_buff); return -EFAULT; } kfree(temp_buff); return count;}#endif/** * Write is is not allowed */static ssize_tz90crypt_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){ PDEBUG("filp %p (PID %d)\n", filp, PID()); return -EPERM;}/** * New status functions */static inline intget_status_totalcount(void){ return z90crypt.hdware_info->hdware_mask.st_count;}static inline intget_status_PCICAcount(void){ return z90crypt.hdware_info->type_mask[PCICA].st_count;}static inline intget_status_PCICCcount(void){ return z90crypt.hdware_info->type_mask[PCICC].st_count;}static inline intget_status_PCIXCCcount(void){ return z90crypt.hdware_info->type_mask[PCIXCC_MCL2].st_count + z90crypt.hdware_info->type_mask[PCIXCC_MCL3].st_count;}static inline intget_status_PCIXCCMCL2count(void){ return z90crypt.hdware_info->type_mask[PCIXCC_MCL2].st_count;}static inline intget_status_PCIXCCMCL3count(void){ return z90crypt.hdware_info->type_mask[PCIXCC_MCL3].st_count;}static inline intget_status_CEX2Ccount(void){ return z90crypt.hdware_info->type_mask[CEX2C].st_count;}static inline intget_status_requestq_count(void){ return requestq_count;}static inline intget_status_pendingq_count(void){ return pendingq_count;}static inline intget_status_totalopen_count(void){ return atomic_read(&total_open);}static inline intget_status_domain_index(void){ return z90crypt.cdx;}static inline unsigned char *get_status_status_mask(unsigned char status[Z90CRYPT_NUM_APS]){ int i, ix; memcpy(status, z90crypt.hdware_info->device_type_array, Z90CRYPT_NUM_APS); for (i = 0; i < get_status_totalcount(); i++) { ix = SHRT2LONG(i); if (LONG2DEVPTR(ix)->user_disabled) status[ix] = 0x0d; } return status;}static inline unsigned char *get_status_qdepth_mask(unsigned char qdepth[Z90CRYPT_NUM_APS]){ int i, ix; memset(qdepth, 0, Z90CRYPT_NUM_APS); for (i = 0; i < get_status_totalcount(); i++) { ix = SHRT2LONG(i); qdepth[ix] = LONG2DEVPTR(ix)->dev_caller_count; } return qdepth;}static inline unsigned int *get_status_perdevice_reqcnt(unsigned int reqcnt[Z90CRYPT_NUM_APS]){ int i, ix; memset(reqcnt, 0, Z90CRYPT_NUM_APS * sizeof(int)); for (i = 0; i < get_status_totalcount(); i++) { ix = SHRT2LONG(i); reqcnt[ix] = LONG2DEVPTR(ix)->dev_total_req_cnt; } return reqcnt;}static inline voidinit_work_element(struct work_element *we_p, struct priv_data *priv_data, pid_t pid){ int step; we_p->requestptr = (unsigned char *)we_p + sizeof(struct work_element); /* Come up with a unique id for this caller. */ step = atomic_inc_return(&z90crypt_step); memcpy(we_p->caller_id+0, (void *) &pid, sizeof(pid)); memcpy(we_p->caller_id+4, (void *) &step, sizeof(step)); we_p->pid = pid; we_p->priv_data = priv_data; we_p->status[0] = STAT_DEFAULT; we_p->audit[0] = 0x00; we_p->audit[1] = 0x00; we_p->audit[2] = 0x00; we_p->resp_buff_size = 0; we_p->retcode = 0; we_p->devindex = -1; we_p->devtype = -1; atomic_set(&we_p->alarmrung, 0); init_waitqueue_head(&we_p->waitq); INIT_LIST_HEAD(&(we_p->liste));}static inline intallocate_work_element(struct work_element **we_pp, struct priv_data *priv_data_p, pid_t pid){ struct work_element *we_p; we_p = (struct work_element *) get_zeroed_page(GFP_KERNEL); if (!we_p) return -ENOMEM; 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++;}/** * Bitlength limits for each card * * There are new MCLs which allow more bitlengths. See the table for details. * The MCL must be applied and the newer bitlengths enabled for these to work. * * Card Type Old limit New limit * PCICA ??-2048 same (the lower limit is less than 128 bit...) * PCICC 512-1024 512-2048 * PCIXCC_MCL2 512-2048 ----- (applying any GA LIC will make an MCL3 card) * PCIXCC_MCL3 ----- 128-2048 * CEX2C 512-2048 128-2048 * * ext_bitlens (extended bitlengths) is a global, since you should not apply an * MCL to just one card in a machine. We assume, at first, that all cards have
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -