Я хочу использовать криптографический 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
Наконец, как я могу поместить число (например, long) в качестве данных? Нужен ли мне синтаксический анализ?