📄 z90main.c
字号:
trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file){ struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); struct ica_rsa_modexpo_crt_32 crt32k; struct ica_rsa_modexpo_crt __user *crt64; int ret = 0; unsigned int i; if (!access_ok(VERIFY_WRITE, crt32u, 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)) ret = -EFAULT; if (!ret) ret = sys_ioctl(fd, cmd, (unsigned long)crt64); if (!ret) if (__get_user(i, &crt64->outputdatalength) || __put_user(i, &crt32u->outputdatalength)) ret = -EFAULT; return ret;}static int compatible_ioctls[] = { ICAZ90STATUS, Z90QUIESCE, Z90STAT_TOTALCOUNT, Z90STAT_PCICACOUNT, Z90STAT_PCICCCOUNT, Z90STAT_PCIXCCCOUNT, Z90STAT_REQUESTQ_COUNT, Z90STAT_PENDINGQ_COUNT, Z90STAT_TOTALOPEN_COUNT, Z90STAT_DOMAIN_INDEX, Z90STAT_STATUS_MASK, Z90STAT_QDEPTH_MASK, Z90STAT_PERDEV_REQCNT,};static void z90_unregister_ioctl32s(void){ int i; unregister_ioctl32_conversion(ICARSAMODEXPO); unregister_ioctl32_conversion(ICARSACRT); for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) unregister_ioctl32_conversion(compatible_ioctls[i]);}static int z90_register_ioctl32s(void){ int result, i; result = register_ioctl32_conversion(ICARSAMODEXPO, trans_modexpo32); if (result) return result; result = register_ioctl32_conversion(ICARSACRT, trans_modexpo_crt32); if (result) return result; for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) { result = register_ioctl32_conversion(compatible_ioctls[i],NULL); if (result) { z90_unregister_ioctl32s(); return result; } } return result;}#else // !CONFIG_COMPATstatic inline void z90_unregister_ioctl32s(void){}static inline int z90_register_ioctl32s(void){ return 0;}#endif/** * The module initialization code. */static int __initz90crypt_init_module(void){ int result, nresult; struct proc_dir_entry *entry; PDEBUG("PID %d\n", PID());#ifndef Z90CRYPT_USE_HOTPLUG /* 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; }#else /* Register the major (or get a dynamic one). */ result = register_chrdev(z90crypt_major, REG_NAME, &z90crypt_fops); if (result < 0) { PRINTKW("register_chrdev (major %d) failed with %d.\n", z90crypt_major, result); return result; } if (z90crypt_major == 0) z90crypt_major = result;#endif 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", z90cmain_version); PRINTKN("%s\n", z90chardware_version); PDEBUG("create_z90crypt (domain index %d) successful.\n", domain); } else PRINTK("No devices at startup\n");#ifdef Z90CRYPT_USE_HOTPLUG /* generate hotplug event for device node generation */ z90crypt_hotplug_event(z90crypt_major, 0, Z90CRYPT_HOTPLUG_ADD);#endif /* 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); if ((result = z90_register_ioctl32s())) goto init_module_cleanup; return 0; // successinit_module_cleanup: z90_unregister_ioctl32s();#ifndef Z90CRYPT_USE_HOTPLUG if ((nresult = misc_deregister(&z90crypt_misc_device))) PRINTK("misc_deregister failed with %d.\n", nresult); else PDEBUG("misc_deregister successful.\n");#else if ((nresult = unregister_chrdev(z90crypt_major, REG_NAME))) PRINTK("unregister_chrdev failed with %d.\n", nresult); else PDEBUG("unregister_chrdev successful.\n");#endif return result; // failure}/** * The module termination code */static void __exitz90crypt_cleanup_module(void){ int nresult; PDEBUG("PID %d\n", PID()); z90_unregister_ioctl32s(); remove_proc_entry("driver/z90crypt", 0);#ifndef Z90CRYPT_USE_HOTPLUG if ((nresult = misc_deregister(&z90crypt_misc_device))) PRINTK("misc_deregister failed with %d.\n", nresult); else PDEBUG("misc_deregister successful.\n");#else z90crypt_hotplug_event(z90crypt_major, 0, Z90CRYPT_HOTPLUG_REMOVE); if ((nresult = unregister_chrdev(z90crypt_major, REG_NAME))) PRINTK("unregister_chrdev failed with %d.\n", nresult); else PDEBUG("unregister_chrdev successful.\n");#endif /* 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_ioctl * z90crypt_status * z90crypt_status_write * disable_card * enable_card * scan_char * scan_string * * 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].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; // send_to_crypto selects the device we_p->devtype = -1; // getCryptoBuffer selects the type 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -