How to compute SHA1 of an array in Linux kernel

2019-05-09 23:26发布

问题:

I'm trying to compute SHA1 of an integer array in the Linux kernel. I have gone through crypto.c/crypto.h and security/integrity/ima/ima_crypto.c but I can't figure out how to init and then update the SHA1 computer. Can someone point me to a tutorial or guide on how to go about doing this?

回答1:

There's a pretty good introduction to the linux cryptography api in Documentation/crypto/api-intro.txt. Also check out fs/ecryptfs/crypto.c for a real-life example of how the functions are used.

Here's a quick summary though to get you start:

Step 1: Declaration

Create some local variables:

struct scatterlist sg;
struct hash_desc desc;
char *plaintext = "plaintext goes here";
size_t len = strlen(plaintext);
u8 hashval[20];
  • A struct scatterlist is used to hold your plaintext in a format the crypto.h functions can understand, while a struct hash_desc is used to configure the hashing.
  • The variable plaintext holds our plaintext string, while hashval will hold the hash of our plaintext.
  • Finally, len holds the length the plaintext string.

Note that while I'm using ASCII plaintext in this example, you can pass an integer array as well -- just store the total memory size in len and replace every instance of plaintext with your integer array:

int myarr[4] = { 1, 3, 3, 7 };
size_t len = sizeof(myarr);

Be careful though: an int element generally has a size greater than a byte, so storing integer values in an int array won't have the same internal representation as a char array -- you may end up with null bytes as padding in between values.

Furthermore, if your intention is to hash the ASCII representation of your integers, you will have to first convert the values in your array to a string character sequence (perhaps using sprintf).

Step 2: Initialization

Initialize sg and desc:

sg_init_one(&sg, plaintext, len);
desc.tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);

Notice that "sha1" is passed to crypto_alloc_hash; this can be set to "md5" for MD5 hashing, or any other supported string in order to use the respective hashing method.

Step 3: Hashing

Now perform the hashing with three function calls:

crypto_hash_init(&desc);
crypto_hash_update(&desc, &sg, len);
crypto_hash_final(&desc, hashval);
  • crypto_hash_init configures the hashing engine according to the supplied struct hash_desc.
  • crypto_hash_update performs the actual hashing method on the plaintext.
  • Finally, crypto_hash_final copies the hash to a character array.

Step 4: Cleanup

Free allocated memory held by desc.tfm:

crypto_free_hash(desc.tfm);

See also

how to use CryptoAPI in the linux kernel 2.6