]> git.saurik.com Git - apple/xnu.git/blame - EXTERNAL_HEADERS/corecrypto/ccmode.h
xnu-7195.101.1.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccmode.h
CommitLineData
f427ee49 1/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
316670eb 2 *
f427ee49
A
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.
316670eb
A
10 */
11
12#ifndef _CORECRYPTO_CCMODE_H_
13#define _CORECRYPTO_CCMODE_H_
14
15#include <corecrypto/cc.h>
16#include <corecrypto/ccmode_impl.h>
39037602 17#include <corecrypto/ccmode_siv.h>
cb323159 18#include <corecrypto/ccmode_siv_hmac.h>
316670eb
A
19
20/* ECB mode. */
21
22/* Declare a ecb key named _name_. Pass the size field of a struct ccmode_ecb
23 for _size_. */
24#define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl(ccecb_ctx, _size_, _name_)
3e170ce0 25#define ccecb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
26
27CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
28{
29 return mode->size;
30}
31
39037602 32CC_INLINE size_t ccecb_block_size(const struct ccmode_ecb *mode)
316670eb 33{
cb323159 34 return mode->block_size;
316670eb
A
35}
36
cb323159 37CC_INLINE int ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx, size_t key_len, const void *key)
316670eb 38{
d190cdc3 39 return mode->init(mode, ctx, key_len, key);
316670eb
A
40}
41
cb323159 42CC_INLINE int ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx, size_t nblocks, const void *in, void *out)
316670eb 43{
cb323159 44 return mode->ecb(ctx, nblocks, in, out);
316670eb
A
45}
46
cb323159
A
47CC_INLINE int
48ccecb_one_shot(const struct ccmode_ecb *mode, size_t key_len, const void *key, size_t nblocks, const void *in, void *out)
316670eb 49{
d190cdc3 50 int rc;
cb323159
A
51 ccecb_ctx_decl(mode->size, ctx);
52 rc = mode->init(mode, ctx, key_len, key);
53 if (rc == 0) {
54 rc = mode->ecb(ctx, nblocks, in, out);
55 }
56 ccecb_ctx_clear(mode->size, ctx);
d190cdc3 57 return rc;
316670eb
A
58}
59
60/* CBC mode. */
61
316670eb
A
62#define __CC_HAS_FIX_FOR_11468135__ 1
63
64/* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
65 for _size_. */
66#define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
3e170ce0 67#define cccbc_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb 68
fe8ab488
A
69/* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
70 struct ccmode_cbc for _size_. */
316670eb 71#define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
3e170ce0 72#define cccbc_iv_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
73
74/* Actual symmetric algorithm implementation can provide you one of these.
75
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
fe8ab488
A
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(). */
316670eb
A
81
82CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
83{
84 return mode->size;
85}
86
39037602 87CC_INLINE size_t cccbc_block_size(const struct ccmode_cbc *mode)
316670eb 88{
cb323159 89 return mode->block_size;
316670eb
A
90}
91
cb323159 92CC_INLINE int cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx, size_t key_len, const void *key)
316670eb 93{
d190cdc3 94 return mode->init(mode, ctx, key_len, key);
316670eb
A
95}
96
cb323159 97CC_INLINE int cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx, const void *iv)
316670eb 98{
cb323159 99 if (iv) {
316670eb 100 cc_copy(mode->block_size, iv_ctx, iv);
cb323159
A
101 } else {
102 cc_clear(mode->block_size, iv_ctx);
103 }
d190cdc3 104 return 0;
316670eb
A
105}
106
cb323159 107CC_INLINE int cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, const void *in, void *out)
316670eb 108{
cb323159 109 return mode->cbc(ctx, iv, nblocks, in, out);
316670eb
A
110}
111
5ba3f43e 112int cccbc_one_shot(const struct ccmode_cbc *mode,
cb323159
A
113 size_t key_len,
114 const void *key,
115 const void *iv,
116 size_t nblocks,
117 const void *in,
118 void *out);
316670eb
A
119
120/* CFB mode. */
121
122/* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
fe8ab488 123 for _size_. */
316670eb 124#define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
3e170ce0 125#define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
126
127CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
128{
129 return mode->size;
130}
131
39037602 132CC_INLINE size_t cccfb_block_size(const struct ccmode_cfb *mode)
316670eb 133{
cb323159 134 return mode->block_size;
316670eb
A
135}
136
cb323159 137CC_INLINE int cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 138{
d190cdc3 139 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
140}
141
cb323159 142CC_INLINE int cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 143{
cb323159 144 return mode->cfb(ctx, nbytes, in, out);
316670eb
A
145}
146
d190cdc3 147CC_INLINE int cccfb_one_shot(const struct ccmode_cfb *mode,
cb323159
A
148 size_t key_len,
149 const void *key,
150 const void *iv,
151 size_t nbytes,
152 const void *in,
153 void *out)
316670eb 154{
d190cdc3 155 int rc;
cb323159
A
156 cccfb_ctx_decl(mode->size, ctx);
157 rc = mode->init(mode, ctx, key_len, key, iv);
158 if (rc == 0) {
159 rc = mode->cfb(ctx, nbytes, in, out);
160 }
161 cccfb_ctx_clear(mode->size, ctx);
d190cdc3 162 return rc;
316670eb
A
163}
164
165/* CFB8 mode. */
166
167/* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
168 for _size_. */
169#define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
3e170ce0 170#define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
171
172CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
173{
174 return mode->size;
175}
176
39037602 177CC_INLINE size_t cccfb8_block_size(const struct ccmode_cfb8 *mode)
316670eb 178{
cb323159 179 return mode->block_size;
316670eb
A
180}
181
cb323159 182CC_INLINE int cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 183{
d190cdc3 184 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
185}
186
cb323159 187CC_INLINE int cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 188{
cb323159 189 return mode->cfb8(ctx, nbytes, in, out);
316670eb
A
190}
191
d190cdc3 192CC_INLINE int cccfb8_one_shot(const struct ccmode_cfb8 *mode,
cb323159
A
193 size_t key_len,
194 const void *key,
195 const void *iv,
196 size_t nbytes,
197 const void *in,
198 void *out)
316670eb 199{
d190cdc3 200 int rc;
cb323159
A
201 cccfb8_ctx_decl(mode->size, ctx);
202 rc = mode->init(mode, ctx, key_len, key, iv);
203 if (rc == 0) {
204 rc = mode->cfb8(ctx, nbytes, in, out);
205 }
206 cccfb8_ctx_clear(mode->size, ctx);
d190cdc3 207 return rc;
316670eb
A
208}
209
210/* CTR mode. */
211
212/* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
213 for _size_. */
214#define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
3e170ce0 215#define ccctr_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
216
217/* This is Integer Counter Mode: The IV is the initial value of the counter
218 that is incremented by 1 for each new block. Use the mode flags to select
219 if the IV/Counter is stored in big or little endian. */
220
221CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
222{
223 return mode->size;
224}
225
39037602 226CC_INLINE size_t ccctr_block_size(const struct ccmode_ctr *mode)
316670eb 227{
cb323159 228 return mode->block_size;
316670eb
A
229}
230
cb323159 231CC_INLINE int ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 232{
d190cdc3 233 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
234}
235
cb323159 236CC_INLINE int ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 237{
cb323159 238 return mode->ctr(ctx, nbytes, in, out);
316670eb
A
239}
240
d190cdc3 241CC_INLINE int ccctr_one_shot(const struct ccmode_ctr *mode,
cb323159
A
242 size_t key_len,
243 const void *key,
244 const void *iv,
245 size_t nbytes,
246 const void *in,
247 void *out)
316670eb 248{
d190cdc3 249 int rc;
cb323159
A
250 ccctr_ctx_decl(mode->size, ctx);
251 rc = mode->init(mode, ctx, key_len, key, iv);
252 if (rc == 0) {
253 rc = mode->ctr(ctx, nbytes, in, out);
254 }
255 ccctr_ctx_clear(mode->size, ctx);
d190cdc3 256 return rc;
316670eb
A
257}
258
316670eb
A
259/* OFB mode. */
260
261/* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
262 for _size_. */
263#define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
3e170ce0 264#define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
265
266CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
267{
268 return mode->size;
269}
270
39037602 271CC_INLINE size_t ccofb_block_size(const struct ccmode_ofb *mode)
316670eb 272{
cb323159 273 return mode->block_size;
316670eb
A
274}
275
cb323159 276CC_INLINE int ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 277{
d190cdc3 278 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
279}
280
cb323159 281CC_INLINE int ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 282{
cb323159 283 return mode->ofb(ctx, nbytes, in, out);
316670eb
A
284}
285
d190cdc3 286CC_INLINE int ccofb_one_shot(const struct ccmode_ofb *mode,
cb323159
A
287 size_t key_len,
288 const void *key,
289 const void *iv,
290 size_t nbytes,
291 const void *in,
292 void *out)
316670eb 293{
d190cdc3 294 int rc;
cb323159 295 ccofb_ctx_decl(mode->size, ctx);
d190cdc3 296 rc = mode->init(mode, ctx, key_len, key, iv);
cb323159
A
297 if (rc == 0) {
298 rc = mode->ofb(ctx, nbytes, in, out);
299 }
300 ccofb_ctx_clear(mode->size, ctx);
d190cdc3 301 return rc;
316670eb
A
302}
303
316670eb
A
304/* XTS mode. */
305
306/* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
307 for _size_. */
308#define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
3e170ce0 309#define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb 310
fe8ab488
A
311/* Declare a xts tweak named _name_. Pass the tweak_size field of a
312 struct ccmode_xts for _size_. */
316670eb 313#define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
3e170ce0 314#define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
315
316/* Actual symmetric algorithm implementation can provide you one of these.
317
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
fe8ab488
A
321 you can dynamically initialize a struct ccmode_xts
322 ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
316670eb
A
323
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
327 of 16. */
328
329CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
330{
331 return mode->size;
332}
333
39037602 334CC_INLINE size_t ccxts_block_size(const struct ccmode_xts *mode)
316670eb 335{
cb323159 336 return mode->block_size;
316670eb
A
337}
338
d190cdc3
A
339/*!
340 @function ccxts_init
341 @abstract Initialize an XTS context.
cb323159 342
d190cdc3
A
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
cb323159 348
d190cdc3 349 @result 0 iff successful.
cb323159 350
d190cdc3
A
351 @discussion For security reasons, the two keys must be different.
352 */
cb323159
A
353CC_INLINE int
354ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx, size_t key_nbytes, const void *data_key, const void *tweak_key)
316670eb 355{
d190cdc3 356 return mode->init(mode, ctx, key_nbytes, data_key, tweak_key);
316670eb
A
357}
358
d190cdc3
A
359/*!
360 @function ccxts_set_tweak
361 @abstract Initialize the tweak for a sector.
cb323159 362
d190cdc3
A
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
cb323159 367
d190cdc3
A
368 @discussion The IV must be exactly one block in length.
369 */
cb323159 370CC_INLINE int ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv)
d190cdc3 371{
cb323159 372 return mode->set_tweak(ctx, tweak, iv);
d190cdc3
A
373}
374
375/*!
376 @function ccxts_update
377 @abstract Encrypt or decrypt data.
cb323159 378
d190cdc3
A
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
383 @param in Input data
384 @param out Output buffer
cb323159 385
d190cdc3
A
386 @result The updated internal buffer of the tweak context. May be ignored.
387 */
cb323159
A
388CC_INLINE void *
389ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, size_t nblocks, const void *in, void *out)
316670eb 390{
cb323159 391 return mode->xts(ctx, tweak, nblocks, in, out);
316670eb
A
392}
393
d190cdc3
A
394/*!
395 @function ccxts_one_shot
396 @abstract Encrypt or decrypt data in XTS mode.
cb323159 397
d190cdc3
A
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
404 @param in Input data
405 @param out Output buffer
cb323159 406
d190cdc3 407 @result 0 iff successful.
cb323159 408
d190cdc3
A
409 @discussion For security reasons, the two keys must be different.
410 */
411int ccxts_one_shot(const struct ccmode_xts *mode,
cb323159
A
412 size_t key_nbytes,
413 const void *data_key,
414 const void *tweak_key,
415 const void *iv,
416 size_t nblocks,
417 const void *in,
418 void *out);
d190cdc3
A
419
420/* Authenticated cipher modes. */
316670eb
A
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_)
3e170ce0 427#define ccgcm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb 428
d190cdc3
A
429#define CCGCM_IV_NBYTES 12
430#define CCGCM_BLOCK_NBYTES 16
431
5ba3f43e
A
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)
437
316670eb
A
438CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
439{
440 return mode->size;
441}
442
39037602 443CC_INLINE size_t ccgcm_block_size(const struct ccmode_gcm *mode)
316670eb 444{
cb323159 445 return mode->block_size;
316670eb
A
446}
447
d190cdc3
A
448/*!
449 @function ccgcm_init
450 @abstract Initialize a GCM context.
cb323159 451
d190cdc3
A
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)
cb323159 456
d190cdc3 457 @result 0 iff successful.
cb323159 458
d190cdc3 459 @discussion The correct sequence of calls is:
cb323159 460
d190cdc3
A
461 @code ccgcm_init(...)
462 ccgcm_set_iv(...)
463 ccgcm_aad(...) (may be called zero or more times)
464 ccgcm_update(...) (may be called zero or more times)
465 ccgcm_finalize(...)
cb323159 466
d190cdc3 467 To reuse the context for additional encryptions, follow this sequence:
cb323159 468
d190cdc3
A
469 @code ccgcm_reset(...)
470 ccgcm_set_iv(...)
471 ccgcm_aad(...) (may be called zero or more times)
472 ccgcm_update(...) (may be called zero or more times)
473 ccgcm_finalize(...)
cb323159 474
d190cdc3 475 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
cb323159
A
476
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.
316670eb 479
5ba3f43e 480 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
d190cdc3 481 */
cb323159 482CC_INLINE int ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *key)
d190cdc3
A
483{
484 return mode->init(mode, ctx, key_nbytes, key);
485}
486
487/*!
488 @function ccgcm_init_with_iv
489 @abstract Initialize a GCM context to manage IVs internally.
cb323159 490
d190cdc3
A
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
cb323159 496
d190cdc3 497 @result 0 iff successful.
cb323159 498
d190cdc3 499 @discussion The correct sequence of calls is:
cb323159 500
d190cdc3
A
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)
504 ccgcm_finalize(...)
cb323159 505
d190cdc3 506 To reuse the context for additional encryptions, follow this sequence:
cb323159 507
d190cdc3
A
508 @code ccgcm_reset(...)
509 ccgcm_inc_iv(...)
510 ccgcm_aad(...) (may be called zero or more times)
511 ccgcm_update(...) (may be called zero or more times)
512 ccgcm_finalize(...)
cb323159 513
d190cdc3 514 The IV must be exactly 12 bytes in length.
cb323159
A
515
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.
519
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.
522
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.
d190cdc3 525 */
cb323159 526int ccgcm_init_with_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *key, const void *iv);
d190cdc3
A
527
528/*!
529 @function ccgcm_set_iv
530 @abstract Set the IV for encryption.
cb323159 531
d190cdc3
A
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
cb323159 536
d190cdc3 537 @result 0 iff successful.
cb323159 538
d190cdc3 539 @discussion Set the initialization vector for encryption.
cb323159 540
d190cdc3 541 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
cb323159
A
542
543 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
544 use as the IV.
545
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).
548
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.
551
5ba3f43e 552 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
d190cdc3 553 */
cb323159 554CC_INLINE int ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv)
d190cdc3 555{
cb323159 556 return mode->set_iv(ctx, iv_nbytes, iv);
d190cdc3
A
557}
558
559/*!
560 @function ccgcm_set_iv_legacy
561 @abstract Set the IV for encryption.
cb323159 562
d190cdc3
A
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
cb323159 567
d190cdc3 568 @result 0 iff successful.
cb323159 569
d190cdc3 570 @discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.
cb323159 571
d190cdc3 572 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
cb323159 573
d190cdc3
A
574 @warning Do not use this function in new applications.
575 */
cb323159 576int ccgcm_set_iv_legacy(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv);
d190cdc3
A
577
578/*!
579 @function ccgcm_inc_iv
580 @abstract Increment the IV for another encryption.
cb323159 581
d190cdc3
A
582 @param mode Descriptor for the mode
583 @param ctx Context for this instance
584 @param iv Updated initialization vector
cb323159 585
d190cdc3 586 @result 0 iff successful.
cb323159 587
d190cdc3 588 @discussion Updates the IV internally for another encryption.
cb323159
A
589
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.
592
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
594 packet (e.g. TLS).
595
d190cdc3
A
596 @warning This function may be used only after initializing the cipher via @p ccgcm_init_with_iv.
597 */
598int ccgcm_inc_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, void *iv);
599
d190cdc3
A
600/*!
601 @function ccgcm_aad
602 @abstract Authenticate additional data.
cb323159 603
d190cdc3
A
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
cb323159 608
d190cdc3 609 @result 0 iff successful.
cb323159 610
d190cdc3 611 @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
cb323159 612
d190cdc3
A
613 This function may be called zero or more times.
614 */
cb323159 615CC_INLINE int ccgcm_aad(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *additional_data)
39037602
A
616{
617 return mode->gmac(ctx, nbytes, additional_data);
316670eb
A
618}
619
d190cdc3
A
620/*!
621 @function ccgcm_gmac
cb323159
A
622
623 @discussion ccgcm_gmac is deprecated. Use the drop-in replacement 'ccgcm_aad' instead.
d190cdc3 624 */
cb323159
A
625CC_INLINE int ccgcm_gmac (const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *in)
626cc_deprecate_with_replacement("ccgcm_aad", 13.0, 10.15, 13.0, 6.0, 4.0)
316670eb 627{
cb323159 628 return mode->gmac(ctx, nbytes, in);
316670eb
A
629}
630
d190cdc3
A
631/*!
632 @function ccgcm_update
633 @abstract Encrypt or decrypt data.
cb323159 634
d190cdc3
A
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
cb323159 640
d190cdc3 641 @result 0 iff successful.
cb323159 642
d190cdc3 643 @discussion In-place processing is supported.
cb323159 644
d190cdc3
A
645 This function may be called zero or more times.
646 */
cb323159 647CC_INLINE int ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 648{
cb323159 649 return mode->gcm(ctx, nbytes, in, out);
316670eb
A
650}
651
d190cdc3
A
652/*!
653 @function ccgcm_finalize
654 @abstract Finish processing and authenticate.
cb323159 655
d190cdc3
A
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
cb323159 660
d190cdc3 661 @result 0 iff successful.
cb323159 662
d190cdc3 663 @discussion Finish processing a packet and generate the authentication tag.
cb323159 664
d190cdc3 665 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
cb323159
A
666
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.
670
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.
d190cdc3 673 */
cb323159 674CC_INLINE int ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t tag_nbytes, void *tag)
316670eb 675{
cb323159 676 return mode->finalize(ctx, tag_nbytes, tag);
316670eb
A
677}
678
d190cdc3
A
679/*!
680 @function ccgcm_reset
681 @abstract Reset the context for another encryption.
cb323159 682
d190cdc3
A
683 @param mode Descriptor for the mode
684 @param ctx Context for this instance
cb323159 685
d190cdc3 686 @result 0 iff successful.
cb323159 687
d190cdc3
A
688 @discussion Refer to @p ccgcm_init for correct usage.
689 */
39037602 690CC_INLINE int ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
316670eb 691{
39037602 692 return mode->reset(ctx);
316670eb
A
693}
694
d190cdc3
A
695/*!
696 @function ccgcm_one_shot
697 @abstract Encrypt or decrypt with GCM.
cb323159 698
d190cdc3
A
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
cb323159 711
d190cdc3 712 @result 0 iff successful.
cb323159 713
d190cdc3 714 @discussion Perform GCM encryption or decryption.
cb323159 715
d190cdc3 716 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
cb323159
A
717
718 In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
719 use as the IV.
720
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).
723
d190cdc3 724 In-place processing is supported.
cb323159 725
d190cdc3 726 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
cb323159
A
727
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.
730
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
733 applications.
d190cdc3 734 */
39037602 735int ccgcm_one_shot(const struct ccmode_gcm *mode,
cb323159
A
736 size_t key_nbytes,
737 const void *key,
738 size_t iv_nbytes,
739 const void *iv,
740 size_t adata_nbytes,
741 const void *adata,
742 size_t nbytes,
743 const void *in,
744 void *out,
745 size_t tag_nbytes,
746 void *tag);
d190cdc3
A
747
748/*!
749 @function ccgcm_one_shot_legacy
750 @abstract Encrypt or decrypt with GCM.
cb323159 751
d190cdc3
A
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
cb323159 764
d190cdc3 765 @result 0 iff successful.
cb323159 766
d190cdc3 767 @discussion Identical to @p ccgcm_one_shot except that it allows zero-length IVs.
cb323159 768
d190cdc3 769 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
cb323159 770
d190cdc3
A
771 @warning Do not use this function in new applications.
772 */
39037602 773int ccgcm_one_shot_legacy(const struct ccmode_gcm *mode,
cb323159
A
774 size_t key_nbytes,
775 const void *key,
776 size_t iv_nbytes,
777 const void *iv,
778 size_t adata_nbytes,
779 const void *adata,
780 size_t nbytes,
781 const void *in,
782 void *out,
783 size_t tag_nbytes,
784 void *tag);
316670eb 785
fe8ab488
A
786/* CCM */
787
788#define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
3e170ce0 789#define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
fe8ab488
A
790
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_)
3e170ce0 793#define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
fe8ab488 794
fe8ab488
A
795CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
796{
797 return mode->size;
798}
799
39037602 800CC_INLINE size_t ccccm_block_size(const struct ccmode_ccm *mode)
fe8ab488 801{
cb323159 802 return mode->block_size;
fe8ab488
A
803}
804
cb323159 805CC_INLINE int ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx, size_t key_len, const void *key)
fe8ab488 806{
39037602 807 return mode->init(mode, ctx, key_len, key);
fe8ab488
A
808}
809
cb323159
A
810CC_INLINE int ccccm_set_iv(const struct ccmode_ccm *mode,
811 ccccm_ctx *ctx,
812 ccccm_nonce *nonce_ctx,
813 size_t nonce_len,
814 const void *nonce,
815 size_t mac_size,
816 size_t auth_len,
817 size_t data_len)
fe8ab488 818{
cb323159 819 return mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
fe8ab488
A
820}
821
cb323159 822CC_INLINE int ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in)
fe8ab488 823{
cb323159 824 return mode->cbcmac(ctx, nonce_ctx, nbytes, in);
fe8ab488
A
825}
826
cb323159
A
827CC_INLINE int
828ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out)
fe8ab488 829{
cb323159 830 return mode->ccm(ctx, nonce_ctx, nbytes, in, out);
fe8ab488
A
831}
832
cb323159 833CC_INLINE int ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, void *mac)
fe8ab488 834{
cb323159 835 return mode->finalize(ctx, nonce_ctx, mac);
fe8ab488
A
836}
837
39037602 838CC_INLINE int ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
fe8ab488 839{
39037602 840 return mode->reset(ctx, nonce_ctx);
fe8ab488
A
841}
842
39037602 843CC_INLINE int ccccm_one_shot(const struct ccmode_ccm *mode,
cb323159
A
844 size_t key_len,
845 const void *key,
846 size_t nonce_len,
847 const void *nonce,
848 size_t nbytes,
849 const void *in,
850 void *out,
851 size_t adata_len,
852 const void *adata,
853 size_t mac_size,
854 void *mac)
855{
856 int rc;
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);
860 if (rc == 0) {
861 rc = mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
862 }
863 if (rc == 0) {
864 rc = mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
865 }
866 if (rc == 0) {
867 rc = mode->ccm(ctx, nonce_ctx, nbytes, in, out);
868 }
869 if (rc == 0) {
870 rc = mode->finalize(ctx, nonce_ctx, mac);
871 }
872 ccccm_ctx_clear(mode->size, ctx);
5ba3f43e 873 ccccm_nonce_clear(mode->nonce_size, nonce_ctx);
39037602
A
874
875 return rc;
fe8ab488
A
876}
877
316670eb
A
878/* OMAC mode. */
879
316670eb
A
880/* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
881 for _size_. */
882#define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
3e170ce0 883#define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
884
885CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
886{
887 return mode->size;
888}
889
39037602 890CC_INLINE size_t ccomac_block_size(const struct ccmode_omac *mode)
316670eb 891{
cb323159 892 return mode->block_size;
316670eb
A
893}
894
cb323159 895CC_INLINE int ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t tweak_len, size_t key_len, const void *key)
316670eb 896{
d190cdc3 897 return mode->init(mode, ctx, tweak_len, key_len, key);
316670eb
A
898}
899
cb323159
A
900CC_INLINE int
901ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t nblocks, const void *tweak, const void *in, void *out)
316670eb 902{
cb323159 903 return mode->omac(ctx, nblocks, tweak, in, out);
316670eb
A
904}
905
906CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
cb323159
A
907 size_t tweak_len,
908 size_t key_len,
909 const void *key,
910 const void *tweak,
911 size_t nblocks,
912 const void *in,
913 void *out)
316670eb 914{
d190cdc3 915 int rc;
cb323159
A
916 ccomac_ctx_decl(mode->size, ctx);
917 rc = mode->init(mode, ctx, tweak_len, key_len, key);
918 if (rc == 0) {
919 rc = mode->omac(ctx, nblocks, tweak, in, out);
920 }
921 ccomac_ctx_clear(mode->size, ctx);
d190cdc3 922 return rc;
316670eb
A
923}
924
316670eb 925#endif /* _CORECRYPTO_CCMODE_H_ */