mirror of
https://github.com/sysprog21/lkmpg.git
synced 2024-11-25 09:41:47 +08:00
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.
This commit is contained in:
parent
1d38d2ed19
commit
f5893d8140
|
@ -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
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* cryptosha256.c
|
||||
*/
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#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");
|
|
@ -1,199 +0,0 @@
|
|||
/*
|
||||
* cryptosk.c
|
||||
*/
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
#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");
|
37
lkmpg.tex
37
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.
|
||||
|
|
Loading…
Reference in New Issue
Block a user