1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * Key-agreement Protocol Primitives (KPP) |
4 | * |
5 | * Copyright (c) 2016, Intel Corporation |
6 | * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com> |
7 | */ |
8 | |
9 | #ifndef _CRYPTO_KPP_ |
10 | #define _CRYPTO_KPP_ |
11 | |
12 | #include <linux/atomic.h> |
13 | #include <linux/container_of.h> |
14 | #include <linux/crypto.h> |
15 | #include <linux/slab.h> |
16 | |
17 | /** |
18 | * struct kpp_request |
19 | * |
20 | * @base: Common attributes for async crypto requests |
21 | * @src: Source data |
22 | * @dst: Destination data |
23 | * @src_len: Size of the input buffer |
24 | * @dst_len: Size of the output buffer. It needs to be at least |
25 | * as big as the expected result depending on the operation |
26 | * After operation it will be updated with the actual size of the |
27 | * result. In case of error where the dst sgl size was insufficient, |
28 | * it will be updated to the size required for the operation. |
29 | * @__ctx: Start of private context data |
30 | */ |
31 | struct kpp_request { |
32 | struct crypto_async_request base; |
33 | struct scatterlist *src; |
34 | struct scatterlist *dst; |
35 | unsigned int src_len; |
36 | unsigned int dst_len; |
37 | void *__ctx[] CRYPTO_MINALIGN_ATTR; |
38 | }; |
39 | |
40 | /** |
41 | * struct crypto_kpp - user-instantiated object which encapsulate |
42 | * algorithms and core processing logic |
43 | * |
44 | * @reqsize: Request context size required by algorithm |
45 | * implementation |
46 | * @base: Common crypto API algorithm data structure |
47 | */ |
48 | struct crypto_kpp { |
49 | unsigned int reqsize; |
50 | |
51 | struct crypto_tfm base; |
52 | }; |
53 | |
54 | /* |
55 | * struct crypto_istat_kpp - statistics for KPP algorithm |
56 | * @setsecret_cnt: number of setsecrey operation |
57 | * @generate_public_key_cnt: number of generate_public_key operation |
58 | * @compute_shared_secret_cnt: number of compute_shared_secret operation |
59 | * @err_cnt: number of error for KPP requests |
60 | */ |
61 | struct crypto_istat_kpp { |
62 | atomic64_t setsecret_cnt; |
63 | atomic64_t generate_public_key_cnt; |
64 | atomic64_t compute_shared_secret_cnt; |
65 | atomic64_t err_cnt; |
66 | }; |
67 | |
68 | /** |
69 | * struct kpp_alg - generic key-agreement protocol primitives |
70 | * |
71 | * @set_secret: Function invokes the protocol specific function to |
72 | * store the secret private key along with parameters. |
73 | * The implementation knows how to decode the buffer |
74 | * @generate_public_key: Function generate the public key to be sent to the |
75 | * counterpart. In case of error, where output is not big |
76 | * enough req->dst_len will be updated to the size |
77 | * required |
78 | * @compute_shared_secret: Function compute the shared secret as defined by |
79 | * the algorithm. The result is given back to the user. |
80 | * In case of error, where output is not big enough, |
81 | * req->dst_len will be updated to the size required |
82 | * @max_size: Function returns the size of the output buffer |
83 | * @init: Initialize the object. This is called only once at |
84 | * instantiation time. In case the cryptographic hardware |
85 | * needs to be initialized. Software fallback should be |
86 | * put in place here. |
87 | * @exit: Undo everything @init did. |
88 | * |
89 | * @base: Common crypto API algorithm data structure |
90 | * @stat: Statistics for KPP algorithm |
91 | */ |
92 | struct kpp_alg { |
93 | int (*set_secret)(struct crypto_kpp *tfm, const void *buffer, |
94 | unsigned int len); |
95 | int (*generate_public_key)(struct kpp_request *req); |
96 | int (*compute_shared_secret)(struct kpp_request *req); |
97 | |
98 | unsigned int (*max_size)(struct crypto_kpp *tfm); |
99 | |
100 | int (*init)(struct crypto_kpp *tfm); |
101 | void (*exit)(struct crypto_kpp *tfm); |
102 | |
103 | #ifdef CONFIG_CRYPTO_STATS |
104 | struct crypto_istat_kpp stat; |
105 | #endif |
106 | |
107 | struct crypto_alg base; |
108 | }; |
109 | |
110 | /** |
111 | * DOC: Generic Key-agreement Protocol Primitives API |
112 | * |
113 | * The KPP API is used with the algorithm type |
114 | * CRYPTO_ALG_TYPE_KPP (listed as type "kpp" in /proc/crypto) |
115 | */ |
116 | |
117 | /** |
118 | * crypto_alloc_kpp() - allocate KPP tfm handle |
119 | * @alg_name: is the name of the kpp algorithm (e.g. "dh", "ecdh") |
120 | * @type: specifies the type of the algorithm |
121 | * @mask: specifies the mask for the algorithm |
122 | * |
123 | * Allocate a handle for kpp algorithm. The returned struct crypto_kpp |
124 | * is required for any following API invocation |
125 | * |
126 | * Return: allocated handle in case of success; IS_ERR() is true in case of |
127 | * an error, PTR_ERR() returns the error code. |
128 | */ |
129 | struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask); |
130 | |
131 | int crypto_has_kpp(const char *alg_name, u32 type, u32 mask); |
132 | |
133 | static inline struct crypto_tfm *crypto_kpp_tfm(struct crypto_kpp *tfm) |
134 | { |
135 | return &tfm->base; |
136 | } |
137 | |
138 | static inline struct kpp_alg *__crypto_kpp_alg(struct crypto_alg *alg) |
139 | { |
140 | return container_of(alg, struct kpp_alg, base); |
141 | } |
142 | |
143 | static inline struct crypto_kpp *__crypto_kpp_tfm(struct crypto_tfm *tfm) |
144 | { |
145 | return container_of(tfm, struct crypto_kpp, base); |
146 | } |
147 | |
148 | static inline struct kpp_alg *crypto_kpp_alg(struct crypto_kpp *tfm) |
149 | { |
150 | return __crypto_kpp_alg(alg: crypto_kpp_tfm(tfm)->__crt_alg); |
151 | } |
152 | |
153 | static inline unsigned int crypto_kpp_reqsize(struct crypto_kpp *tfm) |
154 | { |
155 | return tfm->reqsize; |
156 | } |
157 | |
158 | static inline void kpp_request_set_tfm(struct kpp_request *req, |
159 | struct crypto_kpp *tfm) |
160 | { |
161 | req->base.tfm = crypto_kpp_tfm(tfm); |
162 | } |
163 | |
164 | static inline struct crypto_kpp *crypto_kpp_reqtfm(struct kpp_request *req) |
165 | { |
166 | return __crypto_kpp_tfm(tfm: req->base.tfm); |
167 | } |
168 | |
169 | static inline u32 crypto_kpp_get_flags(struct crypto_kpp *tfm) |
170 | { |
171 | return crypto_tfm_get_flags(tfm: crypto_kpp_tfm(tfm)); |
172 | } |
173 | |
174 | static inline void crypto_kpp_set_flags(struct crypto_kpp *tfm, u32 flags) |
175 | { |
176 | crypto_tfm_set_flags(tfm: crypto_kpp_tfm(tfm), flags); |
177 | } |
178 | |
179 | /** |
180 | * crypto_free_kpp() - free KPP tfm handle |
181 | * |
182 | * @tfm: KPP tfm handle allocated with crypto_alloc_kpp() |
183 | * |
184 | * If @tfm is a NULL or error pointer, this function does nothing. |
185 | */ |
186 | static inline void crypto_free_kpp(struct crypto_kpp *tfm) |
187 | { |
188 | crypto_destroy_tfm(mem: tfm, tfm: crypto_kpp_tfm(tfm)); |
189 | } |
190 | |
191 | /** |
192 | * kpp_request_alloc() - allocates kpp request |
193 | * |
194 | * @tfm: KPP tfm handle allocated with crypto_alloc_kpp() |
195 | * @gfp: allocation flags |
196 | * |
197 | * Return: allocated handle in case of success or NULL in case of an error. |
198 | */ |
199 | static inline struct kpp_request *kpp_request_alloc(struct crypto_kpp *tfm, |
200 | gfp_t gfp) |
201 | { |
202 | struct kpp_request *req; |
203 | |
204 | req = kmalloc(size: sizeof(*req) + crypto_kpp_reqsize(tfm), flags: gfp); |
205 | if (likely(req)) |
206 | kpp_request_set_tfm(req, tfm); |
207 | |
208 | return req; |
209 | } |
210 | |
211 | /** |
212 | * kpp_request_free() - zeroize and free kpp request |
213 | * |
214 | * @req: request to free |
215 | */ |
216 | static inline void kpp_request_free(struct kpp_request *req) |
217 | { |
218 | kfree_sensitive(objp: req); |
219 | } |
220 | |
221 | /** |
222 | * kpp_request_set_callback() - Sets an asynchronous callback. |
223 | * |
224 | * Callback will be called when an asynchronous operation on a given |
225 | * request is finished. |
226 | * |
227 | * @req: request that the callback will be set for |
228 | * @flgs: specify for instance if the operation may backlog |
229 | * @cmpl: callback which will be called |
230 | * @data: private data used by the caller |
231 | */ |
232 | static inline void kpp_request_set_callback(struct kpp_request *req, |
233 | u32 flgs, |
234 | crypto_completion_t cmpl, |
235 | void *data) |
236 | { |
237 | req->base.complete = cmpl; |
238 | req->base.data = data; |
239 | req->base.flags = flgs; |
240 | } |
241 | |
242 | /** |
243 | * kpp_request_set_input() - Sets input buffer |
244 | * |
245 | * Sets parameters required by generate_public_key |
246 | * |
247 | * @req: kpp request |
248 | * @input: ptr to input scatter list |
249 | * @input_len: size of the input scatter list |
250 | */ |
251 | static inline void kpp_request_set_input(struct kpp_request *req, |
252 | struct scatterlist *input, |
253 | unsigned int input_len) |
254 | { |
255 | req->src = input; |
256 | req->src_len = input_len; |
257 | } |
258 | |
259 | /** |
260 | * kpp_request_set_output() - Sets output buffer |
261 | * |
262 | * Sets parameters required by kpp operation |
263 | * |
264 | * @req: kpp request |
265 | * @output: ptr to output scatter list |
266 | * @output_len: size of the output scatter list |
267 | */ |
268 | static inline void kpp_request_set_output(struct kpp_request *req, |
269 | struct scatterlist *output, |
270 | unsigned int output_len) |
271 | { |
272 | req->dst = output; |
273 | req->dst_len = output_len; |
274 | } |
275 | |
276 | enum { |
277 | CRYPTO_KPP_SECRET_TYPE_UNKNOWN, |
278 | CRYPTO_KPP_SECRET_TYPE_DH, |
279 | CRYPTO_KPP_SECRET_TYPE_ECDH, |
280 | }; |
281 | |
282 | /** |
283 | * struct kpp_secret - small header for packing secret buffer |
284 | * |
285 | * @type: define type of secret. Each kpp type will define its own |
286 | * @len: specify the len of the secret, include the header, that |
287 | * follows the struct |
288 | */ |
289 | struct kpp_secret { |
290 | unsigned short type; |
291 | unsigned short len; |
292 | }; |
293 | |
294 | static inline struct crypto_istat_kpp *kpp_get_stat(struct kpp_alg *alg) |
295 | { |
296 | #ifdef CONFIG_CRYPTO_STATS |
297 | return &alg->stat; |
298 | #else |
299 | return NULL; |
300 | #endif |
301 | } |
302 | |
303 | static inline int crypto_kpp_errstat(struct kpp_alg *alg, int err) |
304 | { |
305 | if (!IS_ENABLED(CONFIG_CRYPTO_STATS)) |
306 | return err; |
307 | |
308 | if (err && err != -EINPROGRESS && err != -EBUSY) |
309 | atomic64_inc(v: &kpp_get_stat(alg)->err_cnt); |
310 | |
311 | return err; |
312 | } |
313 | |
314 | /** |
315 | * crypto_kpp_set_secret() - Invoke kpp operation |
316 | * |
317 | * Function invokes the specific kpp operation for a given alg. |
318 | * |
319 | * @tfm: tfm handle |
320 | * @buffer: Buffer holding the packet representation of the private |
321 | * key. The structure of the packet key depends on the particular |
322 | * KPP implementation. Packing and unpacking helpers are provided |
323 | * for ECDH and DH (see the respective header files for those |
324 | * implementations). |
325 | * @len: Length of the packet private key buffer. |
326 | * |
327 | * Return: zero on success; error code in case of error |
328 | */ |
329 | static inline int crypto_kpp_set_secret(struct crypto_kpp *tfm, |
330 | const void *buffer, unsigned int len) |
331 | { |
332 | struct kpp_alg *alg = crypto_kpp_alg(tfm); |
333 | |
334 | if (IS_ENABLED(CONFIG_CRYPTO_STATS)) |
335 | atomic64_inc(v: &kpp_get_stat(alg)->setsecret_cnt); |
336 | |
337 | return crypto_kpp_errstat(alg, err: alg->set_secret(tfm, buffer, len)); |
338 | } |
339 | |
340 | /** |
341 | * crypto_kpp_generate_public_key() - Invoke kpp operation |
342 | * |
343 | * Function invokes the specific kpp operation for generating the public part |
344 | * for a given kpp algorithm. |
345 | * |
346 | * To generate a private key, the caller should use a random number generator. |
347 | * The output of the requested length serves as the private key. |
348 | * |
349 | * @req: kpp key request |
350 | * |
351 | * Return: zero on success; error code in case of error |
352 | */ |
353 | static inline int crypto_kpp_generate_public_key(struct kpp_request *req) |
354 | { |
355 | struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); |
356 | struct kpp_alg *alg = crypto_kpp_alg(tfm); |
357 | |
358 | if (IS_ENABLED(CONFIG_CRYPTO_STATS)) |
359 | atomic64_inc(v: &kpp_get_stat(alg)->generate_public_key_cnt); |
360 | |
361 | return crypto_kpp_errstat(alg, err: alg->generate_public_key(req)); |
362 | } |
363 | |
364 | /** |
365 | * crypto_kpp_compute_shared_secret() - Invoke kpp operation |
366 | * |
367 | * Function invokes the specific kpp operation for computing the shared secret |
368 | * for a given kpp algorithm. |
369 | * |
370 | * @req: kpp key request |
371 | * |
372 | * Return: zero on success; error code in case of error |
373 | */ |
374 | static inline int crypto_kpp_compute_shared_secret(struct kpp_request *req) |
375 | { |
376 | struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); |
377 | struct kpp_alg *alg = crypto_kpp_alg(tfm); |
378 | |
379 | if (IS_ENABLED(CONFIG_CRYPTO_STATS)) |
380 | atomic64_inc(v: &kpp_get_stat(alg)->compute_shared_secret_cnt); |
381 | |
382 | return crypto_kpp_errstat(alg, err: alg->compute_shared_secret(req)); |
383 | } |
384 | |
385 | /** |
386 | * crypto_kpp_maxsize() - Get len for output buffer |
387 | * |
388 | * Function returns the output buffer size required for a given key. |
389 | * Function assumes that the key is already set in the transformation. If this |
390 | * function is called without a setkey or with a failed setkey, you will end up |
391 | * in a NULL dereference. |
392 | * |
393 | * @tfm: KPP tfm handle allocated with crypto_alloc_kpp() |
394 | */ |
395 | static inline unsigned int crypto_kpp_maxsize(struct crypto_kpp *tfm) |
396 | { |
397 | struct kpp_alg *alg = crypto_kpp_alg(tfm); |
398 | |
399 | return alg->max_size(tfm); |
400 | } |
401 | |
402 | #endif |
403 | |