相關的分析工作一年前就做完了,一直懶得寫下來。現在覺得還是寫下來,以來怕自己忘記了,二來可以給大家分享一下自己的研究經驗。
這篇文章算是《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的結構體,如下:
- static struct crypto_alg aes_alg = {
- .cra_name = "aes",
- .cra_driver_name = "aes-generic",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
- .cra_blocksize = AES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct crypto_aes_ctx),
- .cra_alignmask = 3,
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
- .cra_u = {
- .cipher = {
- .cia_min_keysize = AES_MIN_KEY_SIZE,
- .cia_max_keysize = AES_MAX_KEY_SIZE,
- .cia_setkey = crypto_aes_set_key,
- .cia_encrypt = aes_encrypt,
- .cia_decrypt = aes_decrypt
- }
- }
- };
alg是algorithm的縮寫。所有的加密、哈希等算法注冊用數據結構都叫做xxx_alg,crypto_alg的完整定義在<srcdir>/include/linux/crypto.h中:
- struct crypto_alg {
- struct list_head cra_list;
- struct list_head cra_users;
- u32 cra_flags;
- unsigned int cra_blocksize;
- unsigned int cra_ctxsize;
- unsigned int cra_alignmask;
- int cra_priority;
- atomic_t cra_refcnt;
- char cra_name[CRYPTO_MAX_ALG_NAME];
- char cra_driver_name[CRYPTO_MAX_ALG_NAME];
- const struct crypto_type *cra_type;
- union {
- struct ablkcipher_alg ablkcipher;
- struct aead_alg aead;
- struct blkcipher_alg blkcipher;
- struct cipher_alg cipher;
- struct compress_alg compress;
- struct rng_alg rng;
- } cra_u;
- int (*cra_init)(struct crypto_tfm *tfm);
- void (*cra_exit)(struct crypto_tfm *tfm);
- void (*cra_destroy)(struct crypto_alg *alg);
-
- struct module *cra_module;
- };
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。