summaryrefslogtreecommitdiff
path: root/include/crypto/internal/aead.h
blob: cd8cb1e921b7bd251b93dc49282006fde92b92df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * AEAD: Authenticated Encryption with Associated Data
 * 
 * Copyright (c) 2007-2015 Herbert Xu <herbert@gondor.apana.org.au>
 */

#ifndef _CRYPTO_INTERNAL_AEAD_H
#define _CRYPTO_INTERNAL_AEAD_H

#include <crypto/aead.h>
#include <crypto/algapi.h>
#include <linux/stddef.h>
#include <linux/types.h>

struct rtattr;

struct aead_instance {
	void (*free)(struct aead_instance *inst);
	union {
		struct {
			char head[offsetof(struct aead_alg, base)];
			struct crypto_instance base;
		} s;
		struct aead_alg alg;
	};
};

struct crypto_aead_spawn {
	struct crypto_spawn base;
};

struct aead_queue {
	struct crypto_queue base;
};

static inline void *crypto_aead_ctx(struct crypto_aead *tfm)
{
	return crypto_tfm_ctx(&tfm->base);
}

static inline void *crypto_aead_ctx_dma(struct crypto_aead *tfm)
{
	return crypto_tfm_ctx_dma(&tfm->base);
}

static inline struct crypto_instance *aead_crypto_instance(
	struct aead_instance *inst)
{
	return container_of(&inst->alg.base, struct crypto_instance, alg);
}

static inline struct aead_instance *aead_instance(struct crypto_instance *inst)
{
	return container_of(&inst->alg, struct aead_instance, alg.base);
}

static inline struct aead_instance *aead_alg_instance(struct crypto_aead *aead)
{
	return aead_instance(crypto_tfm_alg_instance(&aead->base));
}

static inline void *aead_instance_ctx(struct aead_instance *inst)
{
	return crypto_instance_ctx(aead_crypto_instance(inst));
}

static inline void *aead_request_ctx(struct aead_request *req)
{
	return req->__ctx;
}

static inline void *aead_request_ctx_dma(struct aead_request *req)
{
	unsigned int align = crypto_dma_align();

	if (align <= crypto_tfm_ctx_alignment())
		align = 1;

	return PTR_ALIGN(aead_request_ctx(req), align);
}

static inline void aead_request_complete(struct aead_request *req, int err)
{
	req->base.complete(&req->base, err);
}

static inline u32 aead_request_flags(struct aead_request *req)
{
	return req->base.flags;
}

static inline struct aead_request *aead_request_cast(
	struct crypto_async_request *req)
{
	return container_of(req, struct aead_request, base);
}

int crypto_grab_aead(struct crypto_aead_spawn *spawn,
		     struct crypto_instance *inst,
		     const char *name, u32 type, u32 mask);

static inline void crypto_drop_aead(struct crypto_aead_spawn *spawn)
{
	crypto_drop_spawn(&spawn->base);
}

static inline struct aead_alg *crypto_spawn_aead_alg(
	struct crypto_aead_spawn *spawn)
{
	return container_of(spawn->base.alg, struct aead_alg, base);
}

static inline struct crypto_aead *crypto_spawn_aead(
	struct crypto_aead_spawn *spawn)
{
	return crypto_spawn_tfm2(&spawn->base);
}

static inline void crypto_aead_set_reqsize(struct crypto_aead *aead,
					   unsigned int reqsize)
{
	aead->reqsize = reqsize;
}

static inline void crypto_aead_set_reqsize_dma(struct crypto_aead *aead,
					       unsigned int reqsize)
{
	reqsize += crypto_dma_align() & ~(crypto_tfm_ctx_alignment() - 1);
	aead->reqsize = reqsize;
}

static inline void aead_init_queue(struct aead_queue *queue,
				   unsigned int max_qlen)
{
	crypto_init_queue(&queue->base, max_qlen);
}

static inline unsigned int crypto_aead_alg_chunksize(struct aead_alg *alg)
{
	return alg->chunksize;
}

/**
 * crypto_aead_chunksize() - obtain chunk size
 * @tfm: cipher handle
 *
 * The block size is set to one for ciphers such as CCM.  However,
 * you still need to provide incremental updates in multiples of
 * the underlying block size as the IV does not have sub-block
 * granularity.  This is known in this API as the chunk size.
 *
 * Return: chunk size in bytes
 */
static inline unsigned int crypto_aead_chunksize(struct crypto_aead *tfm)
{
	return crypto_aead_alg_chunksize(crypto_aead_alg(tfm));
}

int crypto_register_aead(struct aead_alg *alg);
void crypto_unregister_aead(struct aead_alg *alg);
int crypto_register_aeads(struct aead_alg *algs, int count);
void crypto_unregister_aeads(struct aead_alg *algs, int count);
int aead_register_instance(struct crypto_template *tmpl,
			   struct aead_instance *inst);

#endif	/* _CRYPTO_INTERNAL_AEAD_H */