/****************************************************************************** 版权所有: 文件名称: sm2_dev.c 文件版本: 01.01 创建作者: xxxxxx 创建日期: 2014.7.23 功能说明: 加密接口. 其它说明: 修改记录: */ #if !defined CPU_FUXI && !defined CPU_AM335X #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //*************************************** //以下定义是为了编译通过 #ifndef BYTE #define BYTE unsigned char #endif #ifndef WORD #define WORD unsigned short #endif #ifndef DWORD #define DWORD unsigned int #endif #ifndef UINT #define UINT unsigned short #endif #ifndef SINT #define SINT short #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif typedef struct IEC101{ int a; } IEC101_DEF; typedef struct IEC104{ int a; } IEC104_DEF; //*************************************** #include "SM2.h" #include "sm2_dev.h" extern int readUserId(BYTE *dat); extern int writeUserId(BYTE *dat); extern int writeSM2key(BYTE no,BYTE *dat); extern int readSM2key(BYTE no,BYTE *dat); //主设备号 static int major=GH_SM2_DEV_MAJOR; //设备个数 #define GH_SM2_DEV_COUNT 1 //设备名 #define GH_SM2_DEV_NAME "sm2_dev" //gh_sm2_dev 设备数据结构 struct gh_sm2_dev{ int idx; //设备编号 struct cdev cdev; //字符设备数据结构 atomic_t open_flag; //打开标志 }; //gh_sm2_dev设备 static struct gh_sm2_dev g_gh_sm2_dev[GH_SM2_DEV_COUNT]; /****************************************************************************** 函数名称: gh_sm2_dev_open 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-07-14 函数说明: 字符设备打开函数. 参数说明: inode:文件节点. file: 打开的文件 返回值: 成功返回0,失败返回负数 修改记录: */ static int gh_sm2_dev_open(struct inode *inode, struct file *file) { struct gh_sm2_dev *dev; //得到gh_sm2_dev dev=container_of(inode->i_cdev, struct gh_sm2_dev, cdev); //保存gh_sm2_dev,便于以后使用 file->private_data=dev; //设备是否已经打开 if(atomic_inc_return(&dev->open_flag)>1){ atomic_dec(&dev->open_flag); return -EBUSY; } return 0; } /****************************************************************************** 函数名称: gh_sm2_dev_write 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-07-14 函数说明: 字符设备写函数. 参数说明: file: 打开的文件. data: 用户空间数据. len: 发送长度. ppos: 文件偏移位置 返回值: 成功返回发送的字节数,失败返回负数 修改记录: */ static ssize_t gh_sm2_dev_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { return 0; } /****************************************************************************** 函数名称: gh_sm2_dev_read 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-07-14 函数说明: 字符设备读函数. 参数说明: file: 打开的文件. buf: 用户空间缓冲区. len: 读长度. ppos: 文件偏移位置 返回值: 成功返回读取的字节数,失败返回负数 修改记录: */ static ssize_t gh_sm2_dev_read(struct file *file, char __user *data, size_t len, loff_t *ppos) { return 0; } /****************************************************************************** 函数名称: gh_sm2_dev_ioctl 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-07-14 函数说明: 字符设备ioctl函数. 参数说明: inode:文件节点. file: 打开的文件. cmd: 命令. arg: 参数. 返回值: 成功返回0,失败返回负数 修改记录: */ #ifdef CPU_AM335X static long gh_sm2_dev_ioctl(struct file *file, unsigned int cmd, uint32_t arg) #else static int gh_sm2_dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, uint32_t arg) #endif { Twr_UserId *p_wrui; Twr_SM2key *p_sm2key; Twr_SM2key sm2key; TSM2_GenerateRandom_me *p_gr; TSM2_GenerateRandom_me gr; Tencrypt_epri *p_enep; Tencrypt_epri enep; TSM2_Encrypt *p_sm2enrypt; TSM2_Encrypt sm2enrypt; TSM2_Verify *p_sm2verify; TSM2_Verify sm2verify; unsigned int out_len=0; unsigned char dat[68]; int ret = 0; switch(cmd) { case GH_SM2_DEV_READUSERID: //readUserId ret = readUserId(dat); if(ret == 0) { p_wrui = (Twr_UserId *)arg; if(copy_to_user(p_wrui->dat, dat, 16)) return -EFAULT; } else { return -EFAULT; } break; case GH_SM2_DEV_WRITEUSERID: //writeUserId p_wrui = (Twr_UserId *)arg; if(copy_from_user(dat, p_wrui->dat, 16)) return -EFAULT; ret = writeUserId(dat); if(ret != 0) { return -EFAULT; } break; case GH_SM2_DEV_READSM2KEY: //readSM2key sm2key.dat = dat; p_sm2key = (Twr_SM2key *)arg; if(copy_from_user(&sm2key.no, &p_sm2key->no, sizeof(sm2key.no))) { return -EFAULT; } ret = readSM2key(sm2key.no, sm2key.dat); if(ret == 0) { if(copy_to_user(p_sm2key->dat, sm2key.dat, 68)) return -EFAULT; } break; case GH_SM2_DEV_WRITESM2KEY: //writeSM2key sm2key.dat = dat; p_sm2key = (Twr_SM2key *)arg; if(copy_from_user(&sm2key.no, &p_sm2key->no, sizeof(sm2key.no))) return -EFAULT; if(copy_from_user(sm2key.dat, p_sm2key->dat, 68)) return -EFAULT; ret = writeSM2key(sm2key.no, sm2key.dat); if(ret != 0) { return -EFAULT; } break; case GH_SM2_DEV_SM2_GENERATERANDOM_ME: //SM2_GenerateRandom_me gr.pucRandom = dat; p_gr = (TSM2_GenerateRandom_me *)arg; if(copy_from_user(&gr.uiLength, &p_gr->uiLength, sizeof(gr.uiLength))) return -EFAULT; ret = SM2_GenerateRandom_me(gr.uiLength, gr.pucRandom); if(ret != 0) return -EFAULT; if(copy_to_user(p_gr->pucRandom, gr.pucRandom, gr.uiLength)) return -EFAULT; break; case GH_SM2_DEV_ENCRYPTE_EPRI: //encrypt_epri p_enep = (Tencrypt_epri *)arg; if(copy_from_user(&enep, p_enep, sizeof(enep))) return -EFAULT; enep.in = kmalloc(enep.in_len, GFP_KERNEL); if(!enep.in) { return -EFAULT; } enep.out = kmalloc(enep.in_len, GFP_KERNEL); if(!enep.out) { kfree(enep.in); return -EFAULT; } if(copy_from_user(enep.in, p_enep->in, enep.in_len)) { kfree(enep.in); kfree(enep.out); return -EFAULT; } enep.out_len = &out_len; encrypt_epri(enep.in, enep.in_len, enep.out, &out_len, enep.key, enep.type); if(copy_to_user(p_enep->out, enep.out, out_len)) { kfree(enep.in); kfree(enep.out); return -EFAULT; } if(copy_to_user(p_enep->out_len, enep.out_len, sizeof(unsigned int))) { kfree(enep.in); kfree(enep.out); return -EFAULT; } kfree(enep.in); kfree(enep.out); break; case GH_SM2_DEV_SM2_ENCRYPT: //SM2_Encrypt p_sm2enrypt = (TSM2_Encrypt *)arg; if(copy_from_user(&sm2enrypt, p_sm2enrypt, sizeof(sm2enrypt))) return -EFAULT; sm2enrypt.pucDataInput = kmalloc(sm2enrypt.uiInputLength, GFP_KERNEL); if(!sm2enrypt.pucDataInput) { return -EFAULT; } sm2enrypt.pucPublicKey = kmalloc(sizeof(ECCrefPublicKey), GFP_KERNEL); if(!sm2enrypt.pucPublicKey) { kfree(sm2enrypt.pucDataInput); return -EFAULT; } sm2enrypt.pucRandom = kmalloc(sm2enrypt.uiRandomLength, GFP_KERNEL); if(!sm2enrypt.pucRandom) { kfree(sm2enrypt.pucDataInput); kfree(sm2enrypt.pucPublicKey); return -EFAULT; } sm2enrypt.pucEncData = kmalloc(sizeof(ECCCipher), GFP_KERNEL); if(!sm2enrypt.pucEncData) { kfree(sm2enrypt.pucDataInput); kfree(sm2enrypt.pucPublicKey); kfree(sm2enrypt.pucRandom); return -EFAULT; } ret = SM2_Encrypt(sm2enrypt.pucDataInput, sm2enrypt.uiInputLength, sm2enrypt.pucPublicKey, sm2enrypt.pucRandom, sm2enrypt.uiRandomLength, sm2enrypt.pucEncData); if(ret != 0 ) { kfree(sm2enrypt.pucDataInput); kfree(sm2enrypt.pucPublicKey); kfree(sm2enrypt.pucRandom); kfree(sm2enrypt.pucEncData); return -EFAULT; } if(copy_to_user(p_sm2enrypt->pucEncData, sm2enrypt.pucEncData, sizeof(ECCCipher))) { kfree(sm2enrypt.pucDataInput); kfree(sm2enrypt.pucPublicKey); kfree(sm2enrypt.pucRandom); kfree(sm2enrypt.pucEncData); return -EFAULT; } kfree(sm2enrypt.pucDataInput); kfree(sm2enrypt.pucPublicKey); kfree(sm2enrypt.pucRandom); kfree(sm2enrypt.pucEncData); break; case GH_SM2_DEV_SM2_VERIFY: //SM2_Verify p_sm2verify = (TSM2_Verify *)arg; if(copy_from_user(&sm2verify, p_sm2verify, sizeof(sm2verify))) return -EFAULT; sm2verify.pucDataInput = kmalloc(sm2verify.uiInputLength, GFP_KERNEL); if(!sm2verify.pucDataInput) { return -EFAULT; } sm2verify.pucID = kmalloc(sm2verify.uiIDLength, GFP_KERNEL); if(!sm2verify.pucID) { kfree(sm2verify.pucDataInput); return -EFAULT; } sm2verify.pucPublicKey = kmalloc(sizeof(ECCrefPublicKey), GFP_KERNEL); if(!sm2verify.pucPublicKey) { kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); return -EFAULT; } sm2verify.pucSignature = kmalloc(sizeof(ECCSignature), GFP_KERNEL); if(!sm2verify.pucSignature) { kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); kfree(sm2verify.pucPublicKey); return -EFAULT; } if(copy_from_user(sm2verify.pucDataInput, p_sm2verify->pucDataInput, sm2verify.uiInputLength)) { kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); kfree(sm2verify.pucPublicKey); kfree(sm2verify.pucSignature); return -EFAULT; } if(copy_from_user(sm2verify.pucID, p_sm2verify->pucID, sm2verify.uiIDLength)) { kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); kfree(sm2verify.pucPublicKey); kfree(sm2verify.pucSignature); return -EFAULT; } if(copy_from_user(sm2verify.pucPublicKey, p_sm2verify->pucPublicKey, sizeof(ECCrefPublicKey))) { kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); kfree(sm2verify.pucPublicKey); kfree(sm2verify.pucSignature); return -EFAULT; } if(copy_from_user(sm2verify.pucSignature, p_sm2verify->pucSignature, sizeof(ECCSignature))) { kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); kfree(sm2verify.pucPublicKey); kfree(sm2verify.pucSignature); return -EFAULT; } ret = SM2_Verify(sm2verify.pucDataInput, sm2verify.uiInputLength, sm2verify.pucID, sm2verify.uiIDLength, sm2verify.pucPublicKey, sm2verify.pucSignature); if(ret != 0) { kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); kfree(sm2verify.pucPublicKey); kfree(sm2verify.pucSignature); return -EFAULT; } kfree(sm2verify.pucDataInput); kfree(sm2verify.pucID); kfree(sm2verify.pucPublicKey); kfree(sm2verify.pucSignature); break; default: ret = -EFAULT; break; } return ret; } /****************************************************************************** 函数名称: gh_sm2_dev_release 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-07-14 函数说明: 字符设备关闭函数. 参数说明: inode:文件节点. file: 打开的文件 返回值: 总是返回0 修改记录: */ static int gh_sm2_dev_release(struct inode *inode, struct file *file) { struct gh_sm2_dev *dev; dev=container_of(inode->i_cdev, struct gh_sm2_dev, cdev); atomic_dec(&dev->open_flag); return 0; } static const struct file_operations gh_sm2_dev_fops = { .owner = THIS_MODULE, .write = gh_sm2_dev_write, .read = gh_sm2_dev_read, .open = gh_sm2_dev_open, #ifdef CPU_AM335X .unlocked_ioctl = gh_sm2_dev_ioctl, #else .ioctl = gh_sm2_dev_ioctl, #endif .release = gh_sm2_dev_release, }; /****************************************************************************** 函数名称: gh_sm2_dev_init_drvinfo 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-07-14 函数说明: 初始化设备数据结构. 参数说明: 无 返回值: 无 修改记录: */ static void gh_sm2_dev_init_drvinfo(void) { int i=0; memset(g_gh_sm2_dev, 0, sizeof(struct gh_sm2_dev)*GH_SM2_DEV_COUNT); for(i=0;i