c - 如何在 Linux 文档中测试加密 api 示例?
问题描述
我想使用加密 API,我找到了关于它的 linux 内核文档。
https://www.kernel.org/doc/html/latest/crypto/api-samples.html
我尝试运行第二个示例,这是我的代码。我不知道要插入什么作为数据,所以我只输入字符串值。我尝试了 datalen 4 和 4 * sizeof(unsigned char) 但都失败了。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/hash.h>
#include <crypto/algapi.h>
MODULE_LICENSE( "GPL" );
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";
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;
}
static int __init init_crypto( void )
{
unsigned char *digest=NULL;
test_hash("hihi", sizeof(unsigned char) * 4, digest);
printk("digest:%s\n", digest);
return 0;
}
static void __exit exit_crypto( void )
{
return;
}
module_init(init_crypto);
module_exit(exit_crypto);
dmesg 输出显示 NULL 指针取消引用,但我找不到它。
[ 531.903173] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 531.903178] #PF: supervisor write access in kernel mode
[ 531.903181] #PF: error_code(0x0002) - not-present page
[ 531.903183] PGD 0 P4D 0
[ 531.903189] Oops: 0002 [#1] SMP NOPTI
[ 531.903195] CPU: 20 PID: 3550 Comm: insmod Tainted: G OE 5.5.0-050500-generic #202001262030
[ 531.903198] Hardware name: Supermicro X11DPi-N(T)/X11DPi-N, BIOS 3.1 04/26/2019
[ 531.903209] RIP: 0010:sha1_final+0x8a/0x150
[ 531.903213] Code: 00 00 00 48 8b 43 20 ba 01 00 00 00 4c 89 f6 4c 89 ef 48 c1 e0 03 48 0f c8 48 89 43 60 e8 ee fe ff ff 31 c0 8b 54 03 08 0f ca <41> 89 14 04 48 83 c0 04 48 83 f8 14 75 ec 31 c0 4c 89 ef b9 0c
00
[ 531.903216] RSP: 0018:ffffa40020fbbb80 EFLAGS: 00010246
[ 531.903220] RAX: 0000000000000000 RBX: ffff8ca974e2b300 RCX: 0000000000000000
[ 531.903223] RDX: 000000007baa8068 RSI: 00000000d957a94f RDI: ffffa40020fbbb48
[ 531.903225] RBP: ffffa40020fbbba0 R08: 00000000115a40ab R09: 00000000d720d80a
[ 531.903228] R10: 0000000073f50df2 R11: 00000000c1388af6 R12: 0000000000000000
[ 531.903230] R13: ffff8ca974e2b308 R14: ffff8ca974e2b328 R15: ffffffffc0a74054
[ 531.903234] FS: 00007f4ce7066540(0000) GS:ffff8ca981e80000(0000) knlGS:0000000000000000
[ 531.903236] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 531.903239] CR2: 0000000000000000 CR3: 0000001f4447c002 CR4: 00000000007606e0
[ 531.903241] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 531.903244] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 531.903246] PKRU: 55555554
[ 531.903248] Call Trace:
[ 531.903255] crypto_sha1_finup+0x5d/0x160
[ 531.903266] crypto_shash_finup+0x25/0x30
[ 531.903270] shash_digest_unaligned+0x52/0x70
[ 531.903275] crypto_shash_digest+0x2e/0x40
[ 531.903281] init_crypto+0x9b/0x1000 [my_crypto]
[ 531.903285] ? 0xffffffffc0b3c000
[ 531.903292] do_one_initcall+0x4a/0x200
[ 531.903303] ? _cond_resched+0x19/0x30
[ 531.903308] ? kmem_cache_alloc_trace+0x19c/0x230
[ 531.903315] do_init_module+0x62/0x250
[ 531.903319] load_module+0x10f0/0x1240
[ 531.903327] __do_sys_finit_module+0xbe/0x120
[ 531.903331] ? __do_sys_finit_module+0xbe/0x120
[ 531.903337] __x64_sys_finit_module+0x1a/0x20
[ 531.903342] do_syscall_64+0x57/0x1b0
[ 531.903347] entry_SYSCALL_64_after_hwframe+0x44/0xa9
最后我怎么能把数字(比如长)作为数据?我需要解析还是什么?
解决方案
的摘要大小为sha1
160 位。分配适当的缓冲区大小。
u8 digest[20];
摘要不是以零结尾的字符串 - 您不能使用%s
它来打印它。遍历字节并以您喜欢的表示形式打印它。
printk("digest: ");
for (size_t i = 0; i < 20; ++i) {
printk("%02x", digest[i]);
}
printk("\n");
请注意,字符串文字是不可变的,请执行以下操作:
const char *hash_alg_name = "sha1";
推荐阅读
- javascript - 事件侦听器即使在 chrome 上也不起作用?
- python - 无法使用 Selenium 提交 drupal 菜单添加表单
- docker - Kubernetes 中的 IBM MQ 统一集群
- sql - 找不到解决三张表和连接操作相关问题的方法
- java - curl --cert 使用了错误的证书
- javascript - setTimout() ajax 请求不成功
- cin - 为什么在我写入并关闭该文件后我不能从该文件中读取?
- bazel - Bazel 是否支持枚举传递依赖项和依赖项存储库位置?
- elasticsearch - 如何过滤来自请求正文而不是请求 url 的 elasticsearch 响应?
- c# - 如何使用 c# Litedb (noSQL) 更改数据库位置?