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