📄 loop_blowfish.c
字号:
u32 *P = key->P; u32 *S = key->S; yl = in_blk[0]; yr = in_blk[1]; ROUND (yr, yl, 0); ROUND (yl, yr, 1); ROUND (yr, yl, 2); ROUND (yl, yr, 3); ROUND (yr, yl, 4); ROUND (yl, yr, 5); ROUND (yr, yl, 6); ROUND (yl, yr, 7); ROUND (yr, yl, 8); ROUND (yl, yr, 9); ROUND (yr, yl, 10); ROUND (yl, yr, 11); ROUND (yr, yl, 12); ROUND (yl, yr, 13); ROUND (yr, yl, 14); ROUND (yl, yr, 15); /* yl and yr are switched */ yl ^= P[16]; yr ^= P[17]; out_blk[0] = yr; out_blk[1] = yl;}static void blowfish_decrypt (blow_key *key, const u8 * in8, u8 * out8){ u32 *in_blk = (u32 *) in8; u32 *out_blk = (u32 *) out8; u32 yl, yr; u32 *P = key->P; u32 *S = key->S; yl = in_blk[0]; yr = in_blk[1]; ROUND (yr, yl, 17); ROUND (yl, yr, 16); ROUND (yr, yl, 15); ROUND (yl, yr, 14); ROUND (yr, yl, 13); ROUND (yl, yr, 12); ROUND (yr, yl, 11); ROUND (yl, yr, 10); ROUND (yr, yl, 9); ROUND (yl, yr, 8); ROUND (yr, yl, 7); ROUND (yl, yr, 6); ROUND (yr, yl, 5); ROUND (yl, yr, 4); ROUND (yr, yl, 3); ROUND (yl, yr, 2); /* yl and yr are switched */ yl ^= P[1]; yr ^= P[0]; out_blk[0] = yr; out_blk[1] = yl;}/* Sets the blowfish S and P boxes for encryption and decryption. */static void blowfish_set_key (blow_key *key2, const unsigned char *key, int key_len){ short i; short j; short count; u32 data[2]; u32 temp; u32 *P = key2->P; u32 *S = key2->S; /* Check key length. */ if (key_len != 8 && key_len != 16 && key_len != 20 && key_len != 24 && key_len != 32) key_len = 16; /* Copy the initialization s-boxes */ for (i = 0, count = 0; i < 256; i++) for (j = 0; j < 4; j++, count++) S[count] = bf_sbox[count]; /* Set the p-boxes */ for (i = 0; i < 16 + 2; i++) P[i] = bf_pbox[i]; /* Actual subkey generation */ for (j = 0, i = 0; i < 16 + 2; i++) { temp = (((u32) key[j] << 24) | ((u32) key[(j + 1) % key_len] << 16) | ((u32) key[(j + 2) % key_len] << 8) | ((u32) key[(j + 3) % key_len])); P[i] = P[i] ^ temp; j = (j + 4) % key_len; } data[0] = 0x00000000; data[1] = 0x00000000; for (i = 0; i < 16 + 2; i += 2) { blowfish_encrypt (key2, (u8 *) data, (u8 *) data); P[i] = data[0]; P[i + 1] = data[1]; } for (i = 0; i < 4; i++) { for (j = 0, count = i * 256; j < 256; j += 2, count += 2) { blowfish_encrypt (key2, (u8 *) data, (u8 *) data); S[count] = data[0]; S[count + 1] = data[1]; } }}#if LINUX_VERSION_CODE >= 0x20600typedef sector_t TransferSector_t;# define LoopInfo_t struct loop_info64#elsetypedef int TransferSector_t;# define LoopInfo_t struct loop_info#endifstatic int transfer_blowfish(struct loop_device *lo, int cmd, char *raw_buf, char *loop_buf, int size, TransferSector_t devSect){ register int x; union { u_int64_t h[2]; u_int32_t w[4]; unsigned char b[16]; } iv; union { u_int32_t w[2]; unsigned char b[8]; } n; if(!size || (size & 511)) { return -EINVAL; } if(cmd == READ) { while(size) { if(sizeof(TransferSector_t) == 8) { iv.h[0] = cpu_to_le64(devSect); } else { iv.w[0] = cpu_to_le32(devSect); iv.w[1] = 0; } x = 32; do { memcpy(&iv.b[8], raw_buf, 8); if(lo->lo_init[0] == 1) { /* bug compatible with cryptoapi ? */ blowfish_decrypt((blow_key *)lo->key_data, raw_buf, loop_buf); } else { n.w[0] = cpu_to_be32(*((u_int32_t *)(&raw_buf[0]))); n.w[1] = cpu_to_be32(*((u_int32_t *)(&raw_buf[4]))); blowfish_decrypt((blow_key *)lo->key_data, &n.b[0], &n.b[0]); *((u_int32_t *)(&loop_buf[0])) = cpu_to_be32(n.w[0]); *((u_int32_t *)(&loop_buf[4])) = cpu_to_be32(n.w[1]); } *((u_int32_t *)(&loop_buf[ 0])) ^= iv.w[0]; *((u_int32_t *)(&loop_buf[ 4])) ^= iv.w[1]; raw_buf += 8; loop_buf += 8; memcpy(&iv.b[0], raw_buf, 8); if(lo->lo_init[0] == 1) { /* bug compatible with cryptoapi ? */ blowfish_decrypt((blow_key *)lo->key_data, raw_buf, loop_buf); } else { n.w[0] = cpu_to_be32(*((u_int32_t *)(&raw_buf[0]))); n.w[1] = cpu_to_be32(*((u_int32_t *)(&raw_buf[4]))); blowfish_decrypt((blow_key *)lo->key_data, &n.b[0], &n.b[0]); *((u_int32_t *)(&loop_buf[0])) = cpu_to_be32(n.w[0]); *((u_int32_t *)(&loop_buf[4])) = cpu_to_be32(n.w[1]); } *((u_int32_t *)(&loop_buf[ 0])) ^= iv.w[2]; *((u_int32_t *)(&loop_buf[ 4])) ^= iv.w[3]; raw_buf += 8; loop_buf += 8; } while(--x);#if LINUX_VERSION_CODE >= 0x20600 cond_resched();#elif LINUX_VERSION_CODE >= 0x20400 if(current->need_resched) {set_current_state(TASK_RUNNING);schedule();}#else if(current->need_resched) {current->state=TASK_RUNNING;schedule();}#endif size -= 512; devSect++; } } else { while(size) { if(sizeof(TransferSector_t) == 8) { iv.h[0] = cpu_to_le64(devSect); } else { iv.w[0] = cpu_to_le32(devSect); iv.w[1] = 0; } x = 64; do { iv.w[0] ^= *((u_int32_t *)(&loop_buf[ 0])); iv.w[1] ^= *((u_int32_t *)(&loop_buf[ 4])); if(lo->lo_init[0] == 1) { /* bug compatible with cryptoapi ? */ blowfish_encrypt((blow_key *)lo->key_data, &iv.b[0], raw_buf); } else { n.w[0] = cpu_to_be32(iv.w[0]); n.w[1] = cpu_to_be32(iv.w[1]); blowfish_encrypt((blow_key *)lo->key_data, &n.b[0], &n.b[0]); *((u_int32_t *)(&raw_buf[0])) = cpu_to_be32(n.w[0]); *((u_int32_t *)(&raw_buf[4])) = cpu_to_be32(n.w[1]); } memcpy(&iv.b[0], raw_buf, 8); loop_buf += 8; raw_buf += 8; } while(--x);#if LINUX_VERSION_CODE >= 0x20600 cond_resched();#elif LINUX_VERSION_CODE >= 0x20400 if(current->need_resched) {set_current_state(TASK_RUNNING);schedule();}#else if(current->need_resched) {current->state=TASK_RUNNING;schedule();}#endif size -= 512; devSect++; } } return(0);}static int keySetup_blowfish(struct loop_device *lo, LoopInfo_t *info){ lo->key_data = kmalloc(sizeof(blow_key), GFP_KERNEL); if(!lo->key_data) return(-ENOMEM); blowfish_set_key((blow_key *)lo->key_data, &info->lo_encrypt_key[0], info->lo_encrypt_key_size); memset(&info->lo_encrypt_key[0], 0, sizeof(info->lo_encrypt_key)); return(0);}static int keyClean_blowfish(struct loop_device *lo){ if(lo->key_data) { memset(lo->key_data, 0, sizeof(blow_key)); kfree(lo->key_data); lo->key_data = 0; } return(0);}#if LINUX_VERSION_CODE < 0x20600static void lock_blowfish(struct loop_device *lo){ MOD_INC_USE_COUNT;}static void unlock_blowfish(struct loop_device *lo){ MOD_DEC_USE_COUNT;}#endifstatic struct loop_func_table funcs_blowfish = { number: 4, /* 4 == LO_CRYPT_BLOW */ transfer: (void *) transfer_blowfish, init: (void *) keySetup_blowfish, release: keyClean_blowfish,#if LINUX_VERSION_CODE >= 0x20600 owner: THIS_MODULE,#else lock: lock_blowfish, unlock: unlock_blowfish,#endif}; #if LINUX_VERSION_CODE >= 0x20600# define loop_blowfish_init __init loop_blowfish_initfn# define loop_blowfish_exit loop_blowfish_exitfn#else# define loop_blowfish_init init_module# define loop_blowfish_exit cleanup_module#endifint loop_blowfish_init(void){ if (loop_register_transfer(&funcs_blowfish)) { printk(KERN_WARNING "loop: unable to register blowfish transfer\n"); return -EIO; } printk(KERN_INFO "loop: registered blowfish encryption\n"); return 0;}void loop_blowfish_exit(void){ if (loop_unregister_transfer(funcs_blowfish.number)) { printk(KERN_WARNING "loop: unable to unregister blowfish transfer\n"); return; } printk(KERN_INFO "loop: unregistered blowfish encryption\n");}#if LINUX_VERSION_CODE >= 0x20600module_init(loop_blowfish_initfn);module_exit(loop_blowfish_exitfn);#endif#if defined(MODULE_LICENSE)MODULE_LICENSE("GPL");#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -