1 Code Examples 1 Code Examples 2 ============= 2 ============= 3 3 4 Code Example For Symmetric Key Cipher Operatio 4 Code Example For Symmetric Key Cipher Operation 5 ---------------------------------------------- 5 ----------------------------------------------- 6 6 7 This code encrypts some data with AES-256-XTS. << 8 all inputs are random bytes, the encryption is << 9 assumed the code is running in a context where << 10 << 11 :: 7 :: 12 8 13 static int test_skcipher(void) !! 9 >> 10 struct tcrypt_result { >> 11 struct completion completion; >> 12 int err; >> 13 }; >> 14 >> 15 /* tie all data structures together */ >> 16 struct skcipher_def { >> 17 struct scatterlist sg; >> 18 struct crypto_skcipher *tfm; >> 19 struct skcipher_request *req; >> 20 struct tcrypt_result result; >> 21 }; >> 22 >> 23 /* Callback function */ >> 24 static void test_skcipher_cb(struct crypto_async_request *req, int error) 14 { 25 { 15 struct crypto_skcipher *tfm = NULL !! 26 struct tcrypt_result *result = req->data; 16 struct skcipher_request *req = NUL << 17 u8 *data = NULL; << 18 const size_t datasize = 512; /* da << 19 struct scatterlist sg; << 20 DECLARE_CRYPTO_WAIT(wait); << 21 u8 iv[16]; /* AES-256-XTS takes a << 22 u8 key[64]; /* AES-256-XTS takes a << 23 int err; << 24 << 25 /* << 26 * Allocate a tfm (a transformatio << 27 * << 28 * In real-world use, a tfm and ke << 29 * encryption/decryption operation << 30 * single encryption operation wit << 31 */ << 32 << 33 tfm = crypto_alloc_skcipher("xts(a << 34 if (IS_ERR(tfm)) { << 35 pr_err("Error allocating x << 36 return PTR_ERR(tfm); << 37 } << 38 27 39 get_random_bytes(key, sizeof(key)) !! 28 if (error == -EINPROGRESS) 40 err = crypto_skcipher_setkey(tfm, !! 29 return; 41 if (err) { !! 30 result->err = error; 42 pr_err("Error setting key: !! 31 complete(&result->completion); 43 goto out; !! 32 pr_info("Encryption finished successfully\n"); 44 } !! 33 } 45 34 46 /* Allocate a request object */ !! 35 /* Perform cipher operation */ 47 req = skcipher_request_alloc(tfm, !! 36 static unsigned int test_skcipher_encdec(struct skcipher_def *sk, 48 if (!req) { !! 37 int enc) 49 err = -ENOMEM; !! 38 { 50 goto out; !! 39 int rc = 0; 51 } << 52 40 53 /* Prepare the input data */ !! 41 if (enc) 54 data = kmalloc(datasize, GFP_KERNE !! 42 rc = crypto_skcipher_encrypt(sk->req); 55 if (!data) { !! 43 else 56 err = -ENOMEM; !! 44 rc = crypto_skcipher_decrypt(sk->req); 57 goto out; !! 45 >> 46 switch (rc) { >> 47 case 0: >> 48 break; >> 49 case -EINPROGRESS: >> 50 case -EBUSY: >> 51 rc = wait_for_completion_interruptible( >> 52 &sk->result.completion); >> 53 if (!rc && !sk->result.err) { >> 54 reinit_completion(&sk->result.completion); >> 55 break; 58 } 56 } 59 get_random_bytes(data, datasize); !! 57 default: >> 58 pr_info("skcipher encrypt returned with %d result %d\n", >> 59 rc, sk->result.err); >> 60 break; >> 61 } >> 62 init_completion(&sk->result.completion); 60 63 61 /* Initialize the IV */ !! 64 return rc; 62 get_random_bytes(iv, sizeof(iv)); !! 65 } 63 66 64 /* !! 67 /* Initialize and trigger cipher operation */ 65 * Encrypt the data in-place. !! 68 static int test_skcipher(void) 66 * !! 69 { 67 * For simplicity, in this example !! 70 struct skcipher_def sk; 68 * before proceeding, even if the !! 71 struct crypto_skcipher *skcipher = NULL; 69 * !! 72 struct skcipher_request *req = NULL; 70 * To decrypt instead of encrypt, !! 73 char *scratchpad = NULL; 71 * crypto_skcipher_decrypt(). !! 74 char *ivdata = NULL; 72 */ !! 75 unsigned char key[32]; 73 sg_init_one(&sg, data, datasize); !! 76 int ret = -EFAULT; 74 skcipher_request_set_callback(req, !! 77 75 !! 78 skcipher = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0); 76 cryp !! 79 if (IS_ERR(skcipher)) { 77 skcipher_request_set_crypt(req, &s !! 80 pr_info("could not allocate skcipher handle\n"); 78 err = crypto_wait_req(crypto_skcip !! 81 return PTR_ERR(skcipher); 79 if (err) { !! 82 } 80 pr_err("Error encrypting d !! 83 81 goto out; !! 84 req = skcipher_request_alloc(skcipher, GFP_KERNEL); 82 } !! 85 if (!req) { >> 86 pr_info("could not allocate skcipher request\n"); >> 87 ret = -ENOMEM; >> 88 goto out; >> 89 } >> 90 >> 91 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, >> 92 test_skcipher_cb, >> 93 &sk.result); >> 94 >> 95 /* AES 256 with random key */ >> 96 get_random_bytes(&key, 32); >> 97 if (crypto_skcipher_setkey(skcipher, key, 32)) { >> 98 pr_info("key could not be set\n"); >> 99 ret = -EAGAIN; >> 100 goto out; >> 101 } >> 102 >> 103 /* IV will be random */ >> 104 ivdata = kmalloc(16, GFP_KERNEL); >> 105 if (!ivdata) { >> 106 pr_info("could not allocate ivdata\n"); >> 107 goto out; >> 108 } >> 109 get_random_bytes(ivdata, 16); >> 110 >> 111 /* Input data will be random */ >> 112 scratchpad = kmalloc(16, GFP_KERNEL); >> 113 if (!scratchpad) { >> 114 pr_info("could not allocate scratchpad\n"); >> 115 goto out; >> 116 } >> 117 get_random_bytes(scratchpad, 16); >> 118 >> 119 sk.tfm = skcipher; >> 120 sk.req = req; >> 121 >> 122 /* We encrypt one block */ >> 123 sg_init_one(&sk.sg, scratchpad, 16); >> 124 skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata); >> 125 init_completion(&sk.result.completion); >> 126 >> 127 /* encrypt data */ >> 128 ret = test_skcipher_encdec(&sk, 1); >> 129 if (ret) >> 130 goto out; >> 131 >> 132 pr_info("Encryption triggered successfully\n"); 83 133 84 pr_debug("Encryption was successfu << 85 out: 134 out: 86 crypto_free_skcipher(tfm); !! 135 if (skcipher) >> 136 crypto_free_skcipher(skcipher); >> 137 if (req) 87 skcipher_request_free(req); 138 skcipher_request_free(req); 88 kfree(data); !! 139 if (ivdata) 89 return err; !! 140 kfree(ivdata); >> 141 if (scratchpad) >> 142 kfree(scratchpad); >> 143 return ret; 90 } 144 } 91 145 92 146 93 Code Example For Use of Operational State Memo 147 Code Example For Use of Operational State Memory With SHASH 94 ---------------------------------------------- 148 ----------------------------------------------------------- 95 149 96 :: 150 :: 97 151 98 152 99 struct sdesc { 153 struct sdesc { 100 struct shash_desc shash; 154 struct shash_desc shash; 101 char ctx[]; 155 char ctx[]; 102 }; 156 }; 103 157 104 static struct sdesc *init_sdesc(struct cry 158 static struct sdesc *init_sdesc(struct crypto_shash *alg) 105 { 159 { 106 struct sdesc *sdesc; 160 struct sdesc *sdesc; 107 int size; 161 int size; 108 162 109 size = sizeof(struct shash_desc) + cry 163 size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); 110 sdesc = kmalloc(size, GFP_KERNEL); 164 sdesc = kmalloc(size, GFP_KERNEL); 111 if (!sdesc) 165 if (!sdesc) 112 return ERR_PTR(-ENOMEM); 166 return ERR_PTR(-ENOMEM); 113 sdesc->shash.tfm = alg; 167 sdesc->shash.tfm = alg; >> 168 sdesc->shash.flags = 0x0; 114 return sdesc; 169 return sdesc; 115 } 170 } 116 171 117 static int calc_hash(struct crypto_shash * 172 static int calc_hash(struct crypto_shash *alg, 118 const unsigned char *data, un 173 const unsigned char *data, unsigned int datalen, 119 unsigned char *digest) 174 unsigned char *digest) 120 { 175 { 121 struct sdesc *sdesc; 176 struct sdesc *sdesc; 122 int ret; 177 int ret; 123 178 124 sdesc = init_sdesc(alg); 179 sdesc = init_sdesc(alg); 125 if (IS_ERR(sdesc)) { 180 if (IS_ERR(sdesc)) { 126 pr_info("can't alloc sdesc\n"); 181 pr_info("can't alloc sdesc\n"); 127 return PTR_ERR(sdesc); 182 return PTR_ERR(sdesc); 128 } 183 } 129 184 130 ret = crypto_shash_digest(&sdesc->shas 185 ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); 131 kfree(sdesc); 186 kfree(sdesc); 132 return ret; 187 return ret; 133 } 188 } 134 189 135 static int test_hash(const unsigned char * 190 static int test_hash(const unsigned char *data, unsigned int datalen, 136 unsigned char *digest) 191 unsigned char *digest) 137 { 192 { 138 struct crypto_shash *alg; 193 struct crypto_shash *alg; 139 char *hash_alg_name = "sha1-padlock-na 194 char *hash_alg_name = "sha1-padlock-nano"; 140 int ret; 195 int ret; 141 196 142 alg = crypto_alloc_shash(hash_alg_name !! 197 alg = crypto_alloc_shash(hash_alg_name, CRYPTO_ALG_TYPE_SHASH, 0); 143 if (IS_ERR(alg)) { 198 if (IS_ERR(alg)) { 144 pr_info("can't alloc alg %s\n" 199 pr_info("can't alloc alg %s\n", hash_alg_name); 145 return PTR_ERR(alg); 200 return PTR_ERR(alg); 146 } 201 } 147 ret = calc_hash(alg, data, datalen, di 202 ret = calc_hash(alg, data, datalen, digest); 148 crypto_free_shash(alg); 203 crypto_free_shash(alg); 149 return ret; 204 return ret; 150 } 205 } 151 206 152 207 153 Code Example For Random Number Generator Usage 208 Code Example For Random Number Generator Usage 154 ---------------------------------------------- 209 ---------------------------------------------- 155 210 156 :: 211 :: 157 212 158 213 159 static int get_random_numbers(u8 *buf, uns 214 static int get_random_numbers(u8 *buf, unsigned int len) 160 { 215 { 161 struct crypto_rng *rng = NULL; 216 struct crypto_rng *rng = NULL; 162 char *drbg = "drbg_nopr_sha256"; /* Ha 217 char *drbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */ 163 int ret; 218 int ret; 164 219 165 if (!buf || !len) { 220 if (!buf || !len) { 166 pr_debug("No output buffer provide 221 pr_debug("No output buffer provided\n"); 167 return -EINVAL; 222 return -EINVAL; 168 } 223 } 169 224 170 rng = crypto_alloc_rng(drbg, 0, 0); 225 rng = crypto_alloc_rng(drbg, 0, 0); 171 if (IS_ERR(rng)) { 226 if (IS_ERR(rng)) { 172 pr_debug("could not allocate RNG h 227 pr_debug("could not allocate RNG handle for %s\n", drbg); 173 return PTR_ERR(rng); 228 return PTR_ERR(rng); 174 } 229 } 175 230 176 ret = crypto_rng_get_bytes(rng, buf, l 231 ret = crypto_rng_get_bytes(rng, buf, len); 177 if (ret < 0) 232 if (ret < 0) 178 pr_debug("generation of random num 233 pr_debug("generation of random numbers failed\n"); 179 else if (ret == 0) 234 else if (ret == 0) 180 pr_debug("RNG returned no data"); 235 pr_debug("RNG returned no data"); 181 else 236 else 182 pr_debug("RNG returned %d bytes of 237 pr_debug("RNG returned %d bytes of data\n", ret); 183 238 184 out: 239 out: 185 crypto_free_rng(rng); 240 crypto_free_rng(rng); 186 return ret; 241 return ret; 187 } 242 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.