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

📄 loop_serpent.c

📁 Fast and transparent file system and swap encryption package for linux. No source code changes to li
💻 C
📖 第 1 页 / 共 3 页
字号:
      ILINTRANS(r0,r4,r3,r2,r1);      I4(r0,r4,r3,r2,r1);      KEYMIX(r0,r2,r3,r1,r4,48);      /* round 21  */      ILINTRANS(r0,r2,r3,r1,r4);      I3(r0,r2,r3,r1,r4);      KEYMIX(r3,r2,r1,r0,r4,44);      /* round 22  */      ILINTRANS(r3,r2,r1,r0,r4);      I2(r3,r2,r1,r0,r4);      KEYMIX(r2,r4,r1,r0,r3,40);      /* round 23  */      ILINTRANS(r2,r4,r1,r0,r3);      I1(r2,r4,r1,r0,r3);      KEYMIX(r3,r2,r0,r1,r4,36);      /* round 24  */      ILINTRANS(r3,r2,r0,r1,r4);      I0(r3,r2,r0,r1,r4);      KEYMIX(r3,r4,r2,r1,r0,32);      /* round 25  */      ILINTRANS(r3,r4,r2,r1,r0);      I7(r3,r4,r2,r1,r0);      KEYMIX(r1,r3,r4,r0,r2,28);      /* round 26  */      ILINTRANS(r1,r3,r4,r0,r2);      I6(r1,r3,r4,r0,r2);      KEYMIX(r3,r4,r2,r0,r1,24);      /* round 27  */      ILINTRANS(r3,r4,r2,r0,r1);      I5(r3,r4,r2,r0,r1);      KEYMIX(r4,r1,r0,r2,r3,20);      /* round 28  */      ILINTRANS(r4,r1,r0,r2,r3);      I4(r4,r1,r0,r2,r3);      KEYMIX(r4,r2,r0,r3,r1,16);      /* round 29  */      ILINTRANS(r4,r2,r0,r3,r1);      I3(r4,r2,r0,r3,r1);      KEYMIX(r0,r2,r3,r4,r1,12);      /* round 30  */      ILINTRANS(r0,r2,r3,r4,r1);      I2(r0,r2,r3,r4,r1);      KEYMIX(r2,r1,r3,r4,r0,8);      /* round 31  */      ILINTRANS(r2,r1,r3,r4,r0);      I1(r2,r1,r3,r4,r0);      KEYMIX(r0,r2,r4,r3,r1,4);      /* round 32  */      ILINTRANS(r0,r2,r4,r3,r1);      I0(r0,r2,r4,r3,r1);      KEYMIX(r0,r1,r2,r3,r4,0);          if (wrongByteOrder) {          /* incorrect byte order */          out_blk[3] = io_swap_be(r0);          out_blk[2] = io_swap_be(r1);          out_blk[1] = io_swap_be(r2);          out_blk[0] = io_swap_be(r3);      } else {          /* correct byte order */          out_blk[0] = io_swap_le(r0);          out_blk[1] = io_swap_le(r1);          out_blk[2] = io_swap_le(r2);          out_blk[3] = io_swap_le(r3);      }};#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#endif#if !defined(LOOP_MULTI_KEY_SETUP)# define LOOP_MULTI_KEY_SETUP 0x4C4D#endif#if !defined(LOOP_MULTI_KEY_SETUP_V3)# define LOOP_MULTI_KEY_SETUP_V3 0x4C4E#endifextern void loop_compute_sector_iv(TransferSector_t, u_int32_t *);extern void loop_compute_md5_iv_v3(TransferSector_t, u_int32_t *, u_int32_t *);typedef struct {    u32 k[140];} serpent_context;typedef struct {    serpent_context *keyPtr[64];    unsigned        keyMask;    u_int32_t       partialMD5[4];} SerpentMultiKey;static SerpentMultiKey *allocMultiKey(void){    SerpentMultiKey *m;    serpent_context *a;    int x, n;    m = (SerpentMultiKey *) kmalloc(sizeof(SerpentMultiKey), GFP_KERNEL);    if(!m) return 0;    memset(m, 0, sizeof(SerpentMultiKey));    n = PAGE_SIZE / sizeof(serpent_context);    if(!n) n = 1;    a = (serpent_context *) kmalloc(sizeof(serpent_context) * n, GFP_KERNEL);    if(!a) {        kfree(m);        return 0;        }    x = 0;    while((x < 64) && n) {        m->keyPtr[x] = a;        a++;        x++;        n--;    }    return m;}static void clearAndFreeMultiKey(SerpentMultiKey *m){    serpent_context *a;    int x, n;    n = PAGE_SIZE / sizeof(serpent_context);    if(!n) n = 1;    x = 0;    while(x < 64) {        a = m->keyPtr[x];        if(!a) break;        memset(a, 0, sizeof(serpent_context) * n);        kfree(a);        x += n;    }    memset(m, 0, sizeof(SerpentMultiKey));    kfree(m);}static int multiKeySetup(struct loop_device *lo, unsigned char *k, int version3){    SerpentMultiKey *m;    serpent_context *a;    int x, y, n;    union {        u_int32_t     w[16];        unsigned char b[64];    } un;    /* lo->lo_init[0] == 0 or 1 means correct byte order serpent */    /* lo->lo_init[0] == 2 means inverted byte order serpent */    int wrongByteOrder = (lo->lo_init[0] == 2);    extern void md5_transform_CPUbyteorder_C(u_int32_t *, u_int32_t const *);#if LINUX_VERSION_CODE >= 0x20200    if(lo->lo_key_owner != current->uid && !capable(CAP_SYS_ADMIN))        return -EPERM;#endif    m = (SerpentMultiKey *)lo->key_data;    if(!m) return -ENXIO;    n = PAGE_SIZE / sizeof(serpent_context);    if(!n) n = 1;    x = 0;    while(x < 64) {        if(!m->keyPtr[x]) {            a = (serpent_context *) kmalloc(sizeof(serpent_context) * n, GFP_KERNEL);            if(!a) return -ENOMEM;            y = x;            while((y < (x + n)) && (y < 64)) {                m->keyPtr[y] = a;                a++;                y++;            }        }        if(copy_from_user(&un.b[0], k, 32)) return -EFAULT;        serpent_set_key(&m->keyPtr[x]->k[0], &un.b[0], lo->lo_encrypt_key_size, wrongByteOrder);        k += 32;        x++;    }    m->partialMD5[0] = 0x67452301;    m->partialMD5[1] = 0xefcdab89;    m->partialMD5[2] = 0x98badcfe;    m->partialMD5[3] = 0x10325476;    if(version3) {        /* only first 128 bits of iv-key is used */        if(copy_from_user(&un.b[0], k, 16)) return -EFAULT;#if defined(__BIG_ENDIAN)        un.w[0] = cpu_to_le32(un.w[0]);        un.w[1] = cpu_to_le32(un.w[1]);        un.w[2] = cpu_to_le32(un.w[2]);        un.w[3] = cpu_to_le32(un.w[3]);#endif        memset(&un.b[16], 0, 48);        md5_transform_CPUbyteorder_C(&m->partialMD5[0], &un.w[0]);        lo->lo_flags |= 0x080000;  /* multi-key-v3 (info exported to user space) */    }    m->keyMask = 0x3F;          /* range 0...63 */    lo->lo_flags |= 0x100000;   /* multi-key (info exported to user space) */    memset(&un.b[0], 0, 32);    return 0;}static int transfer_serpent(struct loop_device *lo, int cmd, char *raw_buf,          char *loop_buf, int size, TransferSector_t devSect){    serpent_context     *a;    SerpentMultiKey     *m;    int             x;    unsigned        y;    u_int32_t       iv[8];    /* lo->lo_init[0] == 0 or 1 means correct byte order serpent */    /* lo->lo_init[0] == 2 means inverted byte order serpent */    int wrongByteOrder = (lo->lo_init[0] == 2);    if(!size || (size & 511)) {        return -EINVAL;    }    m = (SerpentMultiKey *)lo->key_data;    y = m->keyMask;    if(cmd == READ) {        while(size) {            a = m->keyPtr[((unsigned)devSect) & y];            if(y) {                memcpy(&iv[0], raw_buf, 16);                raw_buf += 16;                loop_buf += 16;            } else {                loop_compute_sector_iv(devSect, &iv[0]);            }            x = 15;            do {                memcpy(&iv[4], raw_buf, 16);                serpent_decrypt(&a->k[0], raw_buf, loop_buf, wrongByteOrder);                *((u_int32_t *)(&loop_buf[ 0])) ^= iv[0];                *((u_int32_t *)(&loop_buf[ 4])) ^= iv[1];                *((u_int32_t *)(&loop_buf[ 8])) ^= iv[2];                *((u_int32_t *)(&loop_buf[12])) ^= iv[3];                if(y && !x) {                    raw_buf -= 496;                    loop_buf -= 496;                    memcpy(&iv[4], &m->partialMD5[0], 16);                    loop_compute_md5_iv_v3(devSect, &iv[4], (u_int32_t *)(&loop_buf[16]));                } else {                    raw_buf += 16;                    loop_buf += 16;                    memcpy(&iv[0], raw_buf, 16);                }                serpent_decrypt(&a->k[0], raw_buf, loop_buf, wrongByteOrder);                *((u_int32_t *)(&loop_buf[ 0])) ^= iv[4];                *((u_int32_t *)(&loop_buf[ 4])) ^= iv[5];                *((u_int32_t *)(&loop_buf[ 8])) ^= iv[6];                *((u_int32_t *)(&loop_buf[12])) ^= iv[7];                if(y && !x) {                    raw_buf += 512;                    loop_buf += 512;                } else {                    raw_buf += 16;                    loop_buf += 16;                }            } while(--x >= 0);#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) {            a = m->keyPtr[((unsigned)devSect) & y];            if(y) {#if LINUX_VERSION_CODE < 0x20400                /* on 2.2 and older kernels, real raw_buf may be doing */                /* writes at any time, so this needs to be stack buffer */                u_int32_t tmp_raw_buf[128];                char *TMP_RAW_BUF = (char *)(&tmp_raw_buf[0]);#else                /* on 2.4 and later kernels, real raw_buf is not doing */                /* any writes now so it can be used as temp buffer */# define TMP_RAW_BUF raw_buf#endif                memcpy(TMP_RAW_BUF, loop_buf, 512);                memcpy(&iv[0], &m->partialMD5[0], 16);                loop_compute_md5_iv_v3(devSect, &iv[0], (u_int32_t *)(&TMP_RAW_BUF[16]));                x = 15;                do {                    iv[0] ^= *((u_int32_t *)(&TMP_RAW_BUF[ 0]));                    iv[1] ^= *((u_int32_t *)(&TMP_RAW_BUF[ 4]));                    iv[2] ^= *((u_int32_t *)(&TMP_RAW_BUF[ 8]));                    iv[3] ^= *((u_int32_t *)(&TMP_RAW_BUF[12]));                    serpent_encrypt(&a->k[0], (unsigned char *)(&iv[0]), raw_buf, wrongByteOrder);                    memcpy(&iv[0], raw_buf, 16);                    raw_buf += 16;#if LINUX_VERSION_CODE < 0x20400                    TMP_RAW_BUF += 16;#endif                    iv[0] ^= *((u_int32_t *)(&TMP_RAW_BUF[ 0]));                    iv[1] ^= *((u_int32_t *)(&TMP_RAW_BUF[ 4]));                    iv[2] ^= *((u_int32_t *)(&TMP_RAW_BUF[ 8]));                    iv[3] ^= *((u_int32_t *)(&TMP_RAW_BUF[12]));                    serpent_encrypt(&a->k[0], (unsigned char *)(&iv[0]), raw_buf, wrongByteOrder);                    memcpy(&iv[0], raw_buf, 16);                    raw_buf += 16;#if LINUX_VERSION_CODE < 0x20400                    TMP_RAW_BUF += 16;#endif                } while(--x >= 0);                loop_buf += 512;            } else {                loop_compute_sector_iv(devSect, &iv[0]);                x = 15;                do {                    iv[0] ^= *((u_int32_t *)(&loop_buf[ 0]));                    iv[1] ^= *((u_int32_t *)(&loop_buf[ 4]));                    iv[2] ^= *((u_int32_t *)(&loop_buf[ 8]));                    iv[3] ^= *((u_int32_t *)(&loop_buf[12]));                    serpent_encrypt(&a->k[0], (unsigned char *)(&iv[0]), raw_buf, wrongByteOrder);                    memcpy(&iv[0], raw_buf, 16);                    loop_buf += 16;                    raw_buf += 16;                    iv[0] ^= *((u_int32_t *)(&loop_buf[ 0]));                    iv[1] ^= *((u_int32_t *)(&loop_buf[ 4]));                    iv[2] ^= *((u_int32_t *)(&loop_buf[ 8]));                    iv[3] ^= *((u_int32_t *)(&loop_buf[12]));                    serpent_encrypt(&a->k[0], (unsigned char *)(&iv[0]), raw_buf, wrongByteOrder);                    memcpy(&iv[0], raw_buf, 16);                    loop_buf += 16;                    raw_buf += 16;                } while(--x >= 0);            }#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_serpent(struct loop_device *lo, LoopInfo_t *info){    SerpentMultiKey     *m;    /* lo->lo_init[0] == 0 or 1 means correct byte order serpent */    /* lo->lo_init[0] == 2 means inverted byte order serpent */    int wrongByteOrder = (info->lo_init[0] == 2);    lo->key_data = m = allocMultiKey();    if(!m) return(-ENOMEM);    serpent_set_key(&m->keyPtr[0]->k[0], &info->lo_encrypt_key[0],            info->lo_encrypt_key_size, wrongByteOrder);    memset(&info->lo_encrypt_key[0], 0, sizeof(info->lo_encrypt_key));    return(0);}static int keyClean_serpent(struct loop_device *lo){    if(lo->key_data) {        clearAndFreeMultiKey((SerpentMultiKey *)lo->key_data);        lo->key_data = 0;    }    return(0);}static int handleIoctl_serpent(struct loop_device *lo, int cmd, unsigned long arg){    int err;    switch (cmd) {    case LOOP_MULTI_KEY_SETUP:        err = multiKeySetup(lo, (unsigned char *)arg, 0);        break;    case LOOP_MULTI_KEY_SETUP_V3:        err = multiKeySetup(lo, (unsigned char *)arg, 1);        break;    default:        err = -EINVAL;    }    return err;}#if LINUX_VERSION_CODE < 0x20600static void lock_serpent(struct loop_device *lo){    MOD_INC_USE_COUNT;}static void unlock_serpent(struct loop_device *lo){    MOD_DEC_USE_COUNT;}#endifstatic struct loop_func_table funcs_serpent = {    number:     7,     /* 7 == LO_CRYPT_SERPENT */    transfer:   (void *) transfer_serpent,    init:       (void *) keySetup_serpent,    release:    keyClean_serpent,#if LINUX_VERSION_CODE >= 0x20600    owner:      THIS_MODULE,#else    lock:       lock_serpent,    unlock:     unlock_serpent,#endif    ioctl:      (void *) handleIoctl_serpent};    #if LINUX_VERSION_CODE >= 0x20600# define loop_serpent_init  __init loop_serpent_initfn# define loop_serpent_exit  loop_serpent_exitfn#else# define loop_serpent_init  init_module# define loop_serpent_exit  cleanup_module#endifint loop_serpent_init(void){    if (loop_register_transfer(&funcs_serpent)) {        printk(KERN_WARNING "loop: unable to register serpent transfer\n");        return -EIO;    }    printk(KERN_INFO "loop: registered serpent encryption\n");    return 0;}void loop_serpent_exit(void){       if (loop_unregister_transfer(funcs_serpent.number)) {        printk(KERN_WARNING "loop: unable to unregister serpent transfer\n");        return;    }    printk(KERN_INFO "loop: unregistered serpent encryption\n");}#if LINUX_VERSION_CODE >= 0x20600module_init(loop_serpent_initfn);module_exit(loop_serpent_exitfn);#endif#if defined(MODULE_LICENSE)MODULE_LICENSE("GPL");#endif

⌨️ 快捷键说明

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