]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccmode.h
98057cce4aec068db8ec2180dba5ab16ea1e33c4
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccmode.h
1 /*
2 * ccmode.h
3 * corecrypto
4 *
5 * Created on 12/07/2010
6 *
7 * Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
8 *
9 */
10
11 #ifndef _CORECRYPTO_CCMODE_H_
12 #define _CORECRYPTO_CCMODE_H_
13
14 #include <corecrypto/cc.h>
15 #include <corecrypto/ccmode_impl.h>
16 #include <corecrypto/ccmode_siv.h>
17
18 /* ECB mode. */
19
20 /* Declare a ecb key named _name_. Pass the size field of a struct ccmode_ecb
21 for _size_. */
22 #define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl(ccecb_ctx, _size_, _name_)
23 #define ccecb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
24
25 CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
26 {
27 return mode->size;
28 }
29
30 CC_INLINE size_t ccecb_block_size(const struct ccmode_ecb *mode)
31 {
32 return mode->block_size;
33 }
34
35 CC_INLINE void ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx,
36 size_t key_len, const void *key)
37 {
38 mode->init(mode, ctx, key_len, key);
39 }
40
41 CC_INLINE void ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx,
42 size_t nblocks, const void *in, void *out)
43 {
44 mode->ecb(ctx, nblocks, in, out);
45 }
46
47 CC_INLINE void ccecb_one_shot(const struct ccmode_ecb *mode,
48 size_t key_len, const void *key,
49 size_t nblocks, const void *in, void *out)
50 {
51 ccecb_ctx_decl(mode->size, ctx);
52 mode->init(mode, ctx, key_len, key);
53 mode->ecb(ctx, nblocks, 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_clear(_size_, _name_)
69
70 /* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
71 struct ccmode_cbc for _size_. */
72 #define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
73 #define cccbc_iv_clear(_size_, _name_) cc_clear(_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.
80 Alternatively you can dynamically initialize a struct ccmode_cbc
81 ccmode_factory_cbc_decrypt() 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 size_t 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 size_t 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,
100 const void *iv)
101 {
102 if (iv)
103 cc_copy(mode->block_size, iv_ctx, iv);
104 else
105 cc_zero(mode->block_size, iv_ctx);
106 }
107
108 CC_INLINE void cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
109 cccbc_iv *iv, size_t nblocks,
110 const void *in, void *out)
111 {
112 mode->cbc(ctx, iv, nblocks, in, out);
113 }
114
115 CC_INLINE void cccbc_one_shot(const struct ccmode_cbc *mode,
116 size_t key_len, const void *key,
117 const void *iv, size_t nblocks,
118 const void *in, void *out)
119 {
120 cccbc_ctx_decl(mode->size, ctx);
121 cccbc_iv_decl(mode->block_size, iv_ctx);
122 mode->init(mode, ctx, key_len, key);
123 if (iv)
124 cccbc_set_iv(mode, iv_ctx, iv);
125 else
126 cc_zero(mode->block_size, iv_ctx);
127 mode->cbc(ctx, iv_ctx, nblocks, in, out);
128 cccbc_ctx_clear(mode->size, ctx);
129 }
130
131 /* CFB mode. */
132
133 /* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
134 for _size_. */
135 #define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
136 #define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
137
138 CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
139 {
140 return mode->size;
141 }
142
143 CC_INLINE size_t cccfb_block_size(const struct ccmode_cfb *mode)
144 {
145 return mode->block_size;
146 }
147
148 CC_INLINE void cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
149 size_t key_len, const void *key,
150 const void *iv)
151 {
152 mode->init(mode, ctx, key_len, key, iv);
153 }
154
155 CC_INLINE void cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
156 size_t nbytes, const void *in, void *out)
157 {
158 mode->cfb(ctx, nbytes, in, out);
159 }
160
161 CC_INLINE void cccfb_one_shot(const struct ccmode_cfb *mode,
162 size_t key_len, const void *key, const void *iv,
163 size_t nbytes, const void *in, void *out)
164 {
165 cccfb_ctx_decl(mode->size, ctx);
166 mode->init(mode, ctx, key_len, key, iv);
167 mode->cfb(ctx, nbytes, in, out);
168 cccfb_ctx_clear(mode->size, ctx);
169 }
170
171 /* CFB8 mode. */
172
173 /* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
174 for _size_. */
175 #define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
176 #define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
177
178 CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
179 {
180 return mode->size;
181 }
182
183 CC_INLINE size_t cccfb8_block_size(const struct ccmode_cfb8 *mode)
184 {
185 return mode->block_size;
186 }
187
188 CC_INLINE void cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
189 size_t key_len, const void *key, const void *iv)
190 {
191 mode->init(mode, ctx, key_len, key, iv);
192 }
193
194 CC_INLINE void cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
195 size_t nbytes, const void *in, void *out)
196 {
197 mode->cfb8(ctx, nbytes, in, out);
198 }
199
200 CC_INLINE void cccfb8_one_shot(const struct ccmode_cfb8 *mode,
201 size_t key_len, const void *key, const void *iv,
202 size_t nbytes, const void *in, void *out)
203 {
204 cccfb8_ctx_decl(mode->size, ctx);
205 mode->init(mode, ctx, key_len, key, iv);
206 mode->cfb8(ctx, nbytes, in, out);
207 cccfb8_ctx_clear(mode->size, ctx);
208 }
209
210 /* CTR mode. */
211
212 /* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
213 for _size_. */
214 #define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
215 #define ccctr_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
216
217 /* This is Integer Counter Mode: The IV is the initial value of the counter
218 that is incremented by 1 for each new block. Use the mode flags to select
219 if the IV/Counter is stored in big or little endian. */
220
221 CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
222 {
223 return mode->size;
224 }
225
226 CC_INLINE size_t ccctr_block_size(const struct ccmode_ctr *mode)
227 {
228 return mode->block_size;
229 }
230
231 CC_INLINE void ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
232 size_t key_len, const void *key, const void *iv)
233 {
234 mode->init(mode, ctx, key_len, key, iv);
235 }
236
237 CC_INLINE void ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
238 size_t nbytes, const void *in, void *out)
239 {
240 mode->ctr(ctx, nbytes, in, out);
241 }
242
243 CC_INLINE void ccctr_one_shot(const struct ccmode_ctr *mode,
244 size_t key_len, const void *key, const void *iv,
245 size_t nbytes, const void *in, void *out)
246 {
247 ccctr_ctx_decl(mode->size, ctx);
248 mode->init(mode, ctx, key_len, key, iv);
249 mode->ctr(ctx, nbytes, in, out);
250 ccctr_ctx_clear(mode->size, ctx);
251 }
252
253
254 /* OFB mode. */
255
256 /* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
257 for _size_. */
258 #define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
259 #define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
260
261 CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
262 {
263 return mode->size;
264 }
265
266 CC_INLINE size_t ccofb_block_size(const struct ccmode_ofb *mode)
267 {
268 return mode->block_size;
269 }
270
271 CC_INLINE void ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
272 size_t key_len, const void *key, const void *iv)
273 {
274 mode->init(mode, ctx, key_len, key, iv);
275 }
276
277 CC_INLINE void ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
278 size_t nbytes, const void *in, void *out)
279 {
280 mode->ofb(ctx, nbytes, in, out);
281 }
282
283 CC_INLINE void ccofb_one_shot(const struct ccmode_ofb *mode,
284 size_t key_len, const void *key, const void *iv,
285 size_t nbytes, const void *in, void *out)
286 {
287 ccofb_ctx_decl(mode->size, ctx);
288 mode->init(mode, ctx, key_len, key, iv);
289 mode->ofb(ctx, nbytes, in, out);
290 ccofb_ctx_clear(mode->size, ctx);
291 }
292
293 /* Authenticated cipher modes. */
294
295 /* XTS mode. */
296
297 /* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
298 for _size_. */
299 #define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
300 #define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
301
302 /* Declare a xts tweak named _name_. Pass the tweak_size field of a
303 struct ccmode_xts for _size_. */
304 #define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
305 #define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
306
307 /* Actual symmetric algorithm implementation can provide you one of these.
308
309 Alternatively you can create a ccmode_xts instance from any ccmode_ecb
310 cipher. To do so, statically initialize a struct ccmode_xts using the
311 CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
312 you can dynamically initialize a struct ccmode_xts
313 ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
314
315 /* NOTE that xts mode does not do cts padding. It's really an xex mode.
316 If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
317 functions. Also note that xts only works for ecb modes with a block_size
318 of 16. */
319
320 CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
321 {
322 return mode->size;
323 }
324
325 CC_INLINE size_t ccxts_block_size(const struct ccmode_xts *mode)
326 {
327 return mode->block_size;
328 }
329
330 CC_INLINE void ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx,
331 size_t key_len, const void *key,
332 const void *tweak_key)
333 {
334 mode->init(mode, ctx, key_len, key, tweak_key);
335 }
336
337 CC_INLINE void ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx,
338 ccxts_tweak *tweak, const void *iv)
339 {
340 mode->set_tweak(ctx, tweak, iv);
341 }
342
343 CC_INLINE void *ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx,
344 ccxts_tweak *tweak, size_t nblocks, const void *in, void *out)
345 {
346 return mode->xts(ctx, tweak, nblocks, in, out);
347 }
348
349 CC_INLINE void ccxts_one_shot(const struct ccmode_xts *mode,
350 size_t key_len, const void *key,
351 const void *tweak_key, const void *iv,
352 size_t nblocks, const void *in, void *out)
353 {
354 ccxts_ctx_decl(mode->size, ctx);
355 ccxts_tweak_decl(mode->tweak_size, tweak);
356 mode->init(mode, ctx, key_len, key, tweak_key);
357 mode->set_tweak(ctx, tweak, iv);
358 mode->xts(ctx, tweak, nblocks, in, out);
359 ccxts_ctx_clear(mode->size, ctx);
360 ccxts_tweak_clear(mode->tweak_size, tweak);
361 }
362
363 /* GCM mode. */
364
365 /* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
366 for _size_. */
367 #define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_)
368 #define ccgcm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
369
370 CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
371 {
372 return mode->size;
373 }
374
375 CC_INLINE size_t ccgcm_block_size(const struct ccmode_gcm *mode)
376 {
377 return mode->block_size;
378 }
379
380 CC_INLINE int ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
381 size_t key_len, const void *key)
382 {
383 return mode->init(mode, ctx, key_len, key);
384 }
385
386 CC_INLINE int ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
387 size_t iv_size, const void *iv)
388 {
389 return mode->set_iv(ctx, iv_size, iv);
390 }
391
392 // add Additional authenticated data (AAD)
393 CC_INLINE int ccgcm_aad(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
394 size_t nbytes, const void *additional_data)
395 {
396 return mode->gmac(ctx, nbytes, additional_data);
397 }
398
399 CC_INLINE int ccgcm_gmac(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
400 size_t nbytes, const void *in)
401 {
402 return mode->gmac(ctx, nbytes, in);
403 }
404
405 // encrypt or decrypt
406 CC_INLINE int ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
407 size_t nbytes, const void *in, void *out)
408 {
409 return mode->gcm(ctx, nbytes, in, out);
410 }
411
412 CC_INLINE int ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
413 size_t tag_size, void *tag)
414 {
415 return mode->finalize(ctx, tag_size, tag);
416 }
417
418 CC_INLINE int ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
419 {
420 return mode->reset(ctx);
421 }
422
423
424 int ccgcm_one_shot(const struct ccmode_gcm *mode,
425 size_t key_len, const void *key,
426 size_t iv_len, const void *iv,
427 size_t adata_len, const void *adata,
428 size_t nbytes, const void *in, void *out,
429 size_t tag_len, void *tag);
430
431 //do not call ccgcm_one_shot_legacy() in any new application
432 int ccgcm_one_shot_legacy(const struct ccmode_gcm *mode,
433 size_t key_len, const void *key,
434 size_t iv_len, const void *iv,
435 size_t adata_len, const void *adata,
436 size_t nbytes, const void *in, void *out,
437 size_t tag_len, void *tag);
438
439
440 /* CCM */
441
442 #define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
443 #define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
444
445 /* Declare a ccm nonce named _name_. Pass the mode->nonce_ctx_size for _size_. */
446 #define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl(ccccm_nonce, _size_, _name_)
447 #define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
448
449
450 CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
451 {
452 return mode->size;
453 }
454
455 CC_INLINE size_t ccccm_block_size(const struct ccmode_ccm *mode)
456 {
457 return mode->block_size;
458 }
459
460 CC_INLINE int ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx,
461 size_t key_len, const void *key)
462 {
463 return mode->init(mode, ctx, key_len, key);
464 }
465
466 CC_INLINE int ccccm_set_iv(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
467 size_t nonce_len, const void *nonce,
468 size_t mac_size, size_t auth_len, size_t data_len)
469 {
470 return mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
471 }
472
473 CC_INLINE int ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
474 size_t nbytes, const void *in)
475 {
476 return mode->cbcmac(ctx, nonce_ctx, nbytes, in);
477 }
478
479 CC_INLINE int ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
480 size_t nbytes, const void *in, void *out)
481 {
482 return mode->ccm(ctx, nonce_ctx, nbytes, in, out);
483 }
484
485 CC_INLINE int ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
486 void *mac)
487 {
488 return mode->finalize(ctx, nonce_ctx, mac);
489 }
490
491 CC_INLINE int ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
492 {
493 return mode->reset(ctx, nonce_ctx);
494 }
495
496
497 CC_INLINE int ccccm_one_shot(const struct ccmode_ccm *mode,
498 size_t key_len, const void *key,
499 unsigned nonce_len, const void *nonce,
500 size_t nbytes, const void *in, void *out,
501 unsigned adata_len, const void* adata,
502 unsigned mac_size, void *mac)
503 {
504 int rc=0;
505 ccccm_ctx_decl(mode->size, ctx);
506 ccccm_nonce_decl(mode->nonce_size, nonce_ctx);
507 rc = mode->init(mode, ctx, key_len, key);
508 if(rc==0) rc=mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
509 if(rc==0) rc=mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
510 if(rc==0) rc=mode->ccm(ctx, nonce_ctx, nbytes, in, out);
511 if(rc==0) rc=mode->finalize(ctx, nonce_ctx, mac);
512 ccccm_ctx_clear(mode->size, ctx);
513 ccccm_nonce_clear(mode->size, nonce_ctx);
514
515 return rc;
516 }
517
518
519 /* OMAC mode. */
520
521
522 /* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
523 for _size_. */
524 #define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
525 #define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
526
527 CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
528 {
529 return mode->size;
530 }
531
532 CC_INLINE size_t ccomac_block_size(const struct ccmode_omac *mode)
533 {
534 return mode->block_size;
535 }
536
537 CC_INLINE void ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx,
538 size_t tweak_len, size_t key_len, const void *key)
539 {
540 mode->init(mode, ctx, tweak_len, key_len, key);
541 }
542
543 CC_INLINE int ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx,
544 size_t nblocks, const void *tweak, const void *in, void *out)
545 {
546 return mode->omac(ctx, nblocks, tweak, in, out);
547 }
548
549 CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
550 size_t tweak_len, size_t key_len, const void *key,
551 const void *tweak, size_t nblocks, const void *in, void *out)
552 {
553 ccomac_ctx_decl(mode->size, ctx);
554 mode->init(mode, ctx, tweak_len, key_len, key);
555 int result = mode->omac(ctx, nblocks, tweak, in, out);
556 ccomac_ctx_clear(mode->size, ctx);
557 return result;
558 }
559
560
561 #endif /* _CORECRYPTO_CCMODE_H_ */