Last active
March 14, 2025 03:55
-
-
Save vkobel/3100cea3625ca765e4153782314bd03d to your computer and use it in GitHub Desktop.
Example of using the Linux Kernel Crypto API for SHA256 hashing (tested with 5.6)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/module.h> | |
#include <crypto/hash.h> | |
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 do_sha256(const unsigned char *data, unsigned char *out_digest) | |
{ | |
struct crypto_shash *alg; | |
char *hash_alg_name = "sha256"; | |
unsigned int datalen = sizeof(data) - 1; // remove the null byte | |
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); | |
} | |
calc_hash(alg, data, datalen, out_digest); | |
// Very dirty print of 8 first bytes for comparaison with sha256sum | |
printk(KERN_INFO "HASH(%s, %i): %02x%02x%02x%02x%02x%02x%02x%02x\n", | |
data, datalen, out_digest[0], out_digest[1], out_digest[2], out_digest[3], out_digest[4], | |
out_digest[5], out_digest[6], out_digest[7]); | |
crypto_free_shash(alg); | |
return 0; | |
} | |
static int __init module_start(void) | |
{ | |
unsigned char *digest; | |
digest = kmalloc(256, GFP_KERNEL); | |
if(digest < 0) | |
return -ENOMEM; | |
do_sha256("Test string", digest); | |
return -EPERM; | |
return 0; | |
} |
static int do_sha256(const unsigned char *data, unsigned char *out_digest)
{
struct crypto_shash *alg;
char *hash_alg_name = "sha256";
unsigned int datalen = strlen(data) - 1; // remove the null byte
if you want same as /usr/bin/md5 result, you have
datalen = strlen(data) ;
If I could like (if there were a like button) I would've given you 2 a likes up; keep up the good work!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Adapted from https://github.com/torvalds/linux/blob/master/Documentation/crypto/api-samples.rst