]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccmode.h
xnu-2422.115.4.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccmode.h
1 /*
2 * ccmode.h
3 * corecrypto
4 *
5 * Created by Michael Brouwer on 12/6/10.
6 * Copyright 2010,2011 Apple Inc. All rights reserved.
7 *
8 */
9
10 #ifndef _CORECRYPTO_CCMODE_H_
11 #define _CORECRYPTO_CCMODE_H_
12
13 #include <corecrypto/cc.h>
14 #include <corecrypto/ccmode_impl.h>
15
16 /* ECB mode. */
17
18 /* Declare a ecb key named _name_. Pass the size field of a struct ccmode_ecb
19 for _size_. */
20 #define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl(ccecb_ctx, _size_, _name_)
21 #define ccecb_ctx_clear(_size_, _name_) cc_ctx_clear(ccecb_ctx, _size_, _name_)
22
23 CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
24 {
25 return mode->size;
26 }
27
28 CC_INLINE unsigned long ccecb_block_size(const struct ccmode_ecb *mode)
29 {
30 return mode->block_size;
31 }
32
33 CC_INLINE void ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx,
34 unsigned long key_len, const void *key)
35 {
36 mode->init(mode, ctx, key_len, key);
37 }
38
39 CC_INLINE void ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx,
40 unsigned long in_len, const void *in, void *out)
41 {
42 unsigned long numBlocks = (in_len / mode->block_size);
43 mode->ecb(ctx, numBlocks, in, out);
44 }
45
46 CC_INLINE void ccecb_one_shot(const struct ccmode_ecb *mode,
47 unsigned long key_len, const void *key, unsigned long in_len,
48 const void *in, void *out)
49 {
50 unsigned long numBlocks = (in_len / mode->block_size);
51 ccecb_ctx_decl(mode->size, ctx);
52 mode->init(mode, ctx, key_len, key);
53 mode->ecb(ctx, numBlocks, in, out);
54 ccecb_ctx_clear(mode->size, ctx);
55 }
56
57 /* CBC mode. */
58
59 /* The CBC interface changed due to rdar://11468135. This macros is to indicate
60 to client which CBC API is implemented. Clients can support old versions of
61 corecrypto at build time using this.
62 */
63 #define __CC_HAS_FIX_FOR_11468135__ 1
64
65 /* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
66 for _size_. */
67 #define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
68 #define cccbc_ctx_clear(_size_, _name_) cc_ctx_clear(cccbc_ctx, _size_, _name_)
69
70 /* Declare a cbc iv tweak named _name_. Pass the blocksize field of a struct ccmode_cbc
71 for _size_. */
72 #define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
73 #define cccbc_iv_clear(_size_, _name_) cc_ctx_clear(cccbc_iv, _size_, _name_)
74
75 /* Actual symmetric algorithm implementation can provide you one of these.
76
77 Alternatively you can create a ccmode_cbc instance from any ccmode_ecb
78 cipher. To do so, statically initialize a struct ccmode_cbc using the
79 CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros. Alternatively
80 you can dynamically initialize a struct ccmode_cbc ccmode_factory_cbc_decrypt()
81 or ccmode_factory_cbc_encrypt(). */
82
83 CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
84 {
85 return mode->size;
86 }
87
88 CC_INLINE unsigned long cccbc_block_size(const struct ccmode_cbc *mode)
89 {
90 return mode->block_size;
91 }
92
93 CC_INLINE void cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
94 unsigned long key_len, const void *key)
95 {
96 mode->init(mode, ctx, key_len, key);
97 }
98
99 CC_INLINE void cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx, const void *iv)
100 {
101 if(iv)
102 cc_copy(mode->block_size, iv_ctx, iv);
103 else
104 cc_zero(mode->block_size, iv_ctx);
105 }
106
107 CC_INLINE void cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx, cccbc_iv *iv,
108 unsigned long nblocks, const void *in, void *out)
109 {
110 mode->cbc(ctx, iv, nblocks, in, out);
111 }
112
113 CC_INLINE void cccbc_one_shot(const struct ccmode_cbc *mode,
114 unsigned long key_len, const void *key, const void *iv, unsigned long nblocks,
115 const void *in, void *out)
116 {
117 cccbc_ctx_decl(mode->size, ctx);
118 cccbc_iv_decl(mode->block_size, iv_ctx);
119 mode->init(mode, ctx, key_len, key);
120 if(iv)
121 cccbc_set_iv (mode, iv_ctx, iv);
122 else
123 cc_zero(mode->block_size, iv_ctx);
124 mode->cbc(ctx, iv_ctx, nblocks, in, out);
125 cccbc_ctx_clear(mode->size, ctx);
126 }
127
128 /* CFB mode. */
129
130 /* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
131 for _size_. */
132 #define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
133 #define cccfb_ctx_clear(_size_, _name_) cc_ctx_clear(cccfb_ctx, _size_, _name_)
134
135 CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
136 {
137 return mode->size;
138 }
139
140 CC_INLINE unsigned long cccfb_block_size(const struct ccmode_cfb *mode)
141 {
142 return mode->block_size;
143 }
144
145 CC_INLINE void cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
146 unsigned long key_len, const void *key, const void *iv)
147 {
148 mode->init(mode, ctx, key_len, key, iv);
149 }
150
151 CC_INLINE void cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
152 unsigned long in_len, const void *in, void *out)
153 {
154 mode->cfb(ctx, in_len, in, out);
155 }
156
157 CC_INLINE void cccfb_one_shot(const struct ccmode_cfb *mode,
158 unsigned long key_len, const void *key, const void *iv,
159 unsigned long in_len, const void *in, void *out)
160 {
161 cccfb_ctx_decl(mode->size, ctx);
162 mode->init(mode, ctx, key_len, key, iv);
163 mode->cfb(ctx, in_len, in, out);
164 cccfb_ctx_clear(mode->size, ctx);
165 }
166
167 /* CFB8 mode. */
168
169 /* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
170 for _size_. */
171 #define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
172 #define cccfb8_ctx_clear(_size_, _name_) cc_ctx_clear(cccfb8_ctx, _size_, _name_)
173
174 CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
175 {
176 return mode->size;
177 }
178
179 CC_INLINE unsigned long cccfb8_block_size(const struct ccmode_cfb8 *mode)
180 {
181 return mode->block_size;
182 }
183
184 CC_INLINE void cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
185 unsigned long key_len, const void *key, const void *iv)
186 {
187 mode->init(mode, ctx, key_len, key, iv);
188 }
189
190 CC_INLINE void cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
191 unsigned long in_len, const void *in, void *out)
192 {
193 mode->cfb8(ctx, in_len, in, out);
194 }
195
196 CC_INLINE void cccfb8_one_shot(const struct ccmode_cfb8 *mode,
197 unsigned long key_len, const void *key, const void *iv,
198 unsigned long in_len, const void *in, void *out)
199 {
200 cccfb8_ctx_decl(mode->size, ctx);
201 mode->init(mode, ctx, key_len, key, iv);
202 mode->cfb8(ctx, in_len, in, out);
203 cccfb8_ctx_clear(mode->size, ctx);
204 }
205
206 /* CTR mode. */
207
208 /* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
209 for _size_. */
210 #define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
211 #define ccctr_ctx_clear(_size_, _name_) cc_ctx_clear(ccctr_ctx, _size_, _name_)
212
213 /* This is Integer Counter Mode: The IV is the initial value of the counter
214 that is incremented by 1 for each new block. Use the mode flags to select
215 if the IV/Counter is stored in big or little endian. */
216
217 CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
218 {
219 return mode->size;
220 }
221
222 CC_INLINE unsigned long ccctr_block_size(const struct ccmode_ctr *mode)
223 {
224 return mode->block_size;
225 }
226
227 CC_INLINE void ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
228 unsigned long key_len, const void *key, const void *iv)
229 {
230 mode->init(mode, ctx, key_len, key, iv);
231 }
232
233 CC_INLINE void ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
234 unsigned long in_len, const void *in, void *out)
235 {
236 unsigned long numBlocks = (in_len / mode->block_size);
237 mode->ctr(ctx, numBlocks, in, out);
238 }
239
240 CC_INLINE void ccctr_one_shot(const struct ccmode_ctr *mode,
241 unsigned long key_len, const void *key, const void *iv,
242 unsigned long in_len, const void *in, void *out)
243 {
244 unsigned long numBlocks = (in_len / mode->block_size);
245 ccctr_ctx_decl(mode->size, ctx);
246 mode->init(mode, ctx, key_len, key, iv);
247 mode->ctr(ctx, numBlocks, in, out);
248 ccctr_ctx_clear(mode->size, ctx);
249 }
250
251
252 /* OFB mode. */
253
254 /* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
255 for _size_. */
256 #define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
257 #define ccofb_ctx_clear(_size_, _name_) cc_ctx_clear(ccofb_ctx, _size_, _name_)
258
259 CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
260 {
261 return mode->size;
262 }
263
264 CC_INLINE unsigned long ccofb_block_size(const struct ccmode_ofb *mode)
265 {
266 return mode->block_size;
267 }
268
269 CC_INLINE void ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
270 unsigned long key_len, const void *key, const void *iv)
271 {
272 mode->init(mode, ctx, key_len, key, iv);
273 }
274
275 CC_INLINE void ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
276 unsigned long in_len, const void *in, void *out)
277 {
278 mode->ofb(ctx, in_len, in, out);
279 }
280
281 CC_INLINE void ccofb_one_shot(const struct ccmode_ofb *mode,
282 unsigned long key_len, const void *key, const void *iv,
283 unsigned long in_len, const void *in, void *out)
284 {
285 ccofb_ctx_decl(mode->size, ctx);
286 mode->init(mode, ctx, key_len, key, iv);
287 mode->ofb(ctx, in_len, in, out);
288 ccofb_ctx_clear(mode->size, ctx);
289 }
290
291 /* Authenticated cipher modes. */
292
293 /* XTS mode. */
294
295 /* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
296 for _size_. */
297 #define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
298 #define ccxts_ctx_clear(_size_, _name_) cc_ctx_clear(ccxts_ctx, _size_, _name_)
299
300 /* Declare a xts tweak named _name_. Pass the tweak_size field of a struct ccmode_xts
301 for _size_. */
302 #define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
303 #define ccxts_tweak_clear(_size_, _name_) cc_ctx_clear(ccxts_tweak, _size_, _name_)
304
305 /* Actual symmetric algorithm implementation can provide you one of these.
306
307 Alternatively you can create a ccmode_xts instance from any ccmode_ecb
308 cipher. To do so, statically initialize a struct ccmode_xts using the
309 CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
310 you can dynamically initialize a struct ccmode_xts ccmode_factory_xts_decrypt()
311 or ccmode_factory_xts_encrypt(). */
312
313 /* NOTE that xts mode does not do cts padding. It's really an xex mode.
314 If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
315 functions. Also note that xts only works for ecb modes with a block_size
316 of 16. */
317
318 CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
319 {
320 return mode->size;
321 }
322
323 CC_INLINE unsigned long ccxts_block_size(const struct ccmode_xts *mode)
324 {
325 return mode->block_size;
326 }
327
328 CC_INLINE void ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx,
329 unsigned long key_len, const void *key, const void *tweak_key)
330 {
331 mode->init(mode, ctx, key_len, key, tweak_key);
332 }
333
334 CC_INLINE void ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv)
335 {
336 mode->set_tweak(ctx, tweak, iv);
337 }
338
339 CC_INLINE void *ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx,
340 ccxts_tweak *tweak, unsigned long in_len, const void *in, void *out)
341 {
342 return mode->xts(ctx, tweak, in_len, in, out);
343 }
344
345 CC_INLINE void ccxts_one_shot(const struct ccmode_xts *mode,
346 unsigned long key_len, const void *key, const void *tweak_key,
347 const void* iv,
348 unsigned long in_len, const void *in, void *out)
349 {
350 ccxts_ctx_decl(mode->size, ctx);
351 ccxts_tweak_decl(mode->tweak_size, tweak);
352 mode->init(mode, ctx, key_len, key, tweak_key);
353 mode->set_tweak(ctx, tweak, iv);
354 mode->xts(ctx, tweak, in_len, in, out);
355 ccxts_ctx_clear(mode->size, ctx);
356 ccxts_tweak_clear(mode->tweak_size, tweak);
357 }
358
359 /* GCM mode. */
360
361 /* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
362 for _size_. */
363 #define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_)
364 #define ccgcm_ctx_clear(_size_, _name_) cc_ctx_clear(ccgcm_ctx, _size_, _name_)
365
366 CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
367 {
368 return mode->size;
369 }
370
371 CC_INLINE unsigned long ccgcm_block_size(const struct ccmode_gcm *mode)
372 {
373 return mode->block_size;
374 }
375
376 CC_INLINE void ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
377 unsigned long key_len, const void *key)
378 {
379 mode->init(mode, ctx, key_len, key);
380 }
381
382 CC_INLINE void ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_size, const void *iv)
383 {
384 mode->set_iv(ctx, iv_size, iv);
385 }
386
387 CC_INLINE void ccgcm_gmac(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
388 unsigned long nbytes, const void *in)
389 {
390 mode->gmac(ctx, nbytes, in);
391 }
392
393 CC_INLINE void ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
394 unsigned long nbytes, const void *in, void *out)
395 {
396 mode->gcm(ctx, nbytes, in, out);
397 }
398
399 CC_INLINE void ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
400 size_t tag_size, void *tag)
401 {
402 mode->finalize(ctx, tag_size, tag);
403 }
404
405 CC_INLINE void ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
406 {
407 mode->reset(ctx);
408 }
409
410
411 CC_INLINE void ccgcm_one_shot(const struct ccmode_gcm *mode,
412 unsigned long key_len, const void *key,
413 unsigned long iv_len, const void *iv,
414 unsigned long nbytes, const void *in, void *out,
415 unsigned long adata_len, const void* adata,
416 size_t tag_len, void *tag)
417 {
418 ccgcm_ctx_decl(mode->size, ctx);
419 mode->init(mode, ctx, key_len, key);
420 mode->set_iv(ctx, iv_len, iv);
421 mode->gmac(ctx, adata_len, adata);
422 mode->gcm(ctx, nbytes, in, out);
423 mode->finalize(ctx, tag_len, tag);
424 ccgcm_ctx_clear(mode->size, ctx);
425 }
426
427 /* OMAC mode. */
428
429
430 /* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
431 for _size_. */
432 #define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
433 #define ccomac_ctx_clear(_size_, _name_) cc_ctx_clear(ccomac_ctx, _size_, _name_)
434
435 CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
436 {
437 return mode->size;
438 }
439
440 CC_INLINE unsigned long ccomac_block_size(const struct ccmode_omac *mode)
441 {
442 return mode->block_size;
443 }
444
445 CC_INLINE void ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx,
446 unsigned long tweak_len, unsigned long key_len, const void *key)
447 {
448 return mode->init(mode, ctx, tweak_len, key_len, key);
449 }
450
451 CC_INLINE int ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx,
452 unsigned long in_len, const void *tweak, const void *in, void *out)
453 {
454 return mode->omac(ctx, in_len, tweak, in, out);
455 }
456
457 CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
458 unsigned long tweak_len, unsigned long key_len, const void *key,
459 const void *tweak, unsigned long in_len, const void *in, void *out)
460 {
461 ccomac_ctx_decl(mode->size, ctx);
462 mode->init(mode, ctx, tweak_len, key_len, key);
463 int result = mode->omac(ctx, in_len, tweak, in, out);
464 ccomac_ctx_clear(mode->size, ctx);
465 return result;
466 }
467
468
469 #endif /* _CORECRYPTO_CCMODE_H_ */