1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Chapter&#160;6.&#160;Code Examples</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Linux Kernel Crypto API"><link rel="up" href="index.html" title="Linux Kernel Crypto API"><link rel="prev" href="API-crypto-rng-seedsize.html" title="crypto_rng_seedsize"><link rel="next" href="ch06s02.html" title="Code Example For Synchronous Block Cipher Operation"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter&#160;6.&#160;Code Examples</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="API-crypto-rng-seedsize.html">Prev</a>&#160;</td><th width="60%" align="center">&#160;</th><td width="20%" align="right">&#160;<a accesskey="n" href="ch06s02.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="Code"></a>Chapter&#160;6.&#160;Code Examples</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="Code.html#idp1098420372">Code Example For Asynchronous Block Cipher Operation</a></span></dt><dt><span class="sect1"><a href="ch06s02.html">Code Example For Synchronous Block Cipher Operation</a></span></dt><dt><span class="sect1"><a href="ch06s03.html">Code Example For Use of Operational State Memory With SHASH</a></span></dt><dt><span class="sect1"><a href="ch06s04.html">Code Example For Random Number Generator Usage</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp1098420372"></a>Code Example For Asynchronous Block Cipher Operation</h2></div></div></div><pre class="programlisting">
2
3struct tcrypt_result {
4	struct completion completion;
5	int err;
6};
7
8/* tie all data structures together */
9struct ablkcipher_def {
10	struct scatterlist sg;
11	struct crypto_ablkcipher *tfm;
12	struct ablkcipher_request *req;
13	struct tcrypt_result result;
14};
15
16/* Callback function */
17static void test_ablkcipher_cb(struct crypto_async_request *req, int error)
18{
19	struct tcrypt_result *result = req-&gt;data;
20
21	if (error == -EINPROGRESS)
22		return;
23	result-&gt;err = error;
24	complete(&amp;result-&gt;completion);
25	pr_info("Encryption finished successfully\n");
26}
27
28/* Perform cipher operation */
29static unsigned int test_ablkcipher_encdec(struct ablkcipher_def *ablk,
30					   int enc)
31{
32	int rc = 0;
33
34	if (enc)
35		rc = crypto_ablkcipher_encrypt(ablk-&gt;req);
36	else
37		rc = crypto_ablkcipher_decrypt(ablk-&gt;req);
38
39	switch (rc) {
40	case 0:
41		break;
42	case -EINPROGRESS:
43	case -EBUSY:
44		rc = wait_for_completion_interruptible(
45			&amp;ablk-&gt;result.completion);
46		if (!rc &amp;&amp; !ablk-&gt;result.err) {
47			reinit_completion(&amp;ablk-&gt;result.completion);
48			break;
49		}
50	default:
51		pr_info("ablkcipher encrypt returned with %d result %d\n",
52		       rc, ablk-&gt;result.err);
53		break;
54	}
55	init_completion(&amp;ablk-&gt;result.completion);
56
57	return rc;
58}
59
60/* Initialize and trigger cipher operation */
61static int test_ablkcipher(void)
62{
63	struct ablkcipher_def ablk;
64	struct crypto_ablkcipher *ablkcipher = NULL;
65	struct ablkcipher_request *req = NULL;
66	char *scratchpad = NULL;
67	char *ivdata = NULL;
68	unsigned char key[32];
69	int ret = -EFAULT;
70
71	ablkcipher = crypto_alloc_ablkcipher("cbc-aes-aesni", 0, 0);
72	if (IS_ERR(ablkcipher)) {
73		pr_info("could not allocate ablkcipher handle\n");
74		return PTR_ERR(ablkcipher);
75	}
76
77	req = ablkcipher_request_alloc(ablkcipher, GFP_KERNEL);
78	if (IS_ERR(req)) {
79		pr_info("could not allocate request queue\n");
80		ret = PTR_ERR(req);
81		goto out;
82	}
83
84	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
85					test_ablkcipher_cb,
86					&amp;ablk.result);
87
88	/* AES 256 with random key */
89	get_random_bytes(&amp;key, 32);
90	if (crypto_ablkcipher_setkey(ablkcipher, key, 32)) {
91		pr_info("key could not be set\n");
92		ret = -EAGAIN;
93		goto out;
94	}
95
96	/* IV will be random */
97	ivdata = kmalloc(16, GFP_KERNEL);
98	if (!ivdata) {
99		pr_info("could not allocate ivdata\n");
100		goto out;
101	}
102	get_random_bytes(ivdata, 16);
103
104	/* Input data will be random */
105	scratchpad = kmalloc(16, GFP_KERNEL);
106	if (!scratchpad) {
107		pr_info("could not allocate scratchpad\n");
108		goto out;
109	}
110	get_random_bytes(scratchpad, 16);
111
112	ablk.tfm = ablkcipher;
113	ablk.req = req;
114
115	/* We encrypt one block */
116	sg_init_one(&amp;ablk.sg, scratchpad, 16);
117	ablkcipher_request_set_crypt(req, &amp;ablk.sg, &amp;ablk.sg, 16, ivdata);
118	init_completion(&amp;ablk.result.completion);
119
120	/* encrypt data */
121	ret = test_ablkcipher_encdec(&amp;ablk, 1);
122	if (ret)
123		goto out;
124
125	pr_info("Encryption triggered successfully\n");
126
127out:
128	if (ablkcipher)
129		crypto_free_ablkcipher(ablkcipher);
130	if (req)
131		ablkcipher_request_free(req);
132	if (ivdata)
133		kfree(ivdata);
134	if (scratchpad)
135		kfree(scratchpad);
136	return ret;
137}
138    </pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="API-crypto-rng-seedsize.html">Prev</a>&#160;</td><td width="20%" align="center">&#160;</td><td width="40%" align="right">&#160;<a accesskey="n" href="ch06s02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="phrase">crypto_rng_seedsize</span>&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Code Example For Synchronous Block Cipher Operation</td></tr></table></div></body></html>
139