SHA-1 hash calculate in Kernel.
Bjørn Mork
bjorn at mork.no
Fri Aug 28 04:27:02 EDT 2015
lx <lxlenovostar at gmail.com> writes:
> hi all:
> I built a module for calculate the SHA-1. The code is:
> ##################
> #include <linux/init.h>
> #include <linux/module.h>
> #include <linux/kernel.h>
> #include <linux/crypto.h>
> #include <linux/err.h>
> #include <linux/scatterlist.h>
> MODULE_LICENSE("Dual BSD/GPL");
>
> #define SHA1_LENGTH 20
>
> static int hello_init(void)
> {
> /*
> * http://lxr.oss.org.cn/source/fs/ecryptfs/crypto.c?v=2.6.30
> */
> struct scatterlist sg;
> struct hash_desc desc;
>
> //way 1
> /*
> char *plaintext = "c";
> size_t len = strlen(plaintext);
> */
>
> //way 2
> /*
> char *plaintext = kmalloc(sizeof(char), GFP_KERNEL);
> plaintext = "c";
> size_t len = 1;
> */
>
> // way 3.
> /*
> char plaintext[1] = {'c'};
> size_t len = 1;
> */
>
> // way 4.
> /*
> char *plaintext = (char *)__get_free_page(GFP_KERNEL);
> memcpy(plaintext, "c", 1);
> size_t len = 1;
> */
>
> int rc = 0;
> int i;
> char hashtext[SHA1_LENGTH];
>
> memset(hashtext, 0x00, SHA1_LENGTH);
> printk(KERN_INFO "sha1: %s\n", __FUNCTION__);
>
> sg_init_one(&sg, plaintext, len);
> desc.tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
> desc.flags = 0;
>
> rc = crypto_hash_init(&desc);
> if (rc) {
> printk(KERN_ERR "%s: Error initializing crypto hash; rc = [%d]\n",
> __func__, rc);
> goto out;
> }
> rc = crypto_hash_update(&desc, &sg, len);
> if (rc) {
> printk(KERN_ERR "%s: Error updating crypto hash; rc = [%d]\n",
> __func__, rc);
> goto out;
> }
> rc = crypto_hash_final(&desc, hashtext);
> if (rc) {
> printk(KERN_ERR "%s: Error finalizing crypto hash; rc = [%d]\n",
> __func__, rc);
> goto out;
> }
> crypto_free_hash(desc.tfm);
>
> for (i = 0; i < 20; i++) {
> printk(KERN_INFO "%02x-%d\n", hashtext[i]&0xff, i);
> }
>
> out:
> printk(KERN_INFO "end\n");
> return rc;
> }
>
> static void hello_exit(void)
> {
> printk(KERN_ALERT "Goodbye, cruel world\n");
> }
>
> module_init(hello_init);
> module_exit(hello_exit);
> ##################
> I can just get the right result by way 3 and 4, In way 1 and 2 , I get the
> wrong result,
I suggest you add something like this:
printk(KERN_INFO "plaintext='%c', len=%zu, valid=%s\n", *plaintext, len, virt_addr_valid(plaintext) ? "true" : "false");
and then go figure out the relationship between that and the correct
result :)
Bjørn
More information about the Kernelnewbies
mailing list