首页 > 系统相关 >linux内核hash

linux内核hash

时间:2022-10-14 15:36:07浏览次数:76  
标签:shash hash struct sdesc crypto alg 内核 哈希 linux


linux内核API文档:
​​​https://www.kernel.org/doc/htmldocs/kernel-api/index.html​​​ 带搜索的:
​https://www.kernel.org/doc/html/latest/​

参考:​​https://security.stackexchange.com/questions/11839/what-is-the-difference-between-a-hash-function-and-a-cryptographic-hash-function​​​ 哈希有两种:加密哈希和非加密哈希。
加密哈希的目标是通过加密哈希的得到的哈希值很难逆推得到原始值,而非加密哈希的目标仅仅是减小哈希冲突。

加密哈希

linux内核官方文档中有一个例子:
​​​https://www.kernel.org/doc/html/latest/crypto/api-samples.html​

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

static struct sdesc *init_sdesc(struct crypto_shash *alg)
{
struct sdesc *sdesc;
int size;

size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
sdesc = kmalloc(size, GFP_KERNEL);
if (!sdesc)
return ERR_PTR(-ENOMEM);
sdesc->shash.tfm = alg;
return sdesc;
}

static int calc_hash(struct crypto_shash *alg,
const unsigned char *data, unsigned int datalen,
unsigned char *digest)
{
struct sdesc *sdesc;
int ret;

sdesc = init_sdesc(alg);
if (IS_ERR(sdesc)) {
pr_info("can't alloc sdesc\n");
return PTR_ERR(sdesc);
}

ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
kfree(sdesc);
return ret;
}

static int test_hash(const unsigned char *data, unsigned int datalen,
unsigned char *digest)
{
struct crypto_shash *alg;
char *hash_alg_name = "sha1-padlock-nano";
int ret;

alg = crypto_alloc_shash(hash_alg_name, 0, 0);
if (IS_ERR(alg)) {
pr_info("can't alloc alg %s\n", hash_alg_name);
return PTR_ERR(alg);
}
ret = calc_hash(alg, data, datalen, digest);
crypto_free_shash(alg);
return ret;
}

下面根据我自己的理解解释这段代码。

加密handler:struct crypto_shash

生成

crypto_alloc_shash:根据指定的哈希算法,生成handler,并返回其指针。
原型:

struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
u32 mask);

alg_name: algorithm name,哈希算法名称
type和mask一般都是0。其实我也不清楚

销毁

crypto_free_shash: 销毁由crypto_alloc_shash生成的handler。

static inline void crypto_free_shash(struct crypto_shash *tfm);

struct shash_desc

struct shash_desc {
struct crypto_shash *tfm;
u32 flags;

void *__ctx[] CRYPTO_MINALIGN_ATTR;
};

tfm: 加密handler
ctx: 空数组的首地址,相当于汇编里的一个标号,指向结构体的后一个字节。
这个结构体可能会跟一段buffer一起被申请,而ctx就相当于这段buffer的首地址,所以为了防止访问buffer时出现对齐错误,需要给ctx加上属性CRYPTO_MINALIGN_ATTR。
CRYPTO_MINALIGN_ATTR的含义是通过可能的字节填充,使得ctx是以最大的对齐标准对齐的,防止出现对齐错误。例如在我的机器上,CRYPTO_MINALIGN_ATTR的含义是强制以64位对齐。

struct sdesc

加密handler的第二层封装。我个人觉得上一层封装​​struct shash_desc​​已经可以用了。但是既然官方文档都自定义了一个结构体,就……

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

ctx作为后面跟着的buffer的首地址。由于struct shash_desc里已经进行过对齐,所以后面跟着的buffer的首地址一定是对齐的。

生成

static struct sdesc *init_sdesc(struct crypto_shash *alg)
{
struct sdesc *sdesc;
int size;

size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
sdesc = kmalloc(size, GFP_KERNEL);
if (!sdesc)
return ERR_PTR(-ENOMEM);
sdesc->shash.tfm = alg;
return sdesc;
}

crypto_shash_descsize(alg): 得到这个加密算法需要的buffer大小。

struct shash_desc的大小加上buffer大小就是总共需要申请的内存大小​​size​​。

kmalloc: 申请小于一页的内存。其中GFP_KERNEL表示申请正常的内核RAM,可以睡眠。参考:​​https://www.kernel.org/doc/htmldocs/kernel-api/API-kmalloc.html​

ERR_PTR: 把错误码变成指针。戳这篇文章: ENOMEM: error, no memory

销毁

kfree其内存即可

计算哈希值

int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
unsigned int len, u8 *out);

其中desc后面一定要有足够长的buffer(前面用crypto_shash_descsize保证了)
out就是生成的哈希值。

非加密哈希

一种非常快的哈希质量很好的非加密哈希函数为xxHash系列(xxh32和xxh64)
在​​​linux/xxhash.h​​中xxh32的声明如下:

uint32_t xxh32(const void *input, size_t length, uint32_t seed);

用法是显然的。
benchmarks:​​​https://cyan4973.github.io/xxHash/​


标签:shash,hash,struct,sdesc,crypto,alg,内核,哈希,linux
From: https://blog.51cto.com/seekstar/5757009

相关文章

  • linux 安装python
    wgethttps://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgztarvxzfPython-2.7.18.tgzcdPython-2.7.18yuminstallgccg++make./configuremake&&......
  • linux开放指定端口命令
    1、开启防火墙   systemctlstartfirewalld2、开放指定端口   firewall-cmd--zone=public--add-port=1935/tcp--permanent 命令含义:--zone#作用域......
  • Linux初始化init系统
    近年来,​​Linux​​​ 系统的 ​​init​​​ 进程经历了两次重大的演进,传统的 ​​sysvinit​​​ 已经淡出历史舞台,新的 ​​init​​​ 系统 ​​UpStart​​​......
  • 驱动开发:内核枚举IoTimer定时器
    今天继续分享内核枚举系列知识,这次我们来学习如何通过代码的方式枚举内核IoTimer定时器,内核定时器其实就是在内核中实现的时钟,该定时器的枚举非常简单,因为在IoInitializeTi......
  • 驱动开发:内核枚举IoTimer定时器
    今天继续分享内核枚举系列知识,这次我们来学习如何通过代码的方式枚举内核IoTimer定时器,内核定时器其实就是在内核中实现的时钟,该定时器的枚举非常简单,因为在IoInitializeTim......
  • Linux使用记录
    1.安装gityhexie@Y430P:~$add-apt-repositoryppa:git-core/ppa错误:必须使用root身份运行yhexie@Y430P:~$sudopasswd[sudo]yhexie的密码:输入新的UNIX密码......
  • 全网最全 Linux 命令总结
    今天,给小伙伴们带来一篇Linux命令总结非常全的文章,也是我们平时工作中使用率非常高的操作命令,命令有点多,建议小伙伴们可以先收藏后阅读。基本命令uname-m显示机器的处......
  • 全志 Tina Linux 存储介质切换:eMMC,SPI NAND,SPI NOR,SD Card,SD NAND
    存储切换方法SDK切换存储介质需要修改board.dts、sys_config.fex、内核配置、TINA系统配置。另外,在spinor存储介质下,通过u-boot-sun8iw21p1.bin进行烧录,u-boot-spinor-s......
  • linux绝对路径和相对路径
    前言在操作系统中,路径指的是文件的存放位置,例如windows中C:\Users\HEAD表HEAD目录的路径。在linux中类似,只是路径的描述方式有区别,例如/home/scg表示scg目录的路径。在任......
  • linux 安装mysql8.0.11
    1.使用系统的root账户2.切换到/use/local目录下3.下载mysql?wgethttps://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.21-linux-glibc2.12-x86_64.tar.xz也可以......