如何测试Linux文档中的加密API样本?

问题描述 投票:0回答:1

我想使用加密API,我找到了linux内核的相关文档。

https:/www.kernel.orgdochtmllatestcryptoapi-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)作为数据?我需要解析还是什么?

c linux-kernel cryptoapi
1个回答
1
投票

摘要大小为 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";
© www.soinside.com 2019 - 2024. All rights reserved.