12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2cce9e06dSHerbert Xu /*
3cce9e06dSHerbert Xu * Cryptographic API for algorithms (i.e., low-level API).
4cce9e06dSHerbert Xu *
5cce9e06dSHerbert Xu * Copyright (c) 2006 Herbert Xu <[email protected]>
6cce9e06dSHerbert Xu */
7cce9e06dSHerbert Xu #ifndef _CRYPTO_ALGAPI_H
8cce9e06dSHerbert Xu #define _CRYPTO_ALGAPI_H
9cce9e06dSHerbert Xu
10c616fb0cSHerbert Xu #include <crypto/utils.h>
11244d22ffSAndy Shevchenko #include <linux/align.h>
12eaade84aSHerbert Xu #include <linux/cache.h>
13cce9e06dSHerbert Xu #include <linux/crypto.h>
14f2ffe5a9SHerbert Xu #include <linux/list.h>
15244d22ffSAndy Shevchenko #include <linux/types.h>
169ae4577bSHerbert Xu #include <linux/workqueue.h>
17cce9e06dSHerbert Xu
1813c935bbSSalvatore Mesoraca /*
1913c935bbSSalvatore Mesoraca * Maximum values for blocksize and alignmask, used to allocate
2013c935bbSSalvatore Mesoraca * static buffers that are big enough for any combination of
21a9f7f88aSKees Cook * algs and architectures. Ciphers have a lower maximum size.
2213c935bbSSalvatore Mesoraca */
23a9f7f88aSKees Cook #define MAX_ALGAPI_BLOCKSIZE 160
241c799571SHerbert Xu #define MAX_ALGAPI_ALIGNMASK 127
2513c935bbSSalvatore Mesoraca #define MAX_CIPHER_BLOCKSIZE 16
2613c935bbSSalvatore Mesoraca #define MAX_CIPHER_ALIGNMASK 15
2713c935bbSSalvatore Mesoraca
28e634ac4aSHerbert Xu #ifdef ARCH_DMA_MINALIGN
29e634ac4aSHerbert Xu #define CRYPTO_DMA_ALIGN ARCH_DMA_MINALIGN
30e634ac4aSHerbert Xu #else
31e634ac4aSHerbert Xu #define CRYPTO_DMA_ALIGN CRYPTO_MINALIGN
32e634ac4aSHerbert Xu #endif
33e634ac4aSHerbert Xu
34e634ac4aSHerbert Xu #define CRYPTO_DMA_PADDING ((CRYPTO_DMA_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
35e634ac4aSHerbert Xu
360c0edf61SHerbert Xu /*
370c0edf61SHerbert Xu * Autoloaded crypto modules should only use a prefixed name to avoid allowing
380c0edf61SHerbert Xu * arbitrary modules to be loaded. Loading from userspace may still need the
390c0edf61SHerbert Xu * unprefixed names, so retains those aliases as well.
400c0edf61SHerbert Xu * This uses __MODULE_INFO directly instead of MODULE_ALIAS because pre-4.3
410c0edf61SHerbert Xu * gcc (e.g. avr32 toolchain) uses __LINE__ for uniqueness, and this macro
420c0edf61SHerbert Xu * expands twice on the same line. Instead, use a separate base name for the
430c0edf61SHerbert Xu * alias.
440c0edf61SHerbert Xu */
450c0edf61SHerbert Xu #define MODULE_ALIAS_CRYPTO(name) \
460c0edf61SHerbert Xu __MODULE_INFO(alias, alias_userspace, name); \
470c0edf61SHerbert Xu __MODULE_INFO(alias, alias_crypto, "crypto-" name)
480c0edf61SHerbert Xu
495d1d65f8SHerbert Xu struct crypto_aead;
50319382a6SHerbert Xu struct crypto_instance;
514cc7720cSHerbert Xu struct module;
52244d22ffSAndy Shevchenko struct notifier_block;
53ebc610e5SHerbert Xu struct rtattr;
5401f727cdSHerbert Xu struct scatterlist;
55e853c3cfSHerbert Xu struct seq_file;
560c3dc787SHerbert Xu struct sk_buff;
5765775cf3SHerbert Xu union crypto_no_such_thing;
58e853c3cfSHerbert Xu
594cc7720cSHerbert Xu struct crypto_instance {
604cc7720cSHerbert Xu struct crypto_alg alg;
614cc7720cSHerbert Xu
624cc7720cSHerbert Xu struct crypto_template *tmpl;
635f567fffSHerbert Xu
645f567fffSHerbert Xu union {
655f567fffSHerbert Xu /* Node in list of instances after registration. */
664cc7720cSHerbert Xu struct hlist_node list;
675f567fffSHerbert Xu /* List of attached spawns before registration. */
685f567fffSHerbert Xu struct crypto_spawn *spawns;
695f567fffSHerbert Xu };
704cc7720cSHerbert Xu
719ae4577bSHerbert Xu struct work_struct free_work;
729ae4577bSHerbert Xu
734cc7720cSHerbert Xu void *__ctx[] CRYPTO_MINALIGN_ATTR;
744cc7720cSHerbert Xu };
754cc7720cSHerbert Xu
764cc7720cSHerbert Xu struct crypto_template {
774cc7720cSHerbert Xu struct list_head list;
784cc7720cSHerbert Xu struct hlist_head instances;
794cc7720cSHerbert Xu struct module *module;
804cc7720cSHerbert Xu
81f2ac72e8SHerbert Xu int (*create)(struct crypto_template *tmpl, struct rtattr **tb);
824cc7720cSHerbert Xu
834cc7720cSHerbert Xu char name[CRYPTO_MAX_ALG_NAME];
844cc7720cSHerbert Xu };
854cc7720cSHerbert Xu
866bfd4809SHerbert Xu struct crypto_spawn {
876bfd4809SHerbert Xu struct list_head list;
886bfd4809SHerbert Xu struct crypto_alg *alg;
895f567fffSHerbert Xu union {
905f567fffSHerbert Xu /* Back pointer to instance after registration.*/
916bfd4809SHerbert Xu struct crypto_instance *inst;
925f567fffSHerbert Xu /* Spawn list pointer prior to registration. */
935f567fffSHerbert Xu struct crypto_spawn *next;
945f567fffSHerbert Xu };
9597eedce1SHerbert Xu const struct crypto_type *frontend;
96a73e6996SHerbert Xu u32 mask;
974f87ee11SHerbert Xu bool dead;
985f567fffSHerbert Xu bool registered;
996bfd4809SHerbert Xu };
1006bfd4809SHerbert Xu
101b5b7f088SHerbert Xu struct crypto_queue {
102b5b7f088SHerbert Xu struct list_head list;
103b5b7f088SHerbert Xu struct list_head *backlog;
104b5b7f088SHerbert Xu
105b5b7f088SHerbert Xu unsigned int qlen;
106b5b7f088SHerbert Xu unsigned int max_qlen;
107b5b7f088SHerbert Xu };
108b5b7f088SHerbert Xu
1095c64097aSHerbert Xu struct scatter_walk {
110*db873be6SHerbert Xu /* Must be the first member, see struct skcipher_walk. */
11165775cf3SHerbert Xu union {
11265775cf3SHerbert Xu void *const addr;
11365775cf3SHerbert Xu
11465775cf3SHerbert Xu /* Private API field, do not touch. */
11565775cf3SHerbert Xu union crypto_no_such_thing *__addr;
11665775cf3SHerbert Xu };
117*db873be6SHerbert Xu struct scatterlist *sg;
118*db873be6SHerbert Xu unsigned int offset;
1195c64097aSHerbert Xu };
1205c64097aSHerbert Xu
1215163ab50SHerbert Xu struct crypto_attr_alg {
1225163ab50SHerbert Xu char name[CRYPTO_MAX_ALG_NAME];
1235163ab50SHerbert Xu };
1245163ab50SHerbert Xu
1255163ab50SHerbert Xu struct crypto_attr_type {
1265163ab50SHerbert Xu u32 type;
1275163ab50SHerbert Xu u32 mask;
1285163ab50SHerbert Xu };
1295163ab50SHerbert Xu
13001f727cdSHerbert Xu /*
13101f727cdSHerbert Xu * Algorithm registration interface.
13201f727cdSHerbert Xu */
13301f727cdSHerbert Xu int crypto_register_alg(struct crypto_alg *alg);
13401f727cdSHerbert Xu void crypto_unregister_alg(struct crypto_alg *alg);
13501f727cdSHerbert Xu int crypto_register_algs(struct crypto_alg *algs, int count);
13601f727cdSHerbert Xu void crypto_unregister_algs(struct crypto_alg *algs, int count);
13701f727cdSHerbert Xu
138db131ef9SHerbert Xu void crypto_mod_put(struct crypto_alg *alg);
139db131ef9SHerbert Xu
1404cc7720cSHerbert Xu int crypto_register_template(struct crypto_template *tmpl);
1419572442dSXiongfeng Wang int crypto_register_templates(struct crypto_template *tmpls, int count);
1424cc7720cSHerbert Xu void crypto_unregister_template(struct crypto_template *tmpl);
1439572442dSXiongfeng Wang void crypto_unregister_templates(struct crypto_template *tmpls, int count);
1444cc7720cSHerbert Xu struct crypto_template *crypto_lookup_template(const char *name);
1454cc7720cSHerbert Xu
1469cd899a3SHerbert Xu int crypto_register_instance(struct crypto_template *tmpl,
1479cd899a3SHerbert Xu struct crypto_instance *inst);
148c6d633a9SEric Biggers void crypto_unregister_instance(struct crypto_instance *inst);
1499cd899a3SHerbert Xu
150de95c957SEric Biggers int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
151de95c957SEric Biggers const char *name, u32 type, u32 mask);
1526bfd4809SHerbert Xu void crypto_drop_spawn(struct crypto_spawn *spawn);
1532e306ee0SHerbert Xu struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
1542e306ee0SHerbert Xu u32 mask);
15597eedce1SHerbert Xu void *crypto_spawn_tfm2(struct crypto_spawn *spawn);
1566bfd4809SHerbert Xu
157ebc610e5SHerbert Xu struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb);
1587bcb2c99SEric Biggers int crypto_check_attr_type(struct rtattr **tb, u32 type, u32 *mask_ret);
15968b6c7d6SHerbert Xu const char *crypto_attr_alg_name(struct rtattr *rta);
16032f27c74SHerbert Xu int crypto_inst_setname(struct crypto_instance *inst, const char *name,
16132f27c74SHerbert Xu struct crypto_alg *alg);
1627fed0bf2SHerbert Xu
163b5b7f088SHerbert Xu void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen);
164b5b7f088SHerbert Xu int crypto_enqueue_request(struct crypto_queue *queue,
165b5b7f088SHerbert Xu struct crypto_async_request *request);
166ec6e2bf3SIuliana Prodan void crypto_enqueue_request_head(struct crypto_queue *queue,
167ec6e2bf3SIuliana Prodan struct crypto_async_request *request);
168b5b7f088SHerbert Xu struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue);
crypto_queue_len(struct crypto_queue * queue)1699f93a8a0SBaolin Wang static inline unsigned int crypto_queue_len(struct crypto_queue *queue)
1709f93a8a0SBaolin Wang {
1719f93a8a0SBaolin Wang return queue->qlen;
1729f93a8a0SBaolin Wang }
173b5b7f088SHerbert Xu
1747613636dSHerbert Xu void crypto_inc(u8 *a, unsigned int size);
17545fe93dfSArd Biesheuvel
crypto_tfm_ctx(struct crypto_tfm * tfm)176e634ac4aSHerbert Xu static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
177e634ac4aSHerbert Xu {
178e634ac4aSHerbert Xu return tfm->__crt_ctx;
179e634ac4aSHerbert Xu }
180e634ac4aSHerbert Xu
crypto_tfm_ctx_align(struct crypto_tfm * tfm,unsigned int align)181e634ac4aSHerbert Xu static inline void *crypto_tfm_ctx_align(struct crypto_tfm *tfm,
182e634ac4aSHerbert Xu unsigned int align)
183e634ac4aSHerbert Xu {
184e634ac4aSHerbert Xu if (align <= crypto_tfm_ctx_alignment())
185e634ac4aSHerbert Xu align = 1;
186e634ac4aSHerbert Xu
187e634ac4aSHerbert Xu return PTR_ALIGN(crypto_tfm_ctx(tfm), align);
188e634ac4aSHerbert Xu }
189e634ac4aSHerbert Xu
crypto_dma_align(void)190e634ac4aSHerbert Xu static inline unsigned int crypto_dma_align(void)
191e634ac4aSHerbert Xu {
192e634ac4aSHerbert Xu return CRYPTO_DMA_ALIGN;
193e634ac4aSHerbert Xu }
194e634ac4aSHerbert Xu
crypto_dma_padding(void)195e634ac4aSHerbert Xu static inline unsigned int crypto_dma_padding(void)
196e634ac4aSHerbert Xu {
197e634ac4aSHerbert Xu return (crypto_dma_align() - 1) & ~(crypto_tfm_ctx_alignment() - 1);
198e634ac4aSHerbert Xu }
199e634ac4aSHerbert Xu
crypto_tfm_ctx_dma(struct crypto_tfm * tfm)200e634ac4aSHerbert Xu static inline void *crypto_tfm_ctx_dma(struct crypto_tfm *tfm)
201e634ac4aSHerbert Xu {
202e634ac4aSHerbert Xu return crypto_tfm_ctx_align(tfm, crypto_dma_align());
2035cde0af2SHerbert Xu }
2045cde0af2SHerbert Xu
crypto_tfm_alg_instance(struct crypto_tfm * tfm)205124b53d0SHerbert Xu static inline struct crypto_instance *crypto_tfm_alg_instance(
206124b53d0SHerbert Xu struct crypto_tfm *tfm)
207124b53d0SHerbert Xu {
208124b53d0SHerbert Xu return container_of(tfm->__crt_alg, struct crypto_instance, alg);
209124b53d0SHerbert Xu }
210124b53d0SHerbert Xu
crypto_instance_ctx(struct crypto_instance * inst)2114cc7720cSHerbert Xu static inline void *crypto_instance_ctx(struct crypto_instance *inst)
2124cc7720cSHerbert Xu {
2134cc7720cSHerbert Xu return inst->__ctx;
2144cc7720cSHerbert Xu }
2154cc7720cSHerbert Xu
crypto_get_backlog(struct crypto_queue * queue)216b5b7f088SHerbert Xu static inline struct crypto_async_request *crypto_get_backlog(
217b5b7f088SHerbert Xu struct crypto_queue *queue)
218b5b7f088SHerbert Xu {
219b5b7f088SHerbert Xu return queue->backlog == &queue->list ? NULL :
220b5b7f088SHerbert Xu container_of(queue->backlog, struct crypto_async_request, list);
221b5b7f088SHerbert Xu }
222b5b7f088SHerbert Xu
crypto_requires_off(struct crypto_attr_type * algt,u32 off)2237bcb2c99SEric Biggers static inline u32 crypto_requires_off(struct crypto_attr_type *algt, u32 off)
224016df0abSHerbert Xu {
2257bcb2c99SEric Biggers return (algt->type ^ off) & algt->mask & off;
226016df0abSHerbert Xu }
227016df0abSHerbert Xu
228378f4f51SHerbert Xu /*
2297bcb2c99SEric Biggers * When an algorithm uses another algorithm (e.g., if it's an instance of a
2307bcb2c99SEric Biggers * template), these are the flags that should always be set on the "outer"
2317bcb2c99SEric Biggers * algorithm if any "inner" algorithm has them set.
232378f4f51SHerbert Xu */
2332eb27c11SEric Biggers #define CRYPTO_ALG_INHERITED_FLAGS \
234fbb6cda4SEric Biggers (CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK | \
235fbb6cda4SEric Biggers CRYPTO_ALG_ALLOCATES_MEMORY)
2367bcb2c99SEric Biggers
2377bcb2c99SEric Biggers /*
2387bcb2c99SEric Biggers * Given the type and mask that specify the flags restrictions on a template
2397bcb2c99SEric Biggers * instance being created, return the mask that should be passed to
2407bcb2c99SEric Biggers * crypto_grab_*() (along with type=0) to honor any request the user made to
2417bcb2c99SEric Biggers * have any of the CRYPTO_ALG_INHERITED_FLAGS clear.
2427bcb2c99SEric Biggers */
crypto_algt_inherited_mask(struct crypto_attr_type * algt)2437bcb2c99SEric Biggers static inline u32 crypto_algt_inherited_mask(struct crypto_attr_type *algt)
244378f4f51SHerbert Xu {
2457bcb2c99SEric Biggers return crypto_requires_off(algt, CRYPTO_ALG_INHERITED_FLAGS);
246378f4f51SHerbert Xu }
247378f4f51SHerbert Xu
248dd8b083fSMartin K. Petersen int crypto_register_notifier(struct notifier_block *nb);
249dd8b083fSMartin K. Petersen int crypto_unregister_notifier(struct notifier_block *nb);
250dd8b083fSMartin K. Petersen
251dd8b083fSMartin K. Petersen /* Crypto notification events. */
252dd8b083fSMartin K. Petersen enum {
253dd8b083fSMartin K. Petersen CRYPTO_MSG_ALG_REQUEST,
254dd8b083fSMartin K. Petersen CRYPTO_MSG_ALG_REGISTER,
255dd8b083fSMartin K. Petersen CRYPTO_MSG_ALG_LOADED,
256dd8b083fSMartin K. Petersen };
257dd8b083fSMartin K. Petersen
crypto_request_complete(struct crypto_async_request * req,int err)258c35e03eaSHerbert Xu static inline void crypto_request_complete(struct crypto_async_request *req,
259c35e03eaSHerbert Xu int err)
260c35e03eaSHerbert Xu {
261255e48ebSHerbert Xu req->complete(req->data, err);
262c35e03eaSHerbert Xu }
263c35e03eaSHerbert Xu
crypto_tfm_alg_type(struct crypto_tfm * tfm)26401f727cdSHerbert Xu static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
26501f727cdSHerbert Xu {
26601f727cdSHerbert Xu return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
26701f727cdSHerbert Xu }
26801f727cdSHerbert Xu
crypto_request_chained(struct crypto_async_request * req)269f2ffe5a9SHerbert Xu static inline bool crypto_request_chained(struct crypto_async_request *req)
270f2ffe5a9SHerbert Xu {
271f2ffe5a9SHerbert Xu return !list_empty(&req->list);
272f2ffe5a9SHerbert Xu }
273f2ffe5a9SHerbert Xu
crypto_tfm_req_chain(struct crypto_tfm * tfm)274f2ffe5a9SHerbert Xu static inline bool crypto_tfm_req_chain(struct crypto_tfm *tfm)
275f2ffe5a9SHerbert Xu {
276f2ffe5a9SHerbert Xu return tfm->__crt_alg->cra_flags & CRYPTO_ALG_REQ_CHAIN;
277f2ffe5a9SHerbert Xu }
278f2ffe5a9SHerbert Xu
2796bf37e5aSJames Yonan #endif /* _CRYPTO_ALGAPI_H */
280