]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccmode.h
0c7a19479c5f1e2b1d45ca10a43ee9c5bcf1504b
[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_zero(_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 size_t 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 nblocks, const void *in, void *out)
41 {
42 mode->ecb(ctx, nblocks, in, out);
43 }
44
45 CC_INLINE void ccecb_one_shot(const struct ccmode_ecb *mode,
46 size_t key_len, const void *key,
47 unsigned long nblocks, const void *in, void *out)
48 {
49 ccecb_ctx_decl(mode->size, ctx);
50 mode->init(mode, ctx, key_len, key);
51 mode->ecb(ctx, nblocks, in, out);
52 ccecb_ctx_clear(mode->size, ctx);
53 }
54
55 /* CBC mode. */
56
57 /* The CBC interface changed due to rdar://11468135. This macros is to indicate
58 to client which CBC API is implemented. Clients can support old versions of
59 corecrypto at build time using this.
60 */
61 #define __CC_HAS_FIX_FOR_11468135__ 1
62
63 /* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
64 for _size_. */
65 #define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
66 #define cccbc_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
67
68 /* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
69 struct ccmode_cbc for _size_. */
70 #define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
71 #define cccbc_iv_clear(_size_, _name_) cc_ctx_clear(cccbc_iv, _size_, _name_)
72
73 /* Actual symmetric algorithm implementation can provide you one of these.
74
75 Alternatively you can create a ccmode_cbc instance from any ccmode_ecb
76 cipher. To do so, statically initialize a struct ccmode_cbc using the
77 CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros.
78 Alternatively you can dynamically initialize a struct ccmode_cbc
79 ccmode_factory_cbc_decrypt() or ccmode_factory_cbc_encrypt(). */
80
81 CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
82 {
83 return mode->size;
84 }
85
86 CC_INLINE unsigned long cccbc_block_size(const struct ccmode_cbc *mode)
87 {
88 return mode->block_size;
89 }
90
91 CC_INLINE void cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
92 size_t key_len, const void *key)
93 {
94 mode->init(mode, ctx, key_len, key);
95 }
96
97 CC_INLINE void cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx,
98 const void *iv)
99 {
100 if (iv)
101 cc_copy(mode->block_size, iv_ctx, iv);
102 else
103 cc_zero(mode->block_size, iv_ctx);
104 }
105
106 CC_INLINE void cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
107 cccbc_iv *iv, unsigned long nblocks,
108 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,
115 const void *iv, unsigned long nblocks,
116 const void *in, void *out)
117 {
118 cccbc_ctx_decl(mode->size, ctx);
119 cccbc_iv_decl(mode->block_size, iv_ctx);
120 mode->init(mode, ctx, key_len, key);
121 if (iv)
122 cccbc_set_iv(mode, iv_ctx, iv);
123 else
124 cc_zero(mode->block_size, iv_ctx);
125 mode->cbc(ctx, iv_ctx, nblocks, in, out);
126 cccbc_ctx_clear(mode->size, ctx);
127 }
128
129 /* CFB mode. */
130
131 /* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
132 for _size_. */
133 #define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
134 #define cccfb_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
135
136 CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
137 {
138 return mode->size;
139 }
140
141 CC_INLINE unsigned long cccfb_block_size(const struct ccmode_cfb *mode)
142 {
143 return mode->block_size;
144 }
145
146 CC_INLINE void cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
147 size_t key_len, const void *key,
148 const void *iv)
149 {
150 mode->init(mode, ctx, key_len, key, iv);
151 }
152
153 CC_INLINE void cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
154 size_t nbytes, const void *in, void *out)
155 {
156 mode->cfb(ctx, nbytes, in, out);
157 }
158
159 CC_INLINE void cccfb_one_shot(const struct ccmode_cfb *mode,
160 size_t key_len, const void *key, const void *iv,
161 size_t nbytes, const void *in, void *out)
162 {
163 cccfb_ctx_decl(mode->size, ctx);
164 mode->init(mode, ctx, key_len, key, iv);
165 mode->cfb(ctx, nbytes, in, out);
166 cccfb_ctx_clear(mode->size, ctx);
167 }
168
169 /* CFB8 mode. */
170
171 /* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
172 for _size_. */
173 #define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
174 #define cccfb8_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
175
176 CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
177 {
178 return mode->size;
179 }
180
181 CC_INLINE unsigned long cccfb8_block_size(const struct ccmode_cfb8 *mode)
182 {
183 return mode->block_size;
184 }
185
186 CC_INLINE void cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
187 size_t key_len, const void *key, const void *iv)
188 {
189 mode->init(mode, ctx, key_len, key, iv);
190 }
191
192 CC_INLINE void cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
193 size_t nbytes, const void *in, void *out)
194 {
195 mode->cfb8(ctx, nbytes, in, out);
196 }
197
198 CC_INLINE void cccfb8_one_shot(const struct ccmode_cfb8 *mode,
199 size_t key_len, const void *key, const void *iv,
200 size_t nbytes, const void *in, void *out)
201 {
202 cccfb8_ctx_decl(mode->size, ctx);
203 mode->init(mode, ctx, key_len, key, iv);
204 mode->cfb8(ctx, nbytes, in, out);
205 cccfb8_ctx_clear(mode->size, ctx);
206 }
207
208 /* CTR mode. */
209
210 /* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
211 for _size_. */
212 #define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
213 #define ccctr_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
214
215 /* This is Integer Counter Mode: The IV is the initial value of the counter
216 that is incremented by 1 for each new block. Use the mode flags to select
217 if the IV/Counter is stored in big or little endian. */
218
219 CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
220 {
221 return mode->size;
222 }
223
224 CC_INLINE unsigned long ccctr_block_size(const struct ccmode_ctr *mode)
225 {
226 return mode->block_size;
227 }
228
229 CC_INLINE void ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
230 size_t key_len, const void *key, const void *iv)
231 {
232 mode->init(mode, ctx, key_len, key, iv);
233 }
234
235 CC_INLINE void ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
236 size_t nbytes, const void *in, void *out)
237 {
238 mode->ctr(ctx, nbytes, in, out);
239 }
240
241 CC_INLINE void ccctr_one_shot(const struct ccmode_ctr *mode,
242 size_t key_len, const void *key, const void *iv,
243 size_t nbytes, const void *in, void *out)
244 {
245 ccctr_ctx_decl(mode->size, ctx);
246 mode->init(mode, ctx, key_len, key, iv);
247 mode->ctr(ctx, nbytes, 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_zero(_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 size_t 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 size_t nbytes, const void *in, void *out)
277 {
278 mode->ofb(ctx, nbytes, in, out);
279 }
280
281 CC_INLINE void ccofb_one_shot(const struct ccmode_ofb *mode,
282 size_t key_len, const void *key, const void *iv,
283 size_t nbytes, 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, nbytes, 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_zero(_size_, _name_)
299
300 /* Declare a xts tweak named _name_. Pass the tweak_size field of a
301 struct ccmode_xts for _size_. */
302 #define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
303 #define ccxts_tweak_clear(_size_, _name_) cc_zero(_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
311 ccmode_factory_xts_decrypt() 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 size_t key_len, const void *key,
330 const void *tweak_key)
331 {
332 mode->init(mode, ctx, key_len, key, tweak_key);
333 }
334
335 CC_INLINE void ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx,
336 ccxts_tweak *tweak, const void *iv)
337 {
338 mode->set_tweak(ctx, tweak, iv);
339 }
340
341 CC_INLINE void *ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx,
342 ccxts_tweak *tweak, unsigned long nblocks, const void *in, void *out)
343 {
344 return mode->xts(ctx, tweak, nblocks, in, out);
345 }
346
347 CC_INLINE void ccxts_one_shot(const struct ccmode_xts *mode,
348 size_t key_len, const void *key,
349 const void *tweak_key, const void *iv,
350 unsigned long nblocks, const void *in, void *out)
351 {
352 ccxts_ctx_decl(mode->size, ctx);
353 ccxts_tweak_decl(mode->tweak_size, tweak);
354 mode->init(mode, ctx, key_len, key, tweak_key);
355 mode->set_tweak(ctx, tweak, iv);
356 mode->xts(ctx, tweak, nblocks, in, out);
357 ccxts_ctx_clear(mode->size, ctx);
358 ccxts_tweak_clear(mode->tweak_size, tweak);
359 }
360
361 /* GCM mode. */
362
363 /* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
364 for _size_. */
365 #define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_)
366 #define ccgcm_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
367
368 CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
369 {
370 return mode->size;
371 }
372
373 CC_INLINE unsigned long ccgcm_block_size(const struct ccmode_gcm *mode)
374 {
375 return mode->block_size;
376 }
377
378 CC_INLINE void ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
379 size_t key_len, const void *key)
380 {
381 mode->init(mode, ctx, key_len, key);
382 }
383
384 CC_INLINE void ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
385 size_t iv_size, const void *iv)
386 {
387 mode->set_iv(ctx, iv_size, iv);
388 }
389
390 CC_INLINE void ccgcm_gmac(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
391 size_t nbytes, const void *in)
392 {
393 mode->gmac(ctx, nbytes, in);
394 }
395
396 CC_INLINE void ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
397 size_t nbytes, const void *in, void *out)
398 {
399 mode->gcm(ctx, nbytes, in, out);
400 }
401
402 CC_INLINE void ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
403 size_t tag_size, void *tag)
404 {
405 mode->finalize(ctx, tag_size, tag);
406 }
407
408 CC_INLINE void ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
409 {
410 mode->reset(ctx);
411 }
412
413
414 CC_INLINE void ccgcm_one_shot(const struct ccmode_gcm *mode,
415 size_t key_len, const void *key,
416 size_t iv_len, const void *iv,
417 size_t adata_len, const void *adata,
418 size_t nbytes, const void *in, void *out,
419 size_t tag_len, void *tag)
420 {
421 ccgcm_ctx_decl(mode->size, ctx);
422 mode->init(mode, ctx, key_len, key);
423 mode->set_iv(ctx, iv_len, iv);
424 mode->gmac(ctx, adata_len, adata);
425 mode->gcm(ctx, nbytes, in, out);
426 mode->finalize(ctx, tag_len, tag);
427 ccgcm_ctx_clear(mode->size, ctx);
428 }
429
430 /* CCM */
431
432 #define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
433 #define ccccm_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
434
435 /* Declare a ccm nonce named _name_. Pass the mode->nonce_ctx_size for _size_. */
436 #define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl(ccccm_nonce, _size_, _name_)
437 #define ccccm_nonce_clear(_size_, _name_) cc_zero(_size_, _name_)
438
439
440 CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
441 {
442 return mode->size;
443 }
444
445 CC_INLINE unsigned long ccccm_block_size(const struct ccmode_ccm *mode)
446 {
447 return mode->block_size;
448 }
449
450 CC_INLINE void ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx,
451 size_t key_len, const void *key)
452 {
453 mode->init(mode, ctx, key_len, key);
454 }
455
456 CC_INLINE void ccccm_set_iv(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
457 size_t nonce_len, const void *nonce,
458 size_t mac_size, size_t auth_len, size_t data_len)
459 {
460 mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
461 }
462
463 CC_INLINE void ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
464 size_t nbytes, const void *in)
465 {
466 mode->cbcmac(ctx, nonce_ctx, nbytes, in);
467 }
468
469 CC_INLINE void ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
470 size_t nbytes, const void *in, void *out)
471 {
472 mode->ccm(ctx, nonce_ctx, nbytes, in, out);
473 }
474
475 CC_INLINE void ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
476 void *mac)
477 {
478 mode->finalize(ctx, nonce_ctx, mac);
479 }
480
481 CC_INLINE void ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
482 {
483 mode->reset(ctx, nonce_ctx);
484 }
485
486
487 CC_INLINE void ccccm_one_shot(const struct ccmode_ccm *mode,
488 unsigned long key_len, const void *key,
489 unsigned nonce_len, const void *nonce,
490 unsigned long nbytes, const void *in, void *out,
491 unsigned adata_len, const void* adata,
492 unsigned mac_size, void *mac)
493 {
494 ccccm_ctx_decl(mode->size, ctx);
495 ccccm_nonce_decl(mode->nonce_size, nonce_ctx);
496 mode->init(mode, ctx, key_len, key);
497 mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
498 mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
499 mode->ccm(ctx, nonce_ctx, nbytes, in, out);
500 mode->finalize(ctx, nonce_ctx, mac);
501 ccccm_ctx_clear(mode->size, ctx);
502 ccccm_nonce_clear(mode->size, nonce_ctx);
503 }
504
505
506 /* OMAC mode. */
507
508
509 /* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
510 for _size_. */
511 #define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
512 #define ccomac_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
513
514 CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
515 {
516 return mode->size;
517 }
518
519 CC_INLINE unsigned long ccomac_block_size(const struct ccmode_omac *mode)
520 {
521 return mode->block_size;
522 }
523
524 CC_INLINE void ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx,
525 size_t tweak_len, size_t key_len, const void *key)
526 {
527 return mode->init(mode, ctx, tweak_len, key_len, key);
528 }
529
530 CC_INLINE int ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx,
531 unsigned long nblocks, const void *tweak, const void *in, void *out)
532 {
533 return mode->omac(ctx, nblocks, tweak, in, out);
534 }
535
536 CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
537 size_t tweak_len, size_t key_len, const void *key,
538 const void *tweak, unsigned long nblocks, const void *in, void *out)
539 {
540 ccomac_ctx_decl(mode->size, ctx);
541 mode->init(mode, ctx, tweak_len, key_len, key);
542 int result = mode->omac(ctx, nblocks, tweak, in, out);
543 ccomac_ctx_clear(mode->size, ctx);
544 return result;
545 }
546
547
548 #endif /* _CORECRYPTO_CCMODE_H_ */