Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@vkobel
Last active August 19, 2023 13:35
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vkobel/3100cea3625ca765e4153782314bd03d to your computer and use it in GitHub Desktop.
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)
#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;
}
@vkobel
Copy link
Author

vkobel commented Apr 24, 2020

@ZYV037
Copy link

ZYV037 commented Feb 5, 2021

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) ;

@loneicewolf
Copy link

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