]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccmode.h
xnu-3789.31.2.tar.gz
[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 int ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx,
36 size_t key_len, const void *key)
37 {
38 return mode->init(mode, ctx, key_len, key);
39 }
40
41 CC_INLINE int ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx,
42 size_t nblocks, const void *in, void *out)
43 {
44 return mode->ecb(ctx, nblocks, in, out);
45 }
46
47 CC_INLINE int 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 int rc;
52 ccecb_ctx_decl(mode->size, ctx);
53 rc = mode->init(mode, ctx, key_len, key);
54 mode->ecb(ctx, nblocks, in, out);
55 ccecb_ctx_clear(mode->size, ctx);
56 return rc;
57 }
58
59 /* CBC mode. */
60
61 /* The CBC interface changed due to rdar://11468135. This macros is to indicate
62 to client which CBC API is implemented. Clients can support old versions of
63 corecrypto at build time using this.
64 */
65 #define __CC_HAS_FIX_FOR_11468135__ 1
66
67 /* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
68 for _size_. */
69 #define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
70 #define cccbc_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
71
72 /* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
73 struct ccmode_cbc for _size_. */
74 #define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
75 #define cccbc_iv_clear(_size_, _name_) cc_clear(_size_, _name_)
76
77 /* Actual symmetric algorithm implementation can provide you one of these.
78
79 Alternatively you can create a ccmode_cbc instance from any ccmode_ecb
80 cipher. To do so, statically initialize a struct ccmode_cbc using the
81 CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros.
82 Alternatively you can dynamically initialize a struct ccmode_cbc
83 ccmode_factory_cbc_decrypt() or ccmode_factory_cbc_encrypt(). */
84
85 CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
86 {
87 return mode->size;
88 }
89
90 CC_INLINE size_t cccbc_block_size(const struct ccmode_cbc *mode)
91 {
92 return mode->block_size;
93 }
94
95 CC_INLINE int cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
96 size_t key_len, const void *key)
97 {
98 return mode->init(mode, ctx, key_len, key);
99 }
100
101 CC_INLINE int cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx,
102 const void *iv)
103 {
104 if (iv)
105 cc_copy(mode->block_size, iv_ctx, iv);
106 else
107 cc_zero(mode->block_size, iv_ctx);
108 return 0;
109 }
110
111 CC_INLINE int cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
112 cccbc_iv *iv, size_t nblocks,
113 const void *in, void *out)
114 {
115 return mode->cbc(ctx, iv, nblocks, in, out);
116 }
117
118 CC_INLINE int cccbc_one_shot(const struct ccmode_cbc *mode,
119 size_t key_len, const void *key,
120 const void *iv, size_t nblocks,
121 const void *in, void *out)
122 {
123 int rc;
124 cccbc_ctx_decl(mode->size, ctx);
125 cccbc_iv_decl(mode->block_size, iv_ctx);
126 rc = mode->init(mode, ctx, key_len, key);
127 if (iv)
128 cccbc_set_iv(mode, iv_ctx, iv);
129 else
130 cc_zero(mode->block_size, iv_ctx);
131 mode->cbc(ctx, iv_ctx, nblocks, in, out);
132 cccbc_ctx_clear(mode->size, ctx);
133 return rc;
134 }
135
136 /* CFB mode. */
137
138 /* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
139 for _size_. */
140 #define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
141 #define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
142
143 CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
144 {
145 return mode->size;
146 }
147
148 CC_INLINE size_t cccfb_block_size(const struct ccmode_cfb *mode)
149 {
150 return mode->block_size;
151 }
152
153 CC_INLINE int cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
154 size_t key_len, const void *key,
155 const void *iv)
156 {
157 return mode->init(mode, ctx, key_len, key, iv);
158 }
159
160 CC_INLINE int cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
161 size_t nbytes, const void *in, void *out)
162 {
163 return mode->cfb(ctx, nbytes, in, out);
164 }
165
166 CC_INLINE int cccfb_one_shot(const struct ccmode_cfb *mode,
167 size_t key_len, const void *key, const void *iv,
168 size_t nbytes, const void *in, void *out)
169 {
170 int rc;
171 cccfb_ctx_decl(mode->size, ctx);
172 rc = mode->init(mode, ctx, key_len, key, iv);
173 mode->cfb(ctx, nbytes, in, out);
174 cccfb_ctx_clear(mode->size, ctx);
175 return rc;
176 }
177
178 /* CFB8 mode. */
179
180 /* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
181 for _size_. */
182 #define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
183 #define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
184
185 CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
186 {
187 return mode->size;
188 }
189
190 CC_INLINE size_t cccfb8_block_size(const struct ccmode_cfb8 *mode)
191 {
192 return mode->block_size;
193 }
194
195 CC_INLINE int cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
196 size_t key_len, const void *key, const void *iv)
197 {
198 return mode->init(mode, ctx, key_len, key, iv);
199 }
200
201 CC_INLINE int cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
202 size_t nbytes, const void *in, void *out)
203 {
204 return mode->cfb8(ctx, nbytes, in, out);
205 }
206
207 CC_INLINE int cccfb8_one_shot(const struct ccmode_cfb8 *mode,
208 size_t key_len, const void *key, const void *iv,
209 size_t nbytes, const void *in, void *out)
210 {
211 int rc;
212 cccfb8_ctx_decl(mode->size, ctx);
213 rc = mode->init(mode, ctx, key_len, key, iv);
214 mode->cfb8(ctx, nbytes, in, out);
215 cccfb8_ctx_clear(mode->size, ctx);
216 return rc;
217 }
218
219 /* CTR mode. */
220
221 /* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
222 for _size_. */
223 #define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
224 #define ccctr_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
225
226 /* This is Integer Counter Mode: The IV is the initial value of the counter
227 that is incremented by 1 for each new block. Use the mode flags to select
228 if the IV/Counter is stored in big or little endian. */
229
230 CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
231 {
232 return mode->size;
233 }
234
235 CC_INLINE size_t ccctr_block_size(const struct ccmode_ctr *mode)
236 {
237 return mode->block_size;
238 }
239
240 CC_INLINE int ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
241 size_t key_len, const void *key, const void *iv)
242 {
243 return mode->init(mode, ctx, key_len, key, iv);
244 }
245
246 CC_INLINE int ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
247 size_t nbytes, const void *in, void *out)
248 {
249 return mode->ctr(ctx, nbytes, in, out);
250 }
251
252 CC_INLINE int ccctr_one_shot(const struct ccmode_ctr *mode,
253 size_t key_len, const void *key, const void *iv,
254 size_t nbytes, const void *in, void *out)
255 {
256 int rc;
257 ccctr_ctx_decl(mode->size, ctx);
258 rc = mode->init(mode, ctx, key_len, key, iv);
259 mode->ctr(ctx, nbytes, in, out);
260 ccctr_ctx_clear(mode->size, ctx);
261 return rc;
262 }
263
264
265 /* OFB mode. */
266
267 /* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
268 for _size_. */
269 #define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
270 #define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
271
272 CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
273 {
274 return mode->size;
275 }
276
277 CC_INLINE size_t ccofb_block_size(const struct ccmode_ofb *mode)
278 {
279 return mode->block_size;
280 }
281
282 CC_INLINE int ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
283 size_t key_len, const void *key, const void *iv)
284 {
285 return mode->init(mode, ctx, key_len, key, iv);
286 }
287
288 CC_INLINE int ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
289 size_t nbytes, const void *in, void *out)
290 {
291 return mode->ofb(ctx, nbytes, in, out);
292 }
293
294 CC_INLINE int ccofb_one_shot(const struct ccmode_ofb *mode,
295 size_t key_len, const void *key, const void *iv,
296 size_t nbytes, const void *in, void *out)
297 {
298 int rc;
299 ccofb_ctx_decl(mode->size, ctx);
300 rc = mode->init(mode, ctx, key_len, key, iv);
301 mode->ofb(ctx, nbytes, in, out);
302 ccofb_ctx_clear(mode->size, ctx);
303 return rc;
304 }
305
306 /* XTS mode. */
307
308 /* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
309 for _size_. */
310 #define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
311 #define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
312
313 /* Declare a xts tweak named _name_. Pass the tweak_size field of a
314 struct ccmode_xts for _size_. */
315 #define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
316 #define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
317
318 /* Actual symmetric algorithm implementation can provide you one of these.
319
320 Alternatively you can create a ccmode_xts instance from any ccmode_ecb
321 cipher. To do so, statically initialize a struct ccmode_xts using the
322 CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
323 you can dynamically initialize a struct ccmode_xts
324 ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
325
326 /* NOTE that xts mode does not do cts padding. It's really an xex mode.
327 If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
328 functions. Also note that xts only works for ecb modes with a block_size
329 of 16. */
330
331 CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
332 {
333 return mode->size;
334 }
335
336 CC_INLINE size_t ccxts_block_size(const struct ccmode_xts *mode)
337 {
338 return mode->block_size;
339 }
340
341 /*!
342 @function ccxts_init
343 @abstract Initialize an XTS context.
344
345 @param mode Descriptor for the mode
346 @param ctx Context for this instance
347 @param key_nbytes Length of the key arguments in bytes
348 @param data_key Key for data encryption
349 @param tweak_key Key for tweak generation
350
351 @result 0 iff successful.
352
353 @discussion For security reasons, the two keys must be different.
354 */
355 CC_INLINE int ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx,
356 size_t key_nbytes, const void *data_key,
357 const void *tweak_key)
358 {
359 return mode->init(mode, ctx, key_nbytes, data_key, tweak_key);
360 }
361
362 /*!
363 @function ccxts_set_tweak
364 @abstract Initialize the tweak for a sector.
365
366 @param mode Descriptor for the mode
367 @param ctx Context for this instance
368 @param tweak Context for the tweak for this sector
369 @param iv Data used to generate the tweak
370
371 @discussion The IV must be exactly one block in length.
372 */
373 CC_INLINE int ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx,
374 ccxts_tweak *tweak, const void *iv)
375 {
376 return mode->set_tweak(ctx, tweak, iv);
377 }
378
379 /*!
380 @function ccxts_update
381 @abstract Encrypt or decrypt data.
382
383 @param mode Descriptor for the mode
384 @param ctx Context for an instance
385 @param tweak Context for the tweak for this sector
386 @param nblocks Length of the data in blocks
387 @param in Input data
388 @param out Output buffer
389
390 @result The updated internal buffer of the tweak context. May be ignored.
391 */
392 CC_INLINE void *ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx,
393 ccxts_tweak *tweak, size_t nblocks, const void *in, void *out)
394 {
395 return mode->xts(ctx, tweak, nblocks, in, out);
396 }
397
398 /*!
399 @function ccxts_one_shot
400 @abstract Encrypt or decrypt data in XTS mode.
401
402 @param mode Descriptor for the mode
403 @param key_nbytes Length of the key arguments in bytes
404 @param data_key Key for data encryption
405 @param tweak_key Key for tweak generation
406 @param iv Data used to generate the tweak
407 @param nblocks Length of the data in blocks
408 @param in Input data
409 @param out Output buffer
410
411 @result 0 iff successful.
412
413 @discussion For security reasons, the two keys must be different.
414 */
415 int ccxts_one_shot(const struct ccmode_xts *mode,
416 size_t key_nbytes, const void *data_key,
417 const void *tweak_key, const void *iv,
418 size_t nblocks, const void *in, void *out);
419
420 /* Authenticated cipher modes. */
421
422 /* GCM mode. */
423
424 /* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
425 for _size_. */
426 #define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_)
427 #define ccgcm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
428
429 #define CCGCM_IV_NBYTES 12
430 #define CCGCM_BLOCK_NBYTES 16
431
432 CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
433 {
434 return mode->size;
435 }
436
437 CC_INLINE size_t ccgcm_block_size(const struct ccmode_gcm *mode)
438 {
439 return mode->block_size;
440 }
441
442 /*!
443 @function ccgcm_init
444 @abstract Initialize a GCM context.
445
446 @param mode Descriptor for the mode
447 @param ctx Context for this instance
448 @param key_nbytes Length of the key in bytes
449 @param key Key for the underlying blockcipher (AES)
450
451 @result 0 iff successful.
452
453 @discussion The correct sequence of calls is:
454
455 @code ccgcm_init(...)
456 ccgcm_set_iv(...)
457 ccgcm_aad(...) (may be called zero or more times)
458 ccgcm_update(...) (may be called zero or more times)
459 ccgcm_finalize(...)
460
461 To reuse the context for additional encryptions, follow this sequence:
462
463 @code ccgcm_reset(...)
464 ccgcm_set_iv(...)
465 ccgcm_aad(...) (may be called zero or more times)
466 ccgcm_update(...) (may be called zero or more times)
467 ccgcm_finalize(...)
468
469 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
470
471 @warning It is not permitted to call @p ccgcm_inc_iv after initializing the cipher via the @p ccgcm_init interface. Nonzero is returned in the event of an improper call sequence.
472
473 */
474 CC_INLINE int ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
475 size_t key_nbytes, const void *key)
476 {
477 return mode->init(mode, ctx, key_nbytes, key);
478 }
479
480 /*!
481 @function ccgcm_init_with_iv
482 @abstract Initialize a GCM context to manage IVs internally.
483
484 @param mode Descriptor for the mode
485 @param ctx Context for this instance
486 @param key_nbytes Length of the key in bytes
487 @param key Key for the underlying blockcipher (AES)
488 @param iv IV for the first encryption
489
490 @result 0 iff successful.
491
492 @discussion The correct sequence of calls is:
493
494 @code ccgcm_init_with_iv(...)
495 ccgcm_aad(...) (may be called zero or more times)
496 ccgcm_update(...) (may be called zero or more times)
497 ccgcm_finalize(...)
498
499 To reuse the context for additional encryptions, follow this sequence:
500
501 @code ccgcm_reset(...)
502 ccgcm_inc_iv(...)
503 ccgcm_aad(...) (may be called zero or more times)
504 ccgcm_update(...) (may be called zero or more times)
505 ccgcm_finalize(...)
506
507 The IV must be exactly 12 bytes in length.
508
509 Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain protocols (e.g. TLS). In the call to @p ccgcm_inc_iv, the counter component will be interpreted as a big-endian, unsigned value and incremented in place.
510
511 @warning It is not permitted to call @p ccgcm_set_iv after initializing the cipher via the @p ccgcm_init_with_iv interface. Nonzero is returned in the event of an improper call sequence.
512
513 @warning The security of GCM depends on the uniqueness of key-IV pairs. To avoid key-IV repetition, callers should not initialize multiple contexts with the same key material via the @p ccgcm_init_with_iv interface.
514 */
515 int ccgcm_init_with_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
516 size_t key_nbytes, const void *key,
517 const void *iv);
518
519 /*!
520 @function ccgcm_set_iv
521 @abstract Set the IV for encryption.
522
523 @param mode Descriptor for the mode
524 @param ctx Context for this instance
525 @param iv_nbytes Length of the IV in bytes
526 @param iv Initialization vector
527
528 @result 0 iff successful.
529
530 @discussion Set the initialization vector for encryption.
531
532 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
533
534 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for use as the IV.
535
536 In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number generator (e.g. @p ccrng).
537
538 @warning This function may not be used after initializing the cipher via @p ccgcm_init_with_iv. Nonzero is returned in the event of an improper call sequence.
539 */
540 CC_INLINE int ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
541 size_t iv_nbytes, const void *iv)
542 {
543 return mode->set_iv(ctx, iv_nbytes, iv);
544 }
545
546 /*!
547 @function ccgcm_set_iv_legacy
548 @abstract Set the IV for encryption.
549
550 @param mode Descriptor for the mode
551 @param ctx Context for this instance
552 @param iv_nbytes Length of the IV in bytes
553 @param iv Initialization vector
554
555 @result 0 iff successful.
556
557 @discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.
558
559 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
560
561 @warning Do not use this function in new applications.
562 */
563 int ccgcm_set_iv_legacy(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
564 size_t iv_nbytes, const void *iv);
565
566 /*!
567 @function ccgcm_inc_iv
568 @abstract Increment the IV for another encryption.
569
570 @param mode Descriptor for the mode
571 @param ctx Context for this instance
572 @param iv Updated initialization vector
573
574 @result 0 iff successful.
575
576 @discussion Updates the IV internally for another encryption.
577
578 Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain protocols (e.g. TLS). The counter component is interpreted as a big-endian, unsigned value and incremented in place.
579
580 The updated IV is copied to @p iv. This is to support protocols that require part of the IV to be specified explicitly in each packet (e.g. TLS).
581
582 @warning This function may be used only after initializing the cipher via @p ccgcm_init_with_iv.
583 */
584 int ccgcm_inc_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, void *iv);
585
586
587 /*!
588 @function ccgcm_aad
589 @abstract Authenticate additional data.
590
591 @param mode Descriptor for the mode
592 @param ctx Context for this instance
593 @param nbytes Length of the additional data in bytes
594 @param additional_data Additional data to authenticate
595
596 @result 0 iff successful.
597
598 @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
599
600 This function may be called zero or more times.
601 */
602 CC_INLINE int ccgcm_aad(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
603 size_t nbytes, const void *additional_data)
604 {
605 return mode->gmac(ctx, nbytes, additional_data);
606 }
607
608 /*!
609 @function ccgcm_gmac
610
611 @discussion See @p ccgcm_aad.
612 */
613 CC_INLINE int ccgcm_gmac(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
614 size_t nbytes, const void *in)
615 {
616 return mode->gmac(ctx, nbytes, in);
617 }
618
619 /*!
620 @function ccgcm_update
621 @abstract Encrypt or decrypt data.
622
623 @param mode Descriptor for the mode
624 @param ctx Context for this instance
625 @param nbytes Length of the data in bytes
626 @param in Input plaintext or ciphertext
627 @param out Output ciphertext or plaintext
628
629 @result 0 iff successful.
630
631 @discussion In-place processing is supported.
632
633 This function may be called zero or more times.
634 */
635 CC_INLINE int ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
636 size_t nbytes, const void *in, void *out)
637 {
638 return mode->gcm(ctx, nbytes, in, out);
639 }
640
641 /*!
642 @function ccgcm_finalize
643 @abstract Finish processing and authenticate.
644
645 @param mode Descriptor for the mode
646 @param ctx Context for this instance
647 @param tag_nbytes Length of the tag in bytes
648 @param tag Authentication tag
649
650 @result 0 iff successful.
651
652 @discussion Finish processing a packet and generate the authentication tag.
653
654 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
655
656 On decryption, @p tag is primarily an input parameter. The caller should provide the authentication tag generated during encryption. The function will return nonzero if the input tag does not match the generated tag.
657
658 @warning To support legacy applications, @p tag is also an output parameter during decryption. The generated tag is written to @p tag. Legacy callers may choose to compare this to the tag generated during encryption. Do not follow this usage pattern in new applications.
659 */
660 CC_INLINE int ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
661 size_t tag_nbytes, void *tag)
662 {
663 return mode->finalize(ctx, tag_nbytes, tag);
664 }
665
666 /*!
667 @function ccgcm_reset
668 @abstract Reset the context for another encryption.
669
670 @param mode Descriptor for the mode
671 @param ctx Context for this instance
672
673 @result 0 iff successful.
674
675 @discussion Refer to @p ccgcm_init for correct usage.
676 */
677 CC_INLINE int ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
678 {
679 return mode->reset(ctx);
680 }
681
682
683 /*!
684 @function ccgcm_one_shot
685 @abstract Encrypt or decrypt with GCM.
686
687 @param mode Descriptor for the mode
688 @param key_nbytes Length of the key in bytes
689 @param key Key for the underlying blockcipher (AES)
690 @param iv_nbytes Length of the IV in bytes
691 @param iv Initialization vector
692 @param adata_nbytes Length of the additional data in bytes
693 @param adata Additional data to authenticate
694 @param nbytes Length of the data in bytes
695 @param in Input plaintext or ciphertext
696 @param out Output ciphertext or plaintext
697 @param tag_nbytes Length of the tag in bytes
698 @param tag Authentication tag
699
700 @result 0 iff successful.
701
702 @discussion Perform GCM encryption or decryption.
703
704 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
705
706 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for use as the IV.
707
708 In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number generator (e.g. @p ccrng).
709
710 In-place processing is supported.
711
712 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
713
714 On decryption, @p tag is primarily an input parameter. The caller should provide the authentication tag generated during encryption. The function will return nonzero if the input tag does not match the generated tag.
715
716 @warning To support legacy applications, @p tag is also an output parameter during decryption. The generated tag is written to @p tag. Legacy callers may choose to compare this to the tag generated during encryption. Do not follow this usage pattern in new applications.
717 */
718 int ccgcm_one_shot(const struct ccmode_gcm *mode,
719 size_t key_nbytes, const void *key,
720 size_t iv_nbytes, const void *iv,
721 size_t adata_nbytes, const void *adata,
722 size_t nbytes, const void *in, void *out,
723 size_t tag_nbytes, void *tag);
724
725
726 /*!
727 @function ccgcm_one_shot_legacy
728 @abstract Encrypt or decrypt with GCM.
729
730 @param mode Descriptor for the mode
731 @param key_nbytes Length of the key in bytes
732 @param key Key for the underlying blockcipher (AES)
733 @param iv_nbytes Length of the IV in bytes
734 @param iv Initialization vector
735 @param adata_nbytes Length of the additional data in bytes
736 @param adata Additional data to authenticate
737 @param nbytes Length of the data in bytes
738 @param in Input plaintext or ciphertext
739 @param out Output ciphertext or plaintext
740 @param tag_nbytes Length of the tag in bytes
741 @param tag Authentication tag
742
743 @result 0 iff successful.
744
745 @discussion Identical to @p ccgcm_one_shot except that it allows zero-length IVs.
746
747 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
748
749 @warning Do not use this function in new applications.
750 */
751 int ccgcm_one_shot_legacy(const struct ccmode_gcm *mode,
752 size_t key_nbytes, const void *key,
753 size_t iv_nbytes, const void *iv,
754 size_t adata_nbytes, const void *adata,
755 size_t nbytes, const void *in, void *out,
756 size_t tag_nbytes, void *tag);
757
758
759 /* CCM */
760
761 #define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
762 #define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
763
764 /* Declare a ccm nonce named _name_. Pass the mode->nonce_ctx_size for _size_. */
765 #define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl(ccccm_nonce, _size_, _name_)
766 #define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
767
768
769 CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
770 {
771 return mode->size;
772 }
773
774 CC_INLINE size_t ccccm_block_size(const struct ccmode_ccm *mode)
775 {
776 return mode->block_size;
777 }
778
779 CC_INLINE int ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx,
780 size_t key_len, const void *key)
781 {
782 return mode->init(mode, ctx, key_len, key);
783 }
784
785 CC_INLINE int ccccm_set_iv(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
786 size_t nonce_len, const void *nonce,
787 size_t mac_size, size_t auth_len, size_t data_len)
788 {
789 return mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
790 }
791
792 CC_INLINE int ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
793 size_t nbytes, const void *in)
794 {
795 return mode->cbcmac(ctx, nonce_ctx, nbytes, in);
796 }
797
798 CC_INLINE int ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
799 size_t nbytes, const void *in, void *out)
800 {
801 return mode->ccm(ctx, nonce_ctx, nbytes, in, out);
802 }
803
804 CC_INLINE int ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
805 void *mac)
806 {
807 return mode->finalize(ctx, nonce_ctx, mac);
808 }
809
810 CC_INLINE int ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
811 {
812 return mode->reset(ctx, nonce_ctx);
813 }
814
815
816 CC_INLINE int ccccm_one_shot(const struct ccmode_ccm *mode,
817 size_t key_len, const void *key,
818 unsigned nonce_len, const void *nonce,
819 size_t nbytes, const void *in, void *out,
820 unsigned adata_len, const void* adata,
821 unsigned mac_size, void *mac)
822 {
823 int rc=0;
824 ccccm_ctx_decl(mode->size, ctx);
825 ccccm_nonce_decl(mode->nonce_size, nonce_ctx);
826 rc = mode->init(mode, ctx, key_len, key);
827 if(rc==0) rc=mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
828 if(rc==0) rc=mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
829 if(rc==0) rc=mode->ccm(ctx, nonce_ctx, nbytes, in, out);
830 if(rc==0) rc=mode->finalize(ctx, nonce_ctx, mac);
831 ccccm_ctx_clear(mode->size, ctx);
832 ccccm_nonce_clear(mode->size, nonce_ctx);
833
834 return rc;
835 }
836
837
838 /* OMAC mode. */
839
840
841 /* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
842 for _size_. */
843 #define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
844 #define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
845
846 CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
847 {
848 return mode->size;
849 }
850
851 CC_INLINE size_t ccomac_block_size(const struct ccmode_omac *mode)
852 {
853 return mode->block_size;
854 }
855
856 CC_INLINE int ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx,
857 size_t tweak_len, size_t key_len, const void *key)
858 {
859 return mode->init(mode, ctx, tweak_len, key_len, key);
860 }
861
862 CC_INLINE int ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx,
863 size_t nblocks, const void *tweak, const void *in, void *out)
864 {
865 return mode->omac(ctx, nblocks, tweak, in, out);
866 }
867
868 CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
869 size_t tweak_len, size_t key_len, const void *key,
870 const void *tweak, size_t nblocks, const void *in, void *out)
871 {
872 int rc;
873 ccomac_ctx_decl(mode->size, ctx);
874 rc = mode->init(mode, ctx, tweak_len, key_len, key);
875 if (rc == 0) rc = mode->omac(ctx, nblocks, tweak, in, out);
876 ccomac_ctx_clear(mode->size, ctx);
877 return rc;
878 }
879
880
881 #endif /* _CORECRYPTO_CCMODE_H_ */