1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Chapter 6. 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 6. Code Examples</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="API-crypto-rng-seedsize.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <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 6. 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->data; 20 21 if (error == -EINPROGRESS) 22 return; 23 result->err = error; 24 complete(&result->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->req); 36 else 37 rc = crypto_ablkcipher_decrypt(ablk->req); 38 39 switch (rc) { 40 case 0: 41 break; 42 case -EINPROGRESS: 43 case -EBUSY: 44 rc = wait_for_completion_interruptible( 45 &ablk->result.completion); 46 if (!rc && !ablk->result.err) { 47 reinit_completion(&ablk->result.completion); 48 break; 49 } 50 default: 51 pr_info("ablkcipher encrypt returned with %d result %d\n", 52 rc, ablk->result.err); 53 break; 54 } 55 init_completion(&ablk->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 &ablk.result); 87 88 /* AES 256 with random key */ 89 get_random_bytes(&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(&ablk.sg, scratchpad, 16); 117 ablkcipher_request_set_crypt(req, &ablk.sg, &ablk.sg, 16, ivdata); 118 init_completion(&ablk.result.completion); 119 120 /* encrypt data */ 121 ret = test_ablkcipher_encdec(&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> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <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> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Code Example For Synchronous Block Cipher Operation</td></tr></table></div></body></html> 139