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