Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1228149
  • 博文数量: 389
  • 博客积分: 2874
  • 博客等级: 少校
  • 技术积分: 3577
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 10:34
文章分类

全部博文(389)

文章存档

2020年(2)

2018年(39)

2017年(27)

2016年(3)

2015年(55)

2014年(92)

2013年(54)

2012年(53)

2011年(64)

分类: LINUX

2018-01-17 11:30:10

cryptsetup用kernel里的加密算法通过dm-crypt对磁盘进行加密,能使用的加密算法可以通过/proc/crypt 文件查看,但是如果想使用自己的加密算法该怎么做呢。
这里涉及到三部分,cryptsetup、dm-crypt、kernel里的加密算法模块,因为这几部分是高度模块化的,cryptsetup、dm-crypt根本不管你用什么算法加密数据,它只需要知道算法名称,然后调用该算法的加解密接口就行了,所以我们要实现扩展自己的加密算法只需要自己写一个加密模块,然后将加密算法的名称通过cryptsetup参数传到dm-crypt就可以。
该文不研究加密算法,只关系接口扩展。


先看一下luks命令行操作流程:

点击(此处)折叠或打开

  1. cryptsetup luksFormat /dev/centos/testcrypt -d key.bin
  2. cryptsetup open /dev/centos/testcrypt qcrypt -d key.bin
  3. //只有就可以执行格式化挂载等操作了。
  4. mkfs.xfs /dev/mapper/qcrypt
  5. mount /dev/mapper/qcrypt /mnt/test

上面luksFormat时没有指定加密算法等表示使用默认算法:
LUKS1: aes-xts-plain64, Key: 256 bits, LUKS header hashing: sha256, RNG: /dev/urandom

对上面 aes-xts-plain64不是很了解的可以参考下面:


扩展kernel里的加密算法主要是实现并注册一个struct crypto_alg结构体:

点击(此处)折叠或打开

  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]; //算法名称,将来调用cryptsetup时需要使用
  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. };

对比aes的实现基本也能明白每个字段的含义:

点击(此处)折叠或打开

  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_u = {
  11.  .cipher = {
  12.  .cia_min_keysize = AES_MIN_KEY_SIZE,
  13.  .cia_max_keysize = AES_MAX_KEY_SIZE,
  14.  .cia_setkey = crypto_aes_set_key,
  15.  .cia_encrypt = aes_encrypt,
  16.  .cia_decrypt = aes_decrypt
  17.  }
  18.  }
  19. };
实现了该结构体后就需要将该算法注册到内核中的算法表里:
int crypto_register_alg(struct crypto_alg *alg)
注销算法:
int crypto_unregister_alg(struct crypto_alg *alg)


知道了上面这些内容基本就可以扩展一个自己的算法了:

点击(此处)折叠或打开

  1. static struct crypto_alg qcrypt_algs[] = { {
  2.  .cra_name = "qes",
  3.  .cra_driver_name = "qes-generic",
  4.  .cra_priority = 0,
  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_u = {
  11.  .cipher = {
  12.  .cia_setkey = crypto_qes_set_key,
  13.  .cia_min_keysize = AES_MIN_KEY_SIZE,
  14.  .cia_max_keysize = AES_MAX_KEY_SIZE,
  15.  .cia_encrypt = qes_encrypt,
  16.  .cia_decrypt = qes_decrypt,
  17.  },
  18.  },
  19. } };




  20. static const struct x86_cpu_id qcrypt_cpu_id[] = {
  21.  X86_FEATURE_MATCH(X86_FEATURE_AES),
  22.  {}
  23. };
  24. MODULE_DEVICE_TABLE(x86cpu, qcrypt_cpu_id);


  25. static int __init qcrypt_init(void)
  26. {
  27.  return crypto_register_algs(qcrypt_algs, ARRAY_SIZE(qcrypt_algs));
  28. }


  29. static void __exit qcrypt_exit(void)
  30. {
  31.  crypto_unregister_algs(qcrypt_algs, ARRAY_SIZE(qcrypt_algs));
  32. }


  33. module_init(qcrypt_init);
  34. module_exit(qcrypt_exit);


  35. MODULE_DESCRIPTION("Qgx Cipher Algorithm, test disk crypt");
  36. MODULE_LICENSE("GPL");
  37. MODULE_ALIAS("qcrypt");
crypto_qes_set_key、qes_encrypt、qes_decrypt可以直接参考aes实现,编译加载模块后就能在 /proc/crypt里看到自己的算法qes了。
使用该算法加密磁盘:

cryptsetup luksFormat /dev/centos/testcrypt -d key.bin -c qes-cbc-plain64
cryptsetup open /dev/centos/testcrypt qcrypt -d key.bin
mkfs.xfs /dev/mapper/qcrypt
mount /dev/mapper/qcrypt /mnt/test

阅读(7752) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~