hc
2024-05-10 10ebd8556b7990499c896a550e3d416b444211e6
kernel/Documentation/crypto/api-samples.rst
....@@ -4,111 +4,89 @@
44 Code Example For Symmetric Key Cipher Operation
55 -----------------------------------------------
66
7
+This code encrypts some data with AES-256-XTS. For sake of example,
8
+all inputs are random bytes, the encryption is done in-place, and it's
9
+assumed the code is running in a context where it can sleep.
10
+
711 ::
812
9
-
10
- /* tie all data structures together */
11
- struct skcipher_def {
12
- struct scatterlist sg;
13
- struct crypto_skcipher *tfm;
14
- struct skcipher_request *req;
15
- struct crypto_wait wait;
16
- };
17
-
18
- /* Perform cipher operation */
19
- static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
20
- int enc)
21
- {
22
- int rc;
23
-
24
- if (enc)
25
- rc = crypto_wait_req(crypto_skcipher_encrypt(sk->req), &sk->wait);
26
- else
27
- rc = crypto_wait_req(crypto_skcipher_decrypt(sk->req), &sk->wait);
28
-
29
- if (rc)
30
- pr_info("skcipher encrypt returned with result %d\n", rc);
31
-
32
- return rc;
33
- }
34
-
35
- /* Initialize and trigger cipher operation */
3613 static int test_skcipher(void)
3714 {
38
- struct skcipher_def sk;
39
- struct crypto_skcipher *skcipher = NULL;
40
- struct skcipher_request *req = NULL;
41
- char *scratchpad = NULL;
42
- char *ivdata = NULL;
43
- unsigned char key[32];
44
- int ret = -EFAULT;
15
+ struct crypto_skcipher *tfm = NULL;
16
+ struct skcipher_request *req = NULL;
17
+ u8 *data = NULL;
18
+ const size_t datasize = 512; /* data size in bytes */
19
+ struct scatterlist sg;
20
+ DECLARE_CRYPTO_WAIT(wait);
21
+ u8 iv[16]; /* AES-256-XTS takes a 16-byte IV */
22
+ u8 key[64]; /* AES-256-XTS takes a 64-byte key */
23
+ int err;
4524
46
- skcipher = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0);
47
- if (IS_ERR(skcipher)) {
48
- pr_info("could not allocate skcipher handle\n");
49
- return PTR_ERR(skcipher);
50
- }
25
+ /*
26
+ * Allocate a tfm (a transformation object) and set the key.
27
+ *
28
+ * In real-world use, a tfm and key are typically used for many
29
+ * encryption/decryption operations. But in this example, we'll just do a
30
+ * single encryption operation with it (which is not very efficient).
31
+ */
5132
52
- req = skcipher_request_alloc(skcipher, GFP_KERNEL);
53
- if (!req) {
54
- pr_info("could not allocate skcipher request\n");
55
- ret = -ENOMEM;
56
- goto out;
57
- }
33
+ tfm = crypto_alloc_skcipher("xts(aes)", 0, 0);
34
+ if (IS_ERR(tfm)) {
35
+ pr_err("Error allocating xts(aes) handle: %ld\n", PTR_ERR(tfm));
36
+ return PTR_ERR(tfm);
37
+ }
5838
59
- skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
60
- crypto_req_done,
61
- &sk.wait);
39
+ get_random_bytes(key, sizeof(key));
40
+ err = crypto_skcipher_setkey(tfm, key, sizeof(key));
41
+ if (err) {
42
+ pr_err("Error setting key: %d\n", err);
43
+ goto out;
44
+ }
6245
63
- /* AES 256 with random key */
64
- get_random_bytes(&key, 32);
65
- if (crypto_skcipher_setkey(skcipher, key, 32)) {
66
- pr_info("key could not be set\n");
67
- ret = -EAGAIN;
68
- goto out;
69
- }
46
+ /* Allocate a request object */
47
+ req = skcipher_request_alloc(tfm, GFP_KERNEL);
48
+ if (!req) {
49
+ err = -ENOMEM;
50
+ goto out;
51
+ }
7052
71
- /* IV will be random */
72
- ivdata = kmalloc(16, GFP_KERNEL);
73
- if (!ivdata) {
74
- pr_info("could not allocate ivdata\n");
75
- goto out;
76
- }
77
- get_random_bytes(ivdata, 16);
53
+ /* Prepare the input data */
54
+ data = kmalloc(datasize, GFP_KERNEL);
55
+ if (!data) {
56
+ err = -ENOMEM;
57
+ goto out;
58
+ }
59
+ get_random_bytes(data, datasize);
7860
79
- /* Input data will be random */
80
- scratchpad = kmalloc(16, GFP_KERNEL);
81
- if (!scratchpad) {
82
- pr_info("could not allocate scratchpad\n");
83
- goto out;
84
- }
85
- get_random_bytes(scratchpad, 16);
61
+ /* Initialize the IV */
62
+ get_random_bytes(iv, sizeof(iv));
8663
87
- sk.tfm = skcipher;
88
- sk.req = req;
64
+ /*
65
+ * Encrypt the data in-place.
66
+ *
67
+ * For simplicity, in this example we wait for the request to complete
68
+ * before proceeding, even if the underlying implementation is asynchronous.
69
+ *
70
+ * To decrypt instead of encrypt, just change crypto_skcipher_encrypt() to
71
+ * crypto_skcipher_decrypt().
72
+ */
73
+ sg_init_one(&sg, data, datasize);
74
+ skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
75
+ CRYPTO_TFM_REQ_MAY_SLEEP,
76
+ crypto_req_done, &wait);
77
+ skcipher_request_set_crypt(req, &sg, &sg, datasize, iv);
78
+ err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
79
+ if (err) {
80
+ pr_err("Error encrypting data: %d\n", err);
81
+ goto out;
82
+ }
8983
90
- /* We encrypt one block */
91
- sg_init_one(&sk.sg, scratchpad, 16);
92
- skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata);
93
- crypto_init_wait(&sk.wait);
94
-
95
- /* encrypt data */
96
- ret = test_skcipher_encdec(&sk, 1);
97
- if (ret)
98
- goto out;
99
-
100
- pr_info("Encryption triggered successfully\n");
101
-
84
+ pr_debug("Encryption was successful\n");
10285 out:
103
- if (skcipher)
104
- crypto_free_skcipher(skcipher);
105
- if (req)
86
+ crypto_free_skcipher(tfm);
10687 skcipher_request_free(req);
107
- if (ivdata)
108
- kfree(ivdata);
109
- if (scratchpad)
110
- kfree(scratchpad);
111
- return ret;
88
+ kfree(data);
89
+ return err;
11290 }
11391
11492
....@@ -133,7 +111,6 @@
133111 if (!sdesc)
134112 return ERR_PTR(-ENOMEM);
135113 sdesc->shash.tfm = alg;
136
- sdesc->shash.flags = 0x0;
137114 return sdesc;
138115 }
139116