Linux块设备加密之dm-crypt分析


相关的分析工作一年前就做完了,一直懒得写下来。现在觉得还是写下来,以来怕自己忘记了,二来可以给大家分享一下自己的研究经验。

这篇文章算是《Device Mapper代码分析》的后续篇,因为dm-crypt是基于dm框架的,因此与上一篇一样,也以2.6.33内核代码为基础来讲述代码的分析过程。但是本文侧重点不同在于着重分析一下三个方面:

1、Linux密码管理

2、dm-crypt到与Linux密码的关联

3、dm-crypt的异步处理

一、Linux密码管理

Linux内核中,密码相关的头文件在<srcdir>/include/crypto/下,实现文件在<srcdir>/crypto/下。相关的概念大致有加密、块加密、异步块加密、哈希、分组加密模式(ECB/CBC/CFB/OFB/CTR)等。接下来一一进行简单分析。

1.1 加密算法

我们可以从内核代码中挑一个简单而普通的加密算法来研究一下,例如<srcdir>/crypto/aes_generic.c描述的AES算法。

所有加密算法都是以内核模块方式编写的。所有内核模块的代码都是先看关键数据结构,再看算法。aes先声明了一个叫做crypto_alg的结构体,如下:

  1. static struct crypto_alg aes_alg = {   
  2.     .cra_name       =   "aes",   
  3.     .cra_driver_name    =   "aes-generic",   
  4.     .cra_priority       =   100,   
  5.     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,   
  6.     .cra_blocksize      =   AES_BLOCK_SIZE,   
  7.     .cra_ctxsize        =   sizeof(struct crypto_aes_ctx),   
  8.     .cra_alignmask      =   3,   
  9.     .cra_module     =   THIS_MODULE,   
  10.     .cra_list       =   LIST_HEAD_INIT(aes_alg.cra_list),   
  11.     .cra_u          =   {   
  12.         .cipher = {   
  13.             .cia_min_keysize    =   AES_MIN_KEY_SIZE,   
  14.             .cia_max_keysize    =   AES_MAX_KEY_SIZE,   
  15.             .cia_setkey     =   crypto_aes_set_key,   
  16.             .cia_encrypt        =   aes_encrypt,   
  17.             .cia_decrypt        =   aes_decrypt   
  18.         }   
  19.     }   
  20. };  

alg是algorithm的缩写。所有的加密、哈希等算法注册用数据结构都叫做xxx_alg,crypto_alg的完整定义在<srcdir>/include/linux/crypto.h中:

  1. struct crypto_alg {   
  2.     struct list_head cra_list;   
  3.     struct list_head cra_users;   
  4.     u32 cra_flags;   
  5.     unsigned int cra_blocksize;   
  6.     unsigned int cra_ctxsize;   
  7.     unsigned int cra_alignmask;   
  8.     int cra_priority;   
  9.     atomic_t cra_refcnt;   
  10.     char cra_name[CRYPTO_MAX_ALG_NAME];   
  11.     char cra_driver_name[CRYPTO_MAX_ALG_NAME];   
  12.     const struct crypto_type *cra_type;   
  13.     union {   
  14.         struct ablkcipher_alg ablkcipher;   
  15.         struct aead_alg aead;   
  16.         struct blkcipher_alg blkcipher;   
  17.         struct cipher_alg cipher;   
  18.         struct compress_alg compress;   
  19.         struct rng_alg rng;   
  20.     } cra_u;   
  21.     int (*cra_init)(struct crypto_tfm *tfm);   
  22.     void (*cra_exit)(struct crypto_tfm *tfm);   
  23.     void (*cra_destroy)(struct crypto_alg *alg);   
  24.        
  25.     struct module *cra_module;   
  26. };  

alg的关键成员有name(算法名)、driver_name(驱动名)、flags(算法类型、同步or异步)、blocksize(分组大小,单位:字节)、ctxsize(上下文大小/字节)、alignmask(ctx的对齐)、min/max-keysize(最小or最大密钥长度/字节)、init/exit(tfm的初始化和销毁)、destroy(alg的销毁)、set_key/encrypt/decrypt(设置密钥/加密/解密的函数)。有些算法可能还有iv_size之类的,后面再讲。

这里有个ctx(算法上下文)的概念要解释一下。所谓上下文,就是算法执行过程中所要贯穿始终的数据结构,由每个算法自己定义。set_key/encrypt/decrypt这几个函数都可以从参数获得算法上下文的指针。算法上下文所占的内存空间由密码管理器来分配,注册alg的时候指定ctx大小和对齐即可。ctx的对齐又是什么呢?在密码管理器分配ctx内存的时候,需要进行内存对齐。对于一些硬件加解密或者特殊要求的算法,ctx的首地址可能需要在内存中4字节或者16字节对齐,这个cra_alignmask就是指定这个。aes使用的是3(0x11),就是将首地址低二位清零,即4字节对齐,如果要求N字节对齐(N是2的某个指数),那么alignmask就可以指定为N-1。

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 下一页

相关内容