]>
Commit | Line | Data |
---|---|---|
3b72c814 SM |
1 | Code Examples |
2 | ============= | |
3 | ||
4 | Code Example For Symmetric Key Cipher Operation | |
5 | ----------------------------------------------- | |
6 | ||
03d66cfa EB |
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. | |
3b72c814 | 10 | |
03d66cfa | 11 | :: |
3b72c814 | 12 | |
3b72c814 SM |
13 | static int test_skcipher(void) |
14 | { | |
03d66cfa EB |
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; | |
24 | ||
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 | */ | |
32 | ||
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 | } | |
38 | ||
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 | } | |
45 | ||
46 | /* Allocate a request object */ | |
47 | req = skcipher_request_alloc(tfm, GFP_KERNEL); | |
48 | if (!req) { | |
49 | err = -ENOMEM; | |
50 | goto out; | |
51 | } | |
52 | ||
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); | |
60 | ||
61 | /* Initialize the IV */ | |
62 | get_random_bytes(iv, sizeof(iv)); | |
63 | ||
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 | } | |
83 | ||
84 | pr_debug("Encryption was successful\n"); | |
3b72c814 | 85 | out: |
03d66cfa | 86 | crypto_free_skcipher(tfm); |
3b72c814 | 87 | skcipher_request_free(req); |
03d66cfa EB |
88 | kfree(data); |
89 | return err; | |
3b72c814 SM |
90 | } |
91 | ||
92 | ||
93 | Code Example For Use of Operational State Memory With SHASH | |
94 | ----------------------------------------------------------- | |
95 | ||
96 | :: | |
97 | ||
98 | ||
99 | struct sdesc { | |
100 | struct shash_desc shash; | |
101 | char ctx[]; | |
102 | }; | |
103 | ||
ea644b8c | 104 | static struct sdesc *init_sdesc(struct crypto_shash *alg) |
3b72c814 | 105 | { |
ea644b8c | 106 | struct sdesc *sdesc; |
3b72c814 SM |
107 | int size; |
108 | ||
109 | size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); | |
110 | sdesc = kmalloc(size, GFP_KERNEL); | |
111 | if (!sdesc) | |
112 | return ERR_PTR(-ENOMEM); | |
113 | sdesc->shash.tfm = alg; | |
3b72c814 SM |
114 | return sdesc; |
115 | } | |
116 | ||
ea644b8c KK |
117 | static int calc_hash(struct crypto_shash *alg, |
118 | const unsigned char *data, unsigned int datalen, | |
119 | unsigned char *digest) | |
120 | { | |
121 | struct sdesc *sdesc; | |
3b72c814 SM |
122 | int ret; |
123 | ||
124 | sdesc = init_sdesc(alg); | |
125 | if (IS_ERR(sdesc)) { | |
ea644b8c | 126 | pr_info("can't alloc sdesc\n"); |
3b72c814 SM |
127 | return PTR_ERR(sdesc); |
128 | } | |
129 | ||
130 | ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); | |
131 | kfree(sdesc); | |
132 | return ret; | |
133 | } | |
134 | ||
ea644b8c KK |
135 | static int test_hash(const unsigned char *data, unsigned int datalen, |
136 | unsigned char *digest) | |
137 | { | |
138 | struct crypto_shash *alg; | |
139 | char *hash_alg_name = "sha1-padlock-nano"; | |
140 | int ret; | |
141 | ||
85d7311f | 142 | alg = crypto_alloc_shash(hash_alg_name, 0, 0); |
ea644b8c KK |
143 | if (IS_ERR(alg)) { |
144 | pr_info("can't alloc alg %s\n", hash_alg_name); | |
145 | return PTR_ERR(alg); | |
146 | } | |
147 | ret = calc_hash(alg, data, datalen, digest); | |
148 | crypto_free_shash(alg); | |
149 | return ret; | |
150 | } | |
151 | ||
3b72c814 SM |
152 | |
153 | Code Example For Random Number Generator Usage | |
154 | ---------------------------------------------- | |
155 | ||
156 | :: | |
157 | ||
158 | ||
159 | static int get_random_numbers(u8 *buf, unsigned int len) | |
160 | { | |
ea644b8c KK |
161 | struct crypto_rng *rng = NULL; |
162 | char *drbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */ | |
3b72c814 SM |
163 | int ret; |
164 | ||
165 | if (!buf || !len) { | |
166 | pr_debug("No output buffer provided\n"); | |
167 | return -EINVAL; | |
168 | } | |
169 | ||
170 | rng = crypto_alloc_rng(drbg, 0, 0); | |
171 | if (IS_ERR(rng)) { | |
172 | pr_debug("could not allocate RNG handle for %s\n", drbg); | |
ea644b8c | 173 | return PTR_ERR(rng); |
3b72c814 SM |
174 | } |
175 | ||
176 | ret = crypto_rng_get_bytes(rng, buf, len); | |
177 | if (ret < 0) | |
178 | pr_debug("generation of random numbers failed\n"); | |
179 | else if (ret == 0) | |
180 | pr_debug("RNG returned no data"); | |
181 | else | |
182 | pr_debug("RNG returned %d bytes of data\n", ret); | |
183 | ||
184 | out: | |
185 | crypto_free_rng(rng); | |
186 | return ret; | |
187 | } |