]>
git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccmode.h
5 * Created on 12/07/2010
7 * Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
11 #ifndef _CORECRYPTO_CCMODE_H_
12 #define _CORECRYPTO_CCMODE_H_
14 #include <corecrypto/cc.h>
15 #include <corecrypto/ccmode_impl.h>
16 #include <corecrypto/ccmode_siv.h>
17 #include <corecrypto/ccmode_siv_hmac.h>
21 /* Declare a ecb key named _name_. Pass the size field of a struct ccmode_ecb
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_)
26 CC_INLINE
size_t ccecb_context_size(const struct ccmode_ecb
*mode
)
31 CC_INLINE
size_t ccecb_block_size(const struct ccmode_ecb
*mode
)
33 return mode
->block_size
;
36 CC_INLINE
int ccecb_init(const struct ccmode_ecb
*mode
, ccecb_ctx
*ctx
, size_t key_len
, const void *key
)
38 return mode
->init(mode
, ctx
, key_len
, key
);
41 CC_INLINE
int ccecb_update(const struct ccmode_ecb
*mode
, const ccecb_ctx
*ctx
, size_t nblocks
, const void *in
, void *out
)
43 return mode
->ecb(ctx
, nblocks
, in
, out
);
47 ccecb_one_shot(const struct ccmode_ecb
*mode
, size_t key_len
, const void *key
, size_t nblocks
, const void *in
, void *out
)
50 ccecb_ctx_decl(mode
->size
, ctx
);
51 rc
= mode
->init(mode
, ctx
, key_len
, key
);
53 rc
= mode
->ecb(ctx
, nblocks
, in
, out
);
55 ccecb_ctx_clear(mode
->size
, ctx
);
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.
65 #define __CC_HAS_FIX_FOR_11468135__ 1
67 /* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
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_)
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_)
77 /* Actual symmetric algorithm implementation can provide you one of these.
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(). */
85 CC_INLINE
size_t cccbc_context_size(const struct ccmode_cbc
*mode
)
90 CC_INLINE
size_t cccbc_block_size(const struct ccmode_cbc
*mode
)
92 return mode
->block_size
;
95 CC_INLINE
int cccbc_init(const struct ccmode_cbc
*mode
, cccbc_ctx
*ctx
, size_t key_len
, const void *key
)
97 return mode
->init(mode
, ctx
, key_len
, key
);
100 CC_INLINE
int cccbc_set_iv(const struct ccmode_cbc
*mode
, cccbc_iv
*iv_ctx
, const void *iv
)
103 cc_copy(mode
->block_size
, iv_ctx
, iv
);
105 cc_clear(mode
->block_size
, iv_ctx
);
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
)
112 return mode
->cbc(ctx
, iv
, nblocks
, in
, out
);
115 int cccbc_one_shot(const struct ccmode_cbc
*mode
,
125 /* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
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_)
130 CC_INLINE
size_t cccfb_context_size(const struct ccmode_cfb
*mode
)
135 CC_INLINE
size_t cccfb_block_size(const struct ccmode_cfb
*mode
)
137 return mode
->block_size
;
140 CC_INLINE
int cccfb_init(const struct ccmode_cfb
*mode
, cccfb_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
142 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
145 CC_INLINE
int cccfb_update(const struct ccmode_cfb
*mode
, cccfb_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
147 return mode
->cfb(ctx
, nbytes
, in
, out
);
150 CC_INLINE
int cccfb_one_shot(const struct ccmode_cfb
*mode
,
159 cccfb_ctx_decl(mode
->size
, ctx
);
160 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
162 rc
= mode
->cfb(ctx
, nbytes
, in
, out
);
164 cccfb_ctx_clear(mode
->size
, ctx
);
170 /* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
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_)
175 CC_INLINE
size_t cccfb8_context_size(const struct ccmode_cfb8
*mode
)
180 CC_INLINE
size_t cccfb8_block_size(const struct ccmode_cfb8
*mode
)
182 return mode
->block_size
;
185 CC_INLINE
int cccfb8_init(const struct ccmode_cfb8
*mode
, cccfb8_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
187 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
190 CC_INLINE
int cccfb8_update(const struct ccmode_cfb8
*mode
, cccfb8_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
192 return mode
->cfb8(ctx
, nbytes
, in
, out
);
195 CC_INLINE
int cccfb8_one_shot(const struct ccmode_cfb8
*mode
,
204 cccfb8_ctx_decl(mode
->size
, ctx
);
205 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
207 rc
= mode
->cfb8(ctx
, nbytes
, in
, out
);
209 cccfb8_ctx_clear(mode
->size
, ctx
);
215 /* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
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_)
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. */
224 CC_INLINE
size_t ccctr_context_size(const struct ccmode_ctr
*mode
)
229 CC_INLINE
size_t ccctr_block_size(const struct ccmode_ctr
*mode
)
231 return mode
->block_size
;
234 CC_INLINE
int ccctr_init(const struct ccmode_ctr
*mode
, ccctr_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
236 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
239 CC_INLINE
int ccctr_update(const struct ccmode_ctr
*mode
, ccctr_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
241 return mode
->ctr(ctx
, nbytes
, in
, out
);
244 CC_INLINE
int ccctr_one_shot(const struct ccmode_ctr
*mode
,
253 ccctr_ctx_decl(mode
->size
, ctx
);
254 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
256 rc
= mode
->ctr(ctx
, nbytes
, in
, out
);
258 ccctr_ctx_clear(mode
->size
, ctx
);
264 /* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
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_)
269 CC_INLINE
size_t ccofb_context_size(const struct ccmode_ofb
*mode
)
274 CC_INLINE
size_t ccofb_block_size(const struct ccmode_ofb
*mode
)
276 return mode
->block_size
;
279 CC_INLINE
int ccofb_init(const struct ccmode_ofb
*mode
, ccofb_ctx
*ctx
, size_t key_len
, const void *key
, const void *iv
)
281 return mode
->init(mode
, ctx
, key_len
, key
, iv
);
284 CC_INLINE
int ccofb_update(const struct ccmode_ofb
*mode
, ccofb_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
286 return mode
->ofb(ctx
, nbytes
, in
, out
);
289 CC_INLINE
int ccofb_one_shot(const struct ccmode_ofb
*mode
,
298 ccofb_ctx_decl(mode
->size
, ctx
);
299 rc
= mode
->init(mode
, ctx
, key_len
, key
, iv
);
301 rc
= mode
->ofb(ctx
, nbytes
, in
, out
);
303 ccofb_ctx_clear(mode
->size
, ctx
);
309 /* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
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_)
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_)
319 /* Actual symmetric algorithm implementation can provide you one of these.
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(). */
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
332 CC_INLINE
size_t ccxts_context_size(const struct ccmode_xts
*mode
)
337 CC_INLINE
size_t ccxts_block_size(const struct ccmode_xts
*mode
)
339 return mode
->block_size
;
344 @abstract Initialize an XTS context.
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
352 @result 0 iff successful.
354 @discussion For security reasons, the two keys must be different.
357 ccxts_init(const struct ccmode_xts
*mode
, ccxts_ctx
*ctx
, size_t key_nbytes
, const void *data_key
, const void *tweak_key
)
359 return mode
->init(mode
, ctx
, key_nbytes
, data_key
, tweak_key
);
363 @function ccxts_set_tweak
364 @abstract Initialize the tweak for a sector.
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
371 @discussion The IV must be exactly one block in length.
373 CC_INLINE
int ccxts_set_tweak(const struct ccmode_xts
*mode
, ccxts_ctx
*ctx
, ccxts_tweak
*tweak
, const void *iv
)
375 return mode
->set_tweak(ctx
, tweak
, iv
);
379 @function ccxts_update
380 @abstract Encrypt or decrypt data.
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
387 @param out Output buffer
389 @result The updated internal buffer of the tweak context. May be ignored.
392 ccxts_update(const struct ccmode_xts
*mode
, ccxts_ctx
*ctx
, ccxts_tweak
*tweak
, size_t nblocks
, const void *in
, void *out
)
394 return mode
->xts(ctx
, tweak
, nblocks
, in
, out
);
398 @function ccxts_one_shot
399 @abstract Encrypt or decrypt data in XTS mode.
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
408 @param out Output buffer
410 @result 0 iff successful.
412 @discussion For security reasons, the two keys must be different.
414 int ccxts_one_shot(const struct ccmode_xts
*mode
,
416 const void *data_key
,
417 const void *tweak_key
,
423 /* Authenticated cipher modes. */
427 /* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
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_)
432 #define CCGCM_IV_NBYTES 12
433 #define CCGCM_BLOCK_NBYTES 16
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)
441 CC_INLINE
size_t ccgcm_context_size(const struct ccmode_gcm
*mode
)
446 CC_INLINE
size_t ccgcm_block_size(const struct ccmode_gcm
*mode
)
448 return mode
->block_size
;
453 @abstract Initialize a GCM context.
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)
460 @result 0 iff successful.
462 @discussion The correct sequence of calls is:
464 @code ccgcm_init(...)
466 ccgcm_aad(...) (may be called zero or more times)
467 ccgcm_update(...) (may be called zero or more times)
470 To reuse the context for additional encryptions, follow this sequence:
472 @code ccgcm_reset(...)
474 ccgcm_aad(...) (may be called zero or more times)
475 ccgcm_update(...) (may be called zero or more times)
478 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
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.
483 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
485 CC_INLINE
int ccgcm_init(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t key_nbytes
, const void *key
)
487 return mode
->init(mode
, ctx
, key_nbytes
, key
);
491 @function ccgcm_init_with_iv
492 @abstract Initialize a GCM context to manage IVs internally.
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
500 @result 0 iff successful.
502 @discussion The correct sequence of calls is:
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)
509 To reuse the context for additional encryptions, follow this sequence:
511 @code ccgcm_reset(...)
513 ccgcm_aad(...) (may be called zero or more times)
514 ccgcm_update(...) (may be called zero or more times)
517 The IV must be exactly 12 bytes in length.
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.
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.
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.
529 int ccgcm_init_with_iv(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t key_nbytes
, const void *key
, const void *iv
);
532 @function ccgcm_set_iv
533 @abstract Set the IV for encryption.
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
540 @result 0 iff successful.
542 @discussion Set the initialization vector for encryption.
544 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
546 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
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).
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.
555 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
557 CC_INLINE
int ccgcm_set_iv(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t iv_nbytes
, const void *iv
)
559 return mode
->set_iv(ctx
, iv_nbytes
, iv
);
563 @function ccgcm_set_iv_legacy
564 @abstract Set the IV for encryption.
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
571 @result 0 iff successful.
573 @discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.
575 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
577 @warning Do not use this function in new applications.
579 int ccgcm_set_iv_legacy(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t iv_nbytes
, const void *iv
);
582 @function ccgcm_inc_iv
583 @abstract Increment the IV for another encryption.
585 @param mode Descriptor for the mode
586 @param ctx Context for this instance
587 @param iv Updated initialization vector
589 @result 0 iff successful.
591 @discussion Updates the IV internally for another encryption.
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.
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
599 @warning This function may be used only after initializing the cipher via @p ccgcm_init_with_iv.
601 int ccgcm_inc_iv(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, void *iv
);
605 @abstract Authenticate additional data.
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
612 @result 0 iff successful.
614 @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
616 This function may be called zero or more times.
618 CC_INLINE
int ccgcm_aad(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t nbytes
, const void *additional_data
)
620 return mode
->gmac(ctx
, nbytes
, additional_data
);
626 @discussion ccgcm_gmac is deprecated. Use the drop-in replacement 'ccgcm_aad' instead.
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)
631 return mode
->gmac(ctx
, nbytes
, in
);
635 @function ccgcm_update
636 @abstract Encrypt or decrypt data.
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
644 @result 0 iff successful.
646 @discussion In-place processing is supported.
648 This function may be called zero or more times.
650 CC_INLINE
int ccgcm_update(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t nbytes
, const void *in
, void *out
)
652 return mode
->gcm(ctx
, nbytes
, in
, out
);
656 @function ccgcm_finalize
657 @abstract Finish processing and authenticate.
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
664 @result 0 iff successful.
666 @discussion Finish processing a packet and generate the authentication tag.
668 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
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.
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.
677 CC_INLINE
int ccgcm_finalize(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
, size_t tag_nbytes
, void *tag
)
679 return mode
->finalize(ctx
, tag_nbytes
, tag
);
683 @function ccgcm_reset
684 @abstract Reset the context for another encryption.
686 @param mode Descriptor for the mode
687 @param ctx Context for this instance
689 @result 0 iff successful.
691 @discussion Refer to @p ccgcm_init for correct usage.
693 CC_INLINE
int ccgcm_reset(const struct ccmode_gcm
*mode
, ccgcm_ctx
*ctx
)
695 return mode
->reset(ctx
);
699 @function ccgcm_one_shot
700 @abstract Encrypt or decrypt with GCM.
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
715 @result 0 iff successful.
717 @discussion Perform GCM encryption or decryption.
719 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
721 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
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).
727 In-place processing is supported.
729 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
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.
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
738 int ccgcm_one_shot(const struct ccmode_gcm
*mode
,
752 @function ccgcm_one_shot_legacy
753 @abstract Encrypt or decrypt with GCM.
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
768 @result 0 iff successful.
770 @discussion Identical to @p ccgcm_one_shot except that it allows zero-length IVs.
772 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
774 @warning Do not use this function in new applications.
776 int ccgcm_one_shot_legacy(const struct ccmode_gcm
*mode
,
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_)
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_)
798 CC_INLINE
size_t ccccm_context_size(const struct ccmode_ccm
*mode
)
803 CC_INLINE
size_t ccccm_block_size(const struct ccmode_ccm
*mode
)
805 return mode
->block_size
;
808 CC_INLINE
int ccccm_init(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, size_t key_len
, const void *key
)
810 return mode
->init(mode
, ctx
, key_len
, key
);
813 CC_INLINE
int ccccm_set_iv(const struct ccmode_ccm
*mode
,
815 ccccm_nonce
*nonce_ctx
,
822 return mode
->set_iv(ctx
, nonce_ctx
, nonce_len
, nonce
, mac_size
, auth_len
, data_len
);
825 CC_INLINE
int ccccm_cbcmac(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
, size_t nbytes
, const void *in
)
827 return mode
->cbcmac(ctx
, nonce_ctx
, nbytes
, in
);
831 ccccm_update(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
, size_t nbytes
, const void *in
, void *out
)
833 return mode
->ccm(ctx
, nonce_ctx
, nbytes
, in
, out
);
836 CC_INLINE
int ccccm_finalize(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
, void *mac
)
838 return mode
->finalize(ctx
, nonce_ctx
, mac
);
841 CC_INLINE
int ccccm_reset(const struct ccmode_ccm
*mode
, ccccm_ctx
*ctx
, ccccm_nonce
*nonce_ctx
)
843 return mode
->reset(ctx
, nonce_ctx
);
846 CC_INLINE
int ccccm_one_shot(const struct ccmode_ccm
*mode
,
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
);
864 rc
= mode
->set_iv(ctx
, nonce_ctx
, nonce_len
, nonce
, mac_size
, adata_len
, nbytes
);
867 rc
= mode
->cbcmac(ctx
, nonce_ctx
, adata_len
, adata
);
870 rc
= mode
->ccm(ctx
, nonce_ctx
, nbytes
, in
, out
);
873 rc
= mode
->finalize(ctx
, nonce_ctx
, mac
);
875 ccccm_ctx_clear(mode
->size
, ctx
);
876 ccccm_nonce_clear(mode
->nonce_size
, nonce_ctx
);
883 /* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
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_)
888 CC_INLINE
size_t ccomac_context_size(const struct ccmode_omac
*mode
)
893 CC_INLINE
size_t ccomac_block_size(const struct ccmode_omac
*mode
)
895 return mode
->block_size
;
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
)
900 return mode
->init(mode
, ctx
, tweak_len
, key_len
, key
);
904 ccomac_update(const struct ccmode_omac
*mode
, ccomac_ctx
*ctx
, size_t nblocks
, const void *tweak
, const void *in
, void *out
)
906 return mode
->omac(ctx
, nblocks
, tweak
, in
, out
);
909 CC_INLINE
int ccomac_one_shot(const struct ccmode_omac
*mode
,
919 ccomac_ctx_decl(mode
->size
, ctx
);
920 rc
= mode
->init(mode
, ctx
, tweak_len
, key_len
, key
);
922 rc
= mode
->omac(ctx
, nblocks
, tweak
, in
, out
);
924 ccomac_ctx_clear(mode
->size
, ctx
);
928 #endif /* _CORECRYPTO_CCMODE_H_ */