]>
git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccmode.h
1 /* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
3 * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
4 * is contained in the License.txt file distributed with corecrypto) and only to
5 * people who accept that license. IMPORTANT: Any license rights granted to you by
6 * Apple Inc. (if any) are limited to internal use within your organization only on
7 * devices and computers you own or control, for the sole purpose of verifying the
8 * security characteristics and correct functioning of the Apple Software. You may
9 * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
12 #ifndef _CORECRYPTO_CCMODE_H_
13 #define _CORECRYPTO_CCMODE_H_
15 #include <corecrypto/cc.h>
16 #include <corecrypto/ccmode_impl.h>
17 #include <corecrypto/ccmode_siv.h>
18 #include <corecrypto/ccmode_siv_hmac.h>
22 /* Declare a ecb key named _name_. Pass the size field of a struct ccmode_ecb
24 #define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl(ccecb_ctx, _size_, _name_)
25 #define ccecb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
27 CC_INLINE
size_t ccecb_context_size(const struct ccmode_ecb
*mode
)
32 CC_INLINE
size_t ccecb_block_size(const struct ccmode_ecb
*mode
)
34 return mode
->block_size
;
37 CC_INLINE
int ccecb_init(const struct ccmode_ecb
*mode
, ccecb_ctx
*ctx
, size_t key_len
, const void *key
)
39 return mode
->init(mode
, ctx
, key_len
, key
);
42 CC_INLINE
int ccecb_update(const struct ccmode_ecb
*mode
, const ccecb_ctx
*ctx
, size_t nblocks
, const void *in
, void *out
)
44 return mode
->ecb(ctx
, nblocks
, in
, out
);
48 ccecb_one_shot(const struct ccmode_ecb
*mode
, size_t key_len
, const void *key
, size_t nblocks
, const void *in
, void *out
)
51 ccecb_ctx_decl(mode
->size
, ctx
);
52 rc
= mode
->init(mode
, ctx
, key_len
, key
);
54 rc
= mode
->ecb(ctx
, nblocks
, in
, out
);
56 ccecb_ctx_clear(mode
->size
, ctx
);
62 #define __CC_HAS_FIX_FOR_11468135__ 1
64 /* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
66 #define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
67 #define cccbc_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
69 /* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
70 struct ccmode_cbc for _size_. */
71 #define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
72 #define cccbc_iv_clear(_size_, _name_) cc_clear(_size_, _name_)
74 /* Actual symmetric algorithm implementation can provide you one of these.
76 Alternatively you can create a ccmode_cbc instance from any ccmode_ecb
77 cipher. To do so, statically initialize a struct ccmode_cbc using the
78 CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros.
79 Alternatively you can dynamically initialize a struct ccmode_cbc
80 ccmode_factory_cbc_decrypt() or ccmode_factory_cbc_encrypt(). */
82 CC_INLINE
size_t cccbc_context_size(const struct ccmode_cbc
*mode
)
87 CC_INLINE
size_t cccbc_block_size(const struct ccmode_cbc
*mode
)
89 return mode
->block_size
;
92 CC_INLINE
int cccbc_init(const struct ccmode_cbc
*mode
, cccbc_ctx
*ctx
, size_t key_len
, const void *key
)
94 return mode
->init(mode
, ctx
, key_len
, key
);
97 CC_INLINE
int cccbc_set_iv(const struct ccmode_cbc
*mode
, cccbc_iv
*iv_ctx
, const void *iv
)
100 cc_copy(mode
->block_size
, iv_ctx
, iv
);
102 cc_clear(mode
->block_size
, iv_ctx
);
107 CC_INLINE
int cccbc_update(const struct ccmode_cbc
*mode
, cccbc_ctx
*ctx
, cccbc_iv
*iv
, size_t nblocks
, const void *in
, void *out
)
109 return mode
->cbc(ctx
, iv
, nblocks
, in
, out
);
112 int cccbc_one_shot(const struct ccmode_cbc
*mode
,
122 /* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
124 #define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
125 #define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
127 CC_INLINE
size_t cccfb_context_size(const struct ccmode_cfb
*mode
)
132 CC_INLINE
size_t cccfb_block_size(const struct ccmode_cfb
*mode
)
134 return mode
->block_size
;
137 CC_INLINE
int cccfb_init(const struct ccmode_cfb
*mode
, cccfb_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
139 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
142 CC_INLINE
int cccfb_update(const struct ccmode_cfb
*mode
, cccfb_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
144 return mode
->cfb(ctx
, nbytes
, in
, out
);
147 CC_INLINE
int cccfb_one_shot(const struct ccmode_cfb
*mode
,
156 cccfb_ctx_decl(mode
->size
, ctx
);
157 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
159 rc
= mode
->cfb(ctx
, nbytes
, in
, out
);
161 cccfb_ctx_clear(mode
->size
, ctx
);
167 /* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
169 #define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
170 #define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
172 CC_INLINE
size_t cccfb8_context_size(const struct ccmode_cfb8
*mode
)
177 CC_INLINE
size_t cccfb8_block_size(const struct ccmode_cfb8
*mode
)
179 return mode
->block_size
;
182 CC_INLINE
int cccfb8_init(const struct ccmode_cfb8
*mode
, cccfb8_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
184 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
187 CC_INLINE
int cccfb8_update(const struct ccmode_cfb8
*mode
, cccfb8_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
189 return mode
->cfb8(ctx
, nbytes
, in
, out
);
192 CC_INLINE
int cccfb8_one_shot(const struct ccmode_cfb8
*mode
,
201 cccfb8_ctx_decl(mode
->size
, ctx
);
202 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
204 rc
= mode
->cfb8(ctx
, nbytes
, in
, out
);
206 cccfb8_ctx_clear(mode
->size
, ctx
);
212 /* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
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_)
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. */
221 CC_INLINE
size_t ccctr_context_size(const struct ccmode_ctr
*mode
)
226 CC_INLINE
size_t ccctr_block_size(const struct ccmode_ctr
*mode
)
228 return mode
->block_size
;
231 CC_INLINE
int ccctr_init(const struct ccmode_ctr
*mode
, ccctr_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
233 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
236 CC_INLINE
int ccctr_update(const struct ccmode_ctr
*mode
, ccctr_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
238 return mode
->ctr(ctx
, nbytes
, in
, out
);
241 CC_INLINE
int ccctr_one_shot(const struct ccmode_ctr
*mode
,
250 ccctr_ctx_decl(mode
->size
, ctx
);
251 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
253 rc
= mode
->ctr(ctx
, nbytes
, in
, out
);
255 ccctr_ctx_clear(mode
->size
, ctx
);
261 /* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
263 #define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
264 #define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
266 CC_INLINE
size_t ccofb_context_size(const struct ccmode_ofb
*mode
)
271 CC_INLINE
size_t ccofb_block_size(const struct ccmode_ofb
*mode
)
273 return mode
->block_size
;
276 CC_INLINE
int ccofb_init(const struct ccmode_ofb
*mode
, ccofb_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
278 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
281 CC_INLINE
int ccofb_update(const struct ccmode_ofb
*mode
, ccofb_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
283 return mode
->ofb(ctx
, nbytes
, in
, out
);
286 CC_INLINE
int ccofb_one_shot(const struct ccmode_ofb
*mode
,
295 ccofb_ctx_decl(mode
->size
, ctx
);
296 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
298 rc
= mode
->ofb(ctx
, nbytes
, in
, out
);
300 ccofb_ctx_clear(mode
->size
, ctx
);
306 /* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
308 #define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
309 #define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
311 /* Declare a xts tweak named _name_. Pass the tweak_size field of a
312 struct ccmode_xts for _size_. */
313 #define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
314 #define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
316 /* Actual symmetric algorithm implementation can provide you one of these.
318 Alternatively you can create a ccmode_xts instance from any ccmode_ecb
319 cipher. To do so, statically initialize a struct ccmode_xts using the
320 CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
321 you can dynamically initialize a struct ccmode_xts
322 ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
324 /* NOTE that xts mode does not do cts padding. It's really an xex mode.
325 If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
326 functions. Also note that xts only works for ecb modes with a block_size
329 CC_INLINE
size_t ccxts_context_size(const struct ccmode_xts
*mode
)
334 CC_INLINE
size_t ccxts_block_size(const struct ccmode_xts
*mode
)
336 return mode
->block_size
;
341 @abstract Initialize an XTS context.
343 @param mode Descriptor for the mode
344 @param ctx Context for this instance
345 @param key_nbytes Length of the key arguments in bytes
346 @param data_key Key for data encryption
347 @param tweak_key Key for tweak generation
349 @result 0 iff successful.
351 @discussion For security reasons, the two keys must be different.
354 ccxts_init(const struct ccmode_xts
*mode
, ccxts_ctx
*ctx
, size_t key_nbytes
, const void *data_key
, const void *tweak_key
)
356 return mode
->init(mode
, ctx
, key_nbytes
, data_key
, tweak_key
);
360 @function ccxts_set_tweak
361 @abstract Initialize the tweak for a sector.
363 @param mode Descriptor for the mode
364 @param ctx Context for this instance
365 @param tweak Context for the tweak for this sector
366 @param iv Data used to generate the tweak
368 @discussion The IV must be exactly one block in length.
370 CC_INLINE
int ccxts_set_tweak(const struct ccmode_xts
*mode
, ccxts_ctx
*ctx
, ccxts_tweak
*tweak
, const void *iv
)
372 return mode
->set_tweak(ctx
, tweak
, iv
);
376 @function ccxts_update
377 @abstract Encrypt or decrypt data.
379 @param mode Descriptor for the mode
380 @param ctx Context for an instance
381 @param tweak Context for the tweak for this sector
382 @param nblocks Length of the data in blocks
384 @param out Output buffer
386 @result The updated internal buffer of the tweak context. May be ignored.
389 ccxts_update(const struct ccmode_xts
*mode
, ccxts_ctx
*ctx
, ccxts_tweak
*tweak
, size_t nblocks
, const void *in
, void *out
)
391 return mode
->xts(ctx
, tweak
, nblocks
, in
, out
);
395 @function ccxts_one_shot
396 @abstract Encrypt or decrypt data in XTS mode.
398 @param mode Descriptor for the mode
399 @param key_nbytes Length of the key arguments in bytes
400 @param data_key Key for data encryption
401 @param tweak_key Key for tweak generation
402 @param iv Data used to generate the tweak
403 @param nblocks Length of the data in blocks
405 @param out Output buffer
407 @result 0 iff successful.
409 @discussion For security reasons, the two keys must be different.
411 int ccxts_one_shot(const struct ccmode_xts
*mode
,
413 const void *data_key
,
414 const void *tweak_key
,
420 /* Authenticated cipher modes. */
424 /* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
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_)
429 #define CCGCM_IV_NBYTES 12
430 #define CCGCM_BLOCK_NBYTES 16
432 /* (2^32 - 2) blocks */
433 /* (2^36 - 32) bytes */
434 /* (2^39 - 256) bits */
435 /* Exceeding this figure breaks confidentiality and authenticity. */
436 #define CCGCM_TEXT_MAX_NBYTES ((1ULL << 36) - 32ULL)
438 CC_INLINE
size_t ccgcm_context_size(const struct ccmode_gcm
*mode
)
443 CC_INLINE
size_t ccgcm_block_size(const struct ccmode_gcm
*mode
)
445 return mode
->block_size
;
450 @abstract Initialize a GCM context.
452 @param mode Descriptor for the mode
453 @param ctx Context for this instance
454 @param key_nbytes Length of the key in bytes
455 @param key Key for the underlying blockcipher (AES)
457 @result 0 iff successful.
459 @discussion The correct sequence of calls is:
461 @code ccgcm_init(...)
463 ccgcm_aad(...) (may be called zero or more times)
464 ccgcm_update(...) (may be called zero or more times)
467 To reuse the context for additional encryptions, follow this sequence:
469 @code ccgcm_reset(...)
471 ccgcm_aad(...) (may be called zero or more times)
472 ccgcm_update(...) (may be called zero or more times)
475 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
477 @warning It is not permitted to call @p ccgcm_inc_iv after initializing the cipher via the @p ccgcm_init interface. Nonzero is
478 returned in the event of an improper call sequence.
480 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
482 CC_INLINE
int ccgcm_init(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t key_nbytes
, const void *key
)
484 return mode
->init(mode
, ctx
, key_nbytes
, key
);
488 @function ccgcm_init_with_iv
489 @abstract Initialize a GCM context to manage IVs internally.
491 @param mode Descriptor for the mode
492 @param ctx Context for this instance
493 @param key_nbytes Length of the key in bytes
494 @param key Key for the underlying blockcipher (AES)
495 @param iv IV for the first encryption
497 @result 0 iff successful.
499 @discussion The correct sequence of calls is:
501 @code ccgcm_init_with_iv(...)
502 ccgcm_aad(...) (may be called zero or more times)
503 ccgcm_update(...) (may be called zero or more times)
506 To reuse the context for additional encryptions, follow this sequence:
508 @code ccgcm_reset(...)
510 ccgcm_aad(...) (may be called zero or more times)
511 ccgcm_update(...) (may be called zero or more times)
514 The IV must be exactly 12 bytes in length.
516 Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain
517 protocols (e.g. TLS). In the call to @p ccgcm_inc_iv, the counter component will be interpreted as a big-endian, unsigned value
518 and incremented in place.
520 @warning It is not permitted to call @p ccgcm_set_iv after initializing the cipher via the @p ccgcm_init_with_iv interface.
521 Nonzero is returned in the event of an improper call sequence.
523 @warning The security of GCM depends on the uniqueness of key-IV pairs. To avoid key-IV repetition, callers should not initialize
524 multiple contexts with the same key material via the @p ccgcm_init_with_iv interface.
526 int ccgcm_init_with_iv(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t key_nbytes
, const void *key
, const void *iv
);
529 @function ccgcm_set_iv
530 @abstract Set the IV for encryption.
532 @param mode Descriptor for the mode
533 @param ctx Context for this instance
534 @param iv_nbytes Length of the IV in bytes
535 @param iv Initialization vector
537 @result 0 iff successful.
539 @discussion Set the initialization vector for encryption.
541 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
543 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
546 In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number
547 generator (e.g. @p ccrng).
549 @warning This function may not be used after initializing the cipher via @p ccgcm_init_with_iv. Nonzero is returned in the event
550 of an improper call sequence.
552 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
554 CC_INLINE
int ccgcm_set_iv(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t iv_nbytes
, const void *iv
)
556 return mode
->set_iv(ctx
, iv_nbytes
, iv
);
560 @function ccgcm_set_iv_legacy
561 @abstract Set the IV for encryption.
563 @param mode Descriptor for the mode
564 @param ctx Context for this instance
565 @param iv_nbytes Length of the IV in bytes
566 @param iv Initialization vector
568 @result 0 iff successful.
570 @discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.
572 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
574 @warning Do not use this function in new applications.
576 int ccgcm_set_iv_legacy(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t iv_nbytes
, const void *iv
);
579 @function ccgcm_inc_iv
580 @abstract Increment the IV for another encryption.
582 @param mode Descriptor for the mode
583 @param ctx Context for this instance
584 @param iv Updated initialization vector
586 @result 0 iff successful.
588 @discussion Updates the IV internally for another encryption.
590 Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain
591 protocols (e.g. TLS). The counter component is interpreted as a big-endian, unsigned value and incremented in place.
593 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
596 @warning This function may be used only after initializing the cipher via @p ccgcm_init_with_iv.
598 int ccgcm_inc_iv(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, void *iv
);
602 @abstract Authenticate additional data.
604 @param mode Descriptor for the mode
605 @param ctx Context for this instance
606 @param nbytes Length of the additional data in bytes
607 @param additional_data Additional data to authenticate
609 @result 0 iff successful.
611 @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
613 This function may be called zero or more times.
615 CC_INLINE
int ccgcm_aad(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t nbytes
, const void *additional_data
)
617 return mode
->gmac(ctx
, nbytes
, additional_data
);
623 @discussion ccgcm_gmac is deprecated. Use the drop-in replacement 'ccgcm_aad' instead.
625 CC_INLINE
int ccgcm_gmac (const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t nbytes
, const void *in
)
626 cc_deprecate_with_replacement("ccgcm_aad", 13.0, 10.15, 13.0, 6.0, 4.0)
628 return mode
->gmac(ctx
, nbytes
, in
);
632 @function ccgcm_update
633 @abstract Encrypt or decrypt data.
635 @param mode Descriptor for the mode
636 @param ctx Context for this instance
637 @param nbytes Length of the data in bytes
638 @param in Input plaintext or ciphertext
639 @param out Output ciphertext or plaintext
641 @result 0 iff successful.
643 @discussion In-place processing is supported.
645 This function may be called zero or more times.
647 CC_INLINE
int ccgcm_update(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
649 return mode
->gcm(ctx
, nbytes
, in
, out
);
653 @function ccgcm_finalize
654 @abstract Finish processing and authenticate.
656 @param mode Descriptor for the mode
657 @param ctx Context for this instance
658 @param tag_nbytes Length of the tag in bytes
659 @param tag Authentication tag
661 @result 0 iff successful.
663 @discussion Finish processing a packet and generate the authentication tag.
665 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
667 On decryption, @p tag is both an input and an output parameter. Well-behaved callers should provide the authentication tag
668 generated during encryption. The function will return nonzero if the input tag does not match the generated tag. The generated
669 tag will be written into the @p tag buffer whether authentication succeeds or fails.
671 @warning The generated tag is written to @p tag to support legacy applications that perform authentication manually. Do not
672 follow this usage pattern in new applications. Rely on the function's error code to verify authenticity.
674 CC_INLINE
int ccgcm_finalize(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t tag_nbytes
, void *tag
)
676 return mode
->finalize(ctx
, tag_nbytes
, tag
);
680 @function ccgcm_reset
681 @abstract Reset the context for another encryption.
683 @param mode Descriptor for the mode
684 @param ctx Context for this instance
686 @result 0 iff successful.
688 @discussion Refer to @p ccgcm_init for correct usage.
690 CC_INLINE
int ccgcm_reset(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
)
692 return mode
->reset(ctx
);
696 @function ccgcm_one_shot
697 @abstract Encrypt or decrypt with GCM.
699 @param mode Descriptor for the mode
700 @param key_nbytes Length of the key in bytes
701 @param key Key for the underlying blockcipher (AES)
702 @param iv_nbytes Length of the IV in bytes
703 @param iv Initialization vector
704 @param adata_nbytes Length of the additional data in bytes
705 @param adata Additional data to authenticate
706 @param nbytes Length of the data in bytes
707 @param in Input plaintext or ciphertext
708 @param out Output ciphertext or plaintext
709 @param tag_nbytes Length of the tag in bytes
710 @param tag Authentication tag
712 @result 0 iff successful.
714 @discussion Perform GCM encryption or decryption.
716 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
718 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
721 In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number
722 generator (e.g. @p ccrng).
724 In-place processing is supported.
726 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
728 On decryption, @p tag is primarily an input parameter. The caller should provide the authentication tag generated during
729 encryption. The function will return nonzero if the input tag does not match the generated tag.
731 @warning To support legacy applications, @p tag is also an output parameter during decryption. The generated tag is written to @p
732 tag. Legacy callers may choose to compare this to the tag generated during encryption. Do not follow this usage pattern in new
735 int ccgcm_one_shot(const struct ccmode_gcm
*mode
,
749 @function ccgcm_one_shot_legacy
750 @abstract Encrypt or decrypt with GCM.
752 @param mode Descriptor for the mode
753 @param key_nbytes Length of the key in bytes
754 @param key Key for the underlying blockcipher (AES)
755 @param iv_nbytes Length of the IV in bytes
756 @param iv Initialization vector
757 @param adata_nbytes Length of the additional data in bytes
758 @param adata Additional data to authenticate
759 @param nbytes Length of the data in bytes
760 @param in Input plaintext or ciphertext
761 @param out Output ciphertext or plaintext
762 @param tag_nbytes Length of the tag in bytes
763 @param tag Authentication tag
765 @result 0 iff successful.
767 @discussion Identical to @p ccgcm_one_shot except that it allows zero-length IVs.
769 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
771 @warning Do not use this function in new applications.
773 int ccgcm_one_shot_legacy(const struct ccmode_gcm
*mode
,
788 #define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
789 #define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
791 /* Declare a ccm nonce named _name_. Pass the mode->nonce_ctx_size for _size_. */
792 #define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl(ccccm_nonce, _size_, _name_)
793 #define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
795 CC_INLINE
size_t ccccm_context_size(const struct ccmode_ccm
*mode
)
800 CC_INLINE
size_t ccccm_block_size(const struct ccmode_ccm
*mode
)
802 return mode
->block_size
;
805 CC_INLINE
int ccccm_init(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, size_t key_len
, const void *key
)
807 return mode
->init(mode
, ctx
, key_len
, key
);
810 CC_INLINE
int ccccm_set_iv(const struct ccmode_ccm
*mode
,
812 ccccm_nonce
*nonce_ctx
,
819 return mode
->set_iv(ctx
, nonce_ctx
, nonce_len
, nonce
, mac_size
, auth_len
, data_len
);
822 CC_INLINE
int ccccm_cbcmac(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
, size_t nbytes
, const void *in
)
824 return mode
->cbcmac(ctx
, nonce_ctx
, nbytes
, in
);
828 ccccm_update(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
, size_t nbytes
, const void *in
, void *out
)
830 return mode
->ccm(ctx
, nonce_ctx
, nbytes
, in
, out
);
833 CC_INLINE
int ccccm_finalize(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
, void *mac
)
835 return mode
->finalize(ctx
, nonce_ctx
, mac
);
838 CC_INLINE
int ccccm_reset(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
)
840 return mode
->reset(ctx
, nonce_ctx
);
843 CC_INLINE
int ccccm_one_shot(const struct ccmode_ccm
*mode
,
857 ccccm_ctx_decl(mode
->size
, ctx
);
858 ccccm_nonce_decl(mode
->nonce_size
, nonce_ctx
);
859 rc
= mode
->init(mode
, ctx
, key_len
, key
);
861 rc
= mode
->set_iv(ctx
, nonce_ctx
, nonce_len
, nonce
, mac_size
, adata_len
, nbytes
);
864 rc
= mode
->cbcmac(ctx
, nonce_ctx
, adata_len
, adata
);
867 rc
= mode
->ccm(ctx
, nonce_ctx
, nbytes
, in
, out
);
870 rc
= mode
->finalize(ctx
, nonce_ctx
, mac
);
872 ccccm_ctx_clear(mode
->size
, ctx
);
873 ccccm_nonce_clear(mode
->nonce_size
, nonce_ctx
);
880 /* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
882 #define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
883 #define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
885 CC_INLINE
size_t ccomac_context_size(const struct ccmode_omac
*mode
)
890 CC_INLINE
size_t ccomac_block_size(const struct ccmode_omac
*mode
)
892 return mode
->block_size
;
895 CC_INLINE
int ccomac_init(const struct ccmode_omac
*mode
, ccomac_ctx
*ctx
, size_t tweak_len
, size_t key_len
, const void *key
)
897 return mode
->init(mode
, ctx
, tweak_len
, key_len
, key
);
901 ccomac_update(const struct ccmode_omac
*mode
, ccomac_ctx
*ctx
, size_t nblocks
, const void *tweak
, const void *in
, void *out
)
903 return mode
->omac(ctx
, nblocks
, tweak
, in
, out
);
906 CC_INLINE
int ccomac_one_shot(const struct ccmode_omac
*mode
,
916 ccomac_ctx_decl(mode
->size
, ctx
);
917 rc
= mode
->init(mode
, ctx
, tweak_len
, key_len
, key
);
919 rc
= mode
->omac(ctx
, nblocks
, tweak
, in
, out
);
921 ccomac_ctx_clear(mode
->size
, ctx
);
925 #endif /* _CORECRYPTO_CCMODE_H_ */