From f5893d8140d21773820521ddc7f6080b8f3f29eb Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Tue, 16 Apr 2024 05:39:11 +0800 Subject: [PATCH] Remove the crypto section due to poor maintenance The past content in the crypto section lacks informative descriptions, and there should be a proper procedure to demonstrate how Linux cryptography works. Due to poor maintenance, let's drop the section. --- examples/Makefile | 2 - examples/cryptosha256.c | 68 -------------- examples/cryptosk.c | 199 ---------------------------------------- lkmpg.tex | 37 -------- 4 files changed, 306 deletions(-) delete mode 100644 examples/cryptosha256.c delete mode 100644 examples/cryptosk.c diff --git a/examples/Makefile b/examples/Makefile index c17cce5..2e0dfb9 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -18,8 +18,6 @@ obj-m += sched.o obj-m += chardev2.o obj-m += syscall-steal.o obj-m += intrpt.o -obj-m += cryptosha256.o -obj-m += cryptosk.o obj-m += completions.o obj-m += example_tasklet.o obj-m += devicemodel.o diff --git a/examples/cryptosha256.c b/examples/cryptosha256.c deleted file mode 100644 index 300069b..0000000 --- a/examples/cryptosha256.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * cryptosha256.c - */ -#include -#include - -#define SHA256_LENGTH 32 - -static void show_hash_result(char *plaintext, char *hash_sha256) -{ - int i; - char str[SHA256_LENGTH * 2 + 1]; - - pr_info("sha256 test for string: \"%s\"\n", plaintext); - for (i = 0; i < SHA256_LENGTH; i++) - sprintf(&str[i * 2], "%02x", (unsigned char)hash_sha256[i]); - str[i * 2] = 0; - pr_info("%s\n", str); -} - -static int __init cryptosha256_init(void) -{ - char *plaintext = "This is a test"; - char hash_sha256[SHA256_LENGTH]; - struct crypto_shash *sha256; - struct shash_desc *shash; - - sha256 = crypto_alloc_shash("sha256", 0, 0); - if (IS_ERR(sha256)) { - pr_err( - "%s(): Failed to allocate sha256 algorithm, enable CONFIG_CRYPTO_SHA256 and try again.\n", - __func__); - return -1; - } - - shash = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(sha256), - GFP_KERNEL); - if (!shash) - return -ENOMEM; - - shash->tfm = sha256; - - if (crypto_shash_init(shash)) - return -1; - - if (crypto_shash_update(shash, plaintext, strlen(plaintext))) - return -1; - - if (crypto_shash_final(shash, hash_sha256)) - return -1; - - kfree(shash); - crypto_free_shash(sha256); - - show_hash_result(plaintext, hash_sha256); - - return 0; -} - -static void __exit cryptosha256_exit(void) -{ -} - -module_init(cryptosha256_init); -module_exit(cryptosha256_exit); - -MODULE_DESCRIPTION("sha256 hash test"); -MODULE_LICENSE("GPL"); diff --git a/examples/cryptosk.c b/examples/cryptosk.c deleted file mode 100644 index c46e523..0000000 --- a/examples/cryptosk.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * cryptosk.c - */ -#include -#include -#include -#include -#include - -#define SYMMETRIC_KEY_LENGTH 32 -#define CIPHER_BLOCK_SIZE 16 - -struct tcrypt_result { - struct completion completion; - int err; -}; - -struct skcipher_def { - struct scatterlist sg; - struct crypto_skcipher *tfm; - struct skcipher_request *req; - struct tcrypt_result result; - char *scratchpad; - char *ciphertext; - char *ivdata; -}; - -static struct skcipher_def sk; - -static void test_skcipher_finish(struct skcipher_def *sk) -{ - if (sk->tfm) - crypto_free_skcipher(sk->tfm); - if (sk->req) - skcipher_request_free(sk->req); - if (sk->ivdata) - kfree(sk->ivdata); - if (sk->scratchpad) - kfree(sk->scratchpad); - if (sk->ciphertext) - kfree(sk->ciphertext); -} - -static int test_skcipher_result(struct skcipher_def *sk, int rc) -{ - switch (rc) { - case 0: - break; - case -EINPROGRESS: - case -EBUSY: - rc = wait_for_completion_interruptible(&sk->result.completion); - if (!rc && !sk->result.err) { - reinit_completion(&sk->result.completion); - break; - } - pr_info("skcipher encrypt returned with %d result %d\n", rc, - sk->result.err); - break; - default: - pr_info("skcipher encrypt returned with %d result %d\n", rc, - sk->result.err); - break; - } - - init_completion(&sk->result.completion); - - return rc; -} - -static void test_skcipher_callback(struct crypto_async_request *req, int error) -{ - struct tcrypt_result *result = req->data; - - if (error == -EINPROGRESS) - return; - - result->err = error; - complete(&result->completion); - pr_info("Encryption finished successfully\n"); - - /* decrypt data */ -#if 0 - memset((void*)sk.scratchpad, '-', CIPHER_BLOCK_SIZE); - ret = crypto_skcipher_decrypt(sk.req); - ret = test_skcipher_result(&sk, ret); - if (ret) - return; - - sg_copy_from_buffer(&sk.sg, 1, sk.scratchpad, CIPHER_BLOCK_SIZE); - sk.scratchpad[CIPHER_BLOCK_SIZE-1] = 0; - - pr_info("Decryption request successful\n"); - pr_info("Decrypted: %s\n", sk.scratchpad); -#endif -} - -static int test_skcipher_encrypt(char *plaintext, char *password, - struct skcipher_def *sk) -{ - int ret = -EFAULT; - unsigned char key[SYMMETRIC_KEY_LENGTH]; - - if (!sk->tfm) { - sk->tfm = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0); - if (IS_ERR(sk->tfm)) { - pr_info("could not allocate skcipher handle\n"); - return PTR_ERR(sk->tfm); - } - } - - if (!sk->req) { - sk->req = skcipher_request_alloc(sk->tfm, GFP_KERNEL); - if (!sk->req) { - pr_info("could not allocate skcipher request\n"); - ret = -ENOMEM; - goto out; - } - } - - skcipher_request_set_callback(sk->req, CRYPTO_TFM_REQ_MAY_BACKLOG, - test_skcipher_callback, &sk->result); - - /* clear the key */ - memset((void *)key, '\0', SYMMETRIC_KEY_LENGTH); - - /* Use the world's favourite password */ - sprintf((char *)key, "%s", password); - - /* AES 256 with given symmetric key */ - if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) { - pr_info("key could not be set\n"); - ret = -EAGAIN; - goto out; - } - pr_info("Symmetric key: %s\n", key); - pr_info("Plaintext: %s\n", plaintext); - - if (!sk->ivdata) { - /* see https://en.wikipedia.org/wiki/Initialization_vector */ - sk->ivdata = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL); - if (!sk->ivdata) { - pr_info("could not allocate ivdata\n"); - goto out; - } - get_random_bytes(sk->ivdata, CIPHER_BLOCK_SIZE); - } - - if (!sk->scratchpad) { - /* The text to be encrypted */ - sk->scratchpad = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL); - if (!sk->scratchpad) { - pr_info("could not allocate scratchpad\n"); - goto out; - } - } - sprintf((char *)sk->scratchpad, "%s", plaintext); - - sg_init_one(&sk->sg, sk->scratchpad, CIPHER_BLOCK_SIZE); - skcipher_request_set_crypt(sk->req, &sk->sg, &sk->sg, CIPHER_BLOCK_SIZE, - sk->ivdata); - init_completion(&sk->result.completion); - - /* encrypt data */ - ret = crypto_skcipher_encrypt(sk->req); - ret = test_skcipher_result(sk, ret); - if (ret) - goto out; - - pr_info("Encryption request successful\n"); - -out: - return ret; -} - -static int __init cryptoapi_init(void) -{ - /* The world's favorite password */ - char *password = "password123"; - - sk.tfm = NULL; - sk.req = NULL; - sk.scratchpad = NULL; - sk.ciphertext = NULL; - sk.ivdata = NULL; - - test_skcipher_encrypt("Testing", password, &sk); - return 0; -} - -static void __exit cryptoapi_exit(void) -{ - test_skcipher_finish(&sk); -} - -module_init(cryptoapi_init); -module_exit(cryptoapi_exit); - -MODULE_DESCRIPTION("Symmetric key encryption example"); -MODULE_LICENSE("GPL"); diff --git a/lkmpg.tex b/lkmpg.tex index f4ad87e..4543440 100644 --- a/lkmpg.tex +++ b/lkmpg.tex @@ -1910,43 +1910,6 @@ The example below modifies the previous example to also run an additional task w \samplec{examples/bottomhalf.c} -\section{Crypto} -\label{sec:crypto} -At the dawn of the internet, everybody trusted everybody completely\ldots{}but that did not work out so well. -When this guide was originally written, it was a more innocent era in which almost nobody actually gave a damn about crypto - least of all kernel developers. -That is certainly no longer the case now. -To handle crypto stuff, the kernel has its own API enabling common methods of encryption, decryption and your favourite hash functions. - -\subsection{Hash functions} -\label{sec:hashfunc} - -Calculating and checking the hashes of things is a common operation. -Here is a demonstration of how to calculate a sha256 hash within a kernel module. -To provide the sha256 algorithm support, make sure \cpp|CONFIG_CRYPTO_SHA256| is enabled in kernel. - -\samplec{examples/cryptosha256.c} - -Install the module: - -\begin{codebash} -sudo insmod cryptosha256.ko -sudo dmesg -\end{codebash} - -And you should see that the hash was calculated for the test string. - -Finally, remove the test module: - -\begin{codebash} -sudo rmmod cryptosha256 -\end{codebash} - -\subsection{Symmetric key encryption} -\label{sec:org2fab20b} -Here is an example of symmetrically encrypting a string using the AES algorithm and a password. - -\samplec{examples/cryptosk.c} - \section{Virtual Input Device Driver} \label{sec:vinput} The input device driver is a module that provides a way to communicate with the interaction device via the event.