Linux内核crypto框架Hash/RSA验签算法使用样例

. . . . 是个内核模块里面功能的一部分,用来通过file结构体(来自fs部分)读取文件并计算哈希,在内核5.15上编译通过

#include <crypto/algapi.h>
#include <crypto/hash.h>
#include <crypto/sha2.h> // 注意这个引用,因为用的是SHA256所以要引用它,如果是sha1就得引用sha1.h,不同的算法文件不一样,需要自己去crypto下确认下
#include <linux/fs.h>
#include <linux/string.h>

struct sdesc {
   
   
  struct shash_desc shash;
  char ctx[];
};

// 我这个模块循环执行的,所以环境alloc一次就保持了,不会释放也不会多次申请,提高性能,按需更改
struct crypto_shash *alg = NULL;
struct sdesc *sdesc = NULL;
char *rbuf = NULL;

static int calc_sha256_hash(struct file *file, unsigned char *digest) {
   
   
  int ret = 0;
  int size = 0;
  loff_t i_size = 0;
  loff_t offset = 0;
  int rbuf_len = 0;

  // The target we're checking
  struct dentry *dentry = file->f_path.dentry;
  struct inode *inode = d_backing_inode(dentry);

  // Find out how big the file is
  // 下面这行被注释的代码来自于内核security下ima组件的代码,很简练的用法,但我没试过,我测试通过的是没注释部分的代码
  // i_size = i_size_read(file_inode(file));
  i_size = i_size_read(inode);
  printk(KERN_INFO "File Size: %lld\n", i_size);

  // Allocate a buffer for reading the file contents
  if (rbuf == NULL) {
   
   
    rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL);
    if (!rbuf) {
   
   
      printk(KERN_ERR "failed to kzalloc to read buffer\n");
      return -ENOMEM;
    }
  }

	// 注意下面的初始化操作,要是不是我这种环境持久化的代码,每个出错返回流程中需要把前面申请的内存释放掉,避免泄漏。我这里不需要就没有,释放的代码在最下面
  // Hash Algo init
  if (alg == NULL) {
   
   
  	// 这个位置的算法名字可以指定其他,见下一部分的列表
    alg = crypto_alloc_shash("sha256", 0, 0);
    if (IS_ERR(alg)) {
   
   
      printk(KERN_ERR "can't alloc alg sha256\n");
      return PTR_ERR(alg);
    }
  }

  // Calc CTX init
  if (sdesc == NULL) {
   
   
    size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
    sdesc = kmalloc(size, GFP_KERNEL);
    if (!sdesc) {
   
   
      printk(KERN_ERR "can't alloc sdesc\n");
      return -ENOMEM;
    }
    sdesc->shash.tfm = alg;
    // 部分资料里有写这个,但是5.15没有,我就注释了
    // sdesc->shash.flag = crypto_shash_get_flags(alg);
  }

  // Init the hash
  ret = crypto_shash_init(&sdesc->shash);
  if (ret) {
   
   
    printk(KERN_ERR "failed to crypto_shash_init\n");
    return ret;
  }

  // Calc Hash, in page-sized chunks.
  while (offset < i_size) {
   
   
    // be care of "&offset", offset will self increment
    rbuf_len = kernel_read(file, rbuf, PAGE_SIZE, &offset);
    if (rbuf_len < 0) {
   
   
      ret = rbuf_len
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值