歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

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。

Copyright © Linux教程網 All Rights Reserved