diff options
Diffstat (limited to 'include/linux/crypto.h')
-rw-r--r-- | include/linux/crypto.h | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/include/linux/crypto.h b/include/linux/crypto.h new file mode 100644 index 000000000000..387da6a3e58c --- /dev/null +++ b/include/linux/crypto.h | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * Scatterlist Cryptographic API. | ||
3 | * | ||
4 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | ||
5 | * Copyright (c) 2002 David S. Miller (davem@redhat.com) | ||
6 | * | ||
7 | * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> | ||
8 | * and Nettle, by Niels Möller. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation; either version 2 of the License, or (at your option) | ||
13 | * any later version. | ||
14 | * | ||
15 | */ | ||
16 | #ifndef _LINUX_CRYPTO_H | ||
17 | #define _LINUX_CRYPTO_H | ||
18 | |||
19 | #include <linux/config.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <asm/page.h> | ||
26 | |||
27 | /* | ||
28 | * Algorithm masks and types. | ||
29 | */ | ||
30 | #define CRYPTO_ALG_TYPE_MASK 0x000000ff | ||
31 | #define CRYPTO_ALG_TYPE_CIPHER 0x00000001 | ||
32 | #define CRYPTO_ALG_TYPE_DIGEST 0x00000002 | ||
33 | #define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 | ||
34 | |||
35 | /* | ||
36 | * Transform masks and values (for crt_flags). | ||
37 | */ | ||
38 | #define CRYPTO_TFM_MODE_MASK 0x000000ff | ||
39 | #define CRYPTO_TFM_REQ_MASK 0x000fff00 | ||
40 | #define CRYPTO_TFM_RES_MASK 0xfff00000 | ||
41 | |||
42 | #define CRYPTO_TFM_MODE_ECB 0x00000001 | ||
43 | #define CRYPTO_TFM_MODE_CBC 0x00000002 | ||
44 | #define CRYPTO_TFM_MODE_CFB 0x00000004 | ||
45 | #define CRYPTO_TFM_MODE_CTR 0x00000008 | ||
46 | |||
47 | #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 | ||
48 | #define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 | ||
49 | #define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 | ||
50 | #define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 | ||
51 | #define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 | ||
52 | #define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 | ||
53 | |||
54 | /* | ||
55 | * Miscellaneous stuff. | ||
56 | */ | ||
57 | #define CRYPTO_UNSPEC 0 | ||
58 | #define CRYPTO_MAX_ALG_NAME 64 | ||
59 | |||
60 | #define CRYPTO_DIR_ENCRYPT 1 | ||
61 | #define CRYPTO_DIR_DECRYPT 0 | ||
62 | |||
63 | struct scatterlist; | ||
64 | |||
65 | /* | ||
66 | * Algorithms: modular crypto algorithm implementations, managed | ||
67 | * via crypto_register_alg() and crypto_unregister_alg(). | ||
68 | */ | ||
69 | struct cipher_alg { | ||
70 | unsigned int cia_min_keysize; | ||
71 | unsigned int cia_max_keysize; | ||
72 | int (*cia_setkey)(void *ctx, const u8 *key, | ||
73 | unsigned int keylen, u32 *flags); | ||
74 | void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); | ||
75 | void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); | ||
76 | }; | ||
77 | |||
78 | struct digest_alg { | ||
79 | unsigned int dia_digestsize; | ||
80 | void (*dia_init)(void *ctx); | ||
81 | void (*dia_update)(void *ctx, const u8 *data, unsigned int len); | ||
82 | void (*dia_final)(void *ctx, u8 *out); | ||
83 | int (*dia_setkey)(void *ctx, const u8 *key, | ||
84 | unsigned int keylen, u32 *flags); | ||
85 | }; | ||
86 | |||
87 | struct compress_alg { | ||
88 | int (*coa_init)(void *ctx); | ||
89 | void (*coa_exit)(void *ctx); | ||
90 | int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen, | ||
91 | u8 *dst, unsigned int *dlen); | ||
92 | int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen, | ||
93 | u8 *dst, unsigned int *dlen); | ||
94 | }; | ||
95 | |||
96 | #define cra_cipher cra_u.cipher | ||
97 | #define cra_digest cra_u.digest | ||
98 | #define cra_compress cra_u.compress | ||
99 | |||
100 | struct crypto_alg { | ||
101 | struct list_head cra_list; | ||
102 | u32 cra_flags; | ||
103 | unsigned int cra_blocksize; | ||
104 | unsigned int cra_ctxsize; | ||
105 | const char cra_name[CRYPTO_MAX_ALG_NAME]; | ||
106 | |||
107 | union { | ||
108 | struct cipher_alg cipher; | ||
109 | struct digest_alg digest; | ||
110 | struct compress_alg compress; | ||
111 | } cra_u; | ||
112 | |||
113 | struct module *cra_module; | ||
114 | }; | ||
115 | |||
116 | /* | ||
117 | * Algorithm registration interface. | ||
118 | */ | ||
119 | int crypto_register_alg(struct crypto_alg *alg); | ||
120 | int crypto_unregister_alg(struct crypto_alg *alg); | ||
121 | |||
122 | /* | ||
123 | * Algorithm query interface. | ||
124 | */ | ||
125 | #ifdef CONFIG_CRYPTO | ||
126 | int crypto_alg_available(const char *name, u32 flags); | ||
127 | #else | ||
128 | static inline int crypto_alg_available(const char *name, u32 flags) | ||
129 | { | ||
130 | return 0; | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | /* | ||
135 | * Transforms: user-instantiated objects which encapsulate algorithms | ||
136 | * and core processing logic. Managed via crypto_alloc_tfm() and | ||
137 | * crypto_free_tfm(), as well as the various helpers below. | ||
138 | */ | ||
139 | struct crypto_tfm; | ||
140 | |||
141 | struct cipher_tfm { | ||
142 | void *cit_iv; | ||
143 | unsigned int cit_ivsize; | ||
144 | u32 cit_mode; | ||
145 | int (*cit_setkey)(struct crypto_tfm *tfm, | ||
146 | const u8 *key, unsigned int keylen); | ||
147 | int (*cit_encrypt)(struct crypto_tfm *tfm, | ||
148 | struct scatterlist *dst, | ||
149 | struct scatterlist *src, | ||
150 | unsigned int nbytes); | ||
151 | int (*cit_encrypt_iv)(struct crypto_tfm *tfm, | ||
152 | struct scatterlist *dst, | ||
153 | struct scatterlist *src, | ||
154 | unsigned int nbytes, u8 *iv); | ||
155 | int (*cit_decrypt)(struct crypto_tfm *tfm, | ||
156 | struct scatterlist *dst, | ||
157 | struct scatterlist *src, | ||
158 | unsigned int nbytes); | ||
159 | int (*cit_decrypt_iv)(struct crypto_tfm *tfm, | ||
160 | struct scatterlist *dst, | ||
161 | struct scatterlist *src, | ||
162 | unsigned int nbytes, u8 *iv); | ||
163 | void (*cit_xor_block)(u8 *dst, const u8 *src); | ||
164 | }; | ||
165 | |||
166 | struct digest_tfm { | ||
167 | void (*dit_init)(struct crypto_tfm *tfm); | ||
168 | void (*dit_update)(struct crypto_tfm *tfm, | ||
169 | struct scatterlist *sg, unsigned int nsg); | ||
170 | void (*dit_final)(struct crypto_tfm *tfm, u8 *out); | ||
171 | void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, | ||
172 | unsigned int nsg, u8 *out); | ||
173 | int (*dit_setkey)(struct crypto_tfm *tfm, | ||
174 | const u8 *key, unsigned int keylen); | ||
175 | #ifdef CONFIG_CRYPTO_HMAC | ||
176 | void *dit_hmac_block; | ||
177 | #endif | ||
178 | }; | ||
179 | |||
180 | struct compress_tfm { | ||
181 | int (*cot_compress)(struct crypto_tfm *tfm, | ||
182 | const u8 *src, unsigned int slen, | ||
183 | u8 *dst, unsigned int *dlen); | ||
184 | int (*cot_decompress)(struct crypto_tfm *tfm, | ||
185 | const u8 *src, unsigned int slen, | ||
186 | u8 *dst, unsigned int *dlen); | ||
187 | }; | ||
188 | |||
189 | #define crt_cipher crt_u.cipher | ||
190 | #define crt_digest crt_u.digest | ||
191 | #define crt_compress crt_u.compress | ||
192 | |||
193 | struct crypto_tfm { | ||
194 | |||
195 | u32 crt_flags; | ||
196 | |||
197 | union { | ||
198 | struct cipher_tfm cipher; | ||
199 | struct digest_tfm digest; | ||
200 | struct compress_tfm compress; | ||
201 | } crt_u; | ||
202 | |||
203 | struct crypto_alg *__crt_alg; | ||
204 | }; | ||
205 | |||
206 | /* | ||
207 | * Transform user interface. | ||
208 | */ | ||
209 | |||
210 | /* | ||
211 | * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm. | ||
212 | * If that fails and the kernel supports dynamically loadable modules, it | ||
213 | * will then attempt to load a module of the same name or alias. A refcount | ||
214 | * is grabbed on the algorithm which is then associated with the new transform. | ||
215 | * | ||
216 | * crypto_free_tfm() frees up the transform and any associated resources, | ||
217 | * then drops the refcount on the associated algorithm. | ||
218 | */ | ||
219 | struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); | ||
220 | void crypto_free_tfm(struct crypto_tfm *tfm); | ||
221 | |||
222 | /* | ||
223 | * Transform helpers which query the underlying algorithm. | ||
224 | */ | ||
225 | static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm) | ||
226 | { | ||
227 | return tfm->__crt_alg->cra_name; | ||
228 | } | ||
229 | |||
230 | static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm) | ||
231 | { | ||
232 | return module_name(tfm->__crt_alg->cra_module); | ||
233 | } | ||
234 | |||
235 | static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm) | ||
236 | { | ||
237 | return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK; | ||
238 | } | ||
239 | |||
240 | static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) | ||
241 | { | ||
242 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
243 | return tfm->__crt_alg->cra_cipher.cia_min_keysize; | ||
244 | } | ||
245 | |||
246 | static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) | ||
247 | { | ||
248 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
249 | return tfm->__crt_alg->cra_cipher.cia_max_keysize; | ||
250 | } | ||
251 | |||
252 | static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) | ||
253 | { | ||
254 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
255 | return tfm->crt_cipher.cit_ivsize; | ||
256 | } | ||
257 | |||
258 | static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm) | ||
259 | { | ||
260 | return tfm->__crt_alg->cra_blocksize; | ||
261 | } | ||
262 | |||
263 | static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) | ||
264 | { | ||
265 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | ||
266 | return tfm->__crt_alg->cra_digest.dia_digestsize; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * API wrappers. | ||
271 | */ | ||
272 | static inline void crypto_digest_init(struct crypto_tfm *tfm) | ||
273 | { | ||
274 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | ||
275 | tfm->crt_digest.dit_init(tfm); | ||
276 | } | ||
277 | |||
278 | static inline void crypto_digest_update(struct crypto_tfm *tfm, | ||
279 | struct scatterlist *sg, | ||
280 | unsigned int nsg) | ||
281 | { | ||
282 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | ||
283 | tfm->crt_digest.dit_update(tfm, sg, nsg); | ||
284 | } | ||
285 | |||
286 | static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) | ||
287 | { | ||
288 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | ||
289 | tfm->crt_digest.dit_final(tfm, out); | ||
290 | } | ||
291 | |||
292 | static inline void crypto_digest_digest(struct crypto_tfm *tfm, | ||
293 | struct scatterlist *sg, | ||
294 | unsigned int nsg, u8 *out) | ||
295 | { | ||
296 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | ||
297 | tfm->crt_digest.dit_digest(tfm, sg, nsg, out); | ||
298 | } | ||
299 | |||
300 | static inline int crypto_digest_setkey(struct crypto_tfm *tfm, | ||
301 | const u8 *key, unsigned int keylen) | ||
302 | { | ||
303 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); | ||
304 | if (tfm->crt_digest.dit_setkey == NULL) | ||
305 | return -ENOSYS; | ||
306 | return tfm->crt_digest.dit_setkey(tfm, key, keylen); | ||
307 | } | ||
308 | |||
309 | static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, | ||
310 | const u8 *key, unsigned int keylen) | ||
311 | { | ||
312 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
313 | return tfm->crt_cipher.cit_setkey(tfm, key, keylen); | ||
314 | } | ||
315 | |||
316 | static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, | ||
317 | struct scatterlist *dst, | ||
318 | struct scatterlist *src, | ||
319 | unsigned int nbytes) | ||
320 | { | ||
321 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
322 | return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); | ||
323 | } | ||
324 | |||
325 | static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, | ||
326 | struct scatterlist *dst, | ||
327 | struct scatterlist *src, | ||
328 | unsigned int nbytes, u8 *iv) | ||
329 | { | ||
330 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
331 | BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); | ||
332 | return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv); | ||
333 | } | ||
334 | |||
335 | static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, | ||
336 | struct scatterlist *dst, | ||
337 | struct scatterlist *src, | ||
338 | unsigned int nbytes) | ||
339 | { | ||
340 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
341 | return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); | ||
342 | } | ||
343 | |||
344 | static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, | ||
345 | struct scatterlist *dst, | ||
346 | struct scatterlist *src, | ||
347 | unsigned int nbytes, u8 *iv) | ||
348 | { | ||
349 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
350 | BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); | ||
351 | return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv); | ||
352 | } | ||
353 | |||
354 | static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, | ||
355 | const u8 *src, unsigned int len) | ||
356 | { | ||
357 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
358 | memcpy(tfm->crt_cipher.cit_iv, src, len); | ||
359 | } | ||
360 | |||
361 | static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, | ||
362 | u8 *dst, unsigned int len) | ||
363 | { | ||
364 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | ||
365 | memcpy(dst, tfm->crt_cipher.cit_iv, len); | ||
366 | } | ||
367 | |||
368 | static inline int crypto_comp_compress(struct crypto_tfm *tfm, | ||
369 | const u8 *src, unsigned int slen, | ||
370 | u8 *dst, unsigned int *dlen) | ||
371 | { | ||
372 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); | ||
373 | return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen); | ||
374 | } | ||
375 | |||
376 | static inline int crypto_comp_decompress(struct crypto_tfm *tfm, | ||
377 | const u8 *src, unsigned int slen, | ||
378 | u8 *dst, unsigned int *dlen) | ||
379 | { | ||
380 | BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); | ||
381 | return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen); | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * HMAC support. | ||
386 | */ | ||
387 | #ifdef CONFIG_CRYPTO_HMAC | ||
388 | void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); | ||
389 | void crypto_hmac_update(struct crypto_tfm *tfm, | ||
390 | struct scatterlist *sg, unsigned int nsg); | ||
391 | void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, | ||
392 | unsigned int *keylen, u8 *out); | ||
393 | void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, | ||
394 | struct scatterlist *sg, unsigned int nsg, u8 *out); | ||
395 | #endif /* CONFIG_CRYPTO_HMAC */ | ||
396 | |||
397 | #endif /* _LINUX_CRYPTO_H */ | ||
398 | |||