]> git.saurik.com Git - apple/xnu.git/blame - EXTERNAL_HEADERS/corecrypto/ccmode.h
xnu-6153.141.1.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccmode.h
CommitLineData
316670eb
A
1/*
2 * ccmode.h
3 * corecrypto
4 *
3e170ce0
A
5 * Created on 12/07/2010
6 *
7 * Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
316670eb
A
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>
39037602 16#include <corecrypto/ccmode_siv.h>
cb323159 17#include <corecrypto/ccmode_siv_hmac.h>
316670eb
A
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_)
3e170ce0 24#define ccecb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
25
26CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
27{
28 return mode->size;
29}
30
39037602 31CC_INLINE size_t ccecb_block_size(const struct ccmode_ecb *mode)
316670eb 32{
cb323159 33 return mode->block_size;
316670eb
A
34}
35
cb323159 36CC_INLINE int ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx, size_t key_len, const void *key)
316670eb 37{
d190cdc3 38 return mode->init(mode, ctx, key_len, key);
316670eb
A
39}
40
cb323159 41CC_INLINE int ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx, size_t nblocks, const void *in, void *out)
316670eb 42{
cb323159 43 return mode->ecb(ctx, nblocks, in, out);
316670eb
A
44}
45
cb323159
A
46CC_INLINE int
47ccecb_one_shot(const struct ccmode_ecb *mode, size_t key_len, const void *key, size_t nblocks, const void *in, void *out)
316670eb 48{
d190cdc3 49 int rc;
cb323159
A
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);
d190cdc3 56 return rc;
316670eb
A
57}
58
59/* CBC mode. */
60
cb323159 61/* The CBC interface changed due to rdar://11468135. This macros is to indicate
316670eb
A
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_)
3e170ce0 70#define cccbc_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb 71
fe8ab488
A
72/* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
73 struct ccmode_cbc for _size_. */
316670eb 74#define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
3e170ce0 75#define cccbc_iv_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
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
fe8ab488
A
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(). */
316670eb
A
84
85CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
86{
87 return mode->size;
88}
89
39037602 90CC_INLINE size_t cccbc_block_size(const struct ccmode_cbc *mode)
316670eb 91{
cb323159 92 return mode->block_size;
316670eb
A
93}
94
cb323159 95CC_INLINE int cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx, size_t key_len, const void *key)
316670eb 96{
d190cdc3 97 return mode->init(mode, ctx, key_len, key);
316670eb
A
98}
99
cb323159 100CC_INLINE int cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx, const void *iv)
316670eb 101{
cb323159 102 if (iv) {
316670eb 103 cc_copy(mode->block_size, iv_ctx, iv);
cb323159
A
104 } else {
105 cc_clear(mode->block_size, iv_ctx);
106 }
d190cdc3 107 return 0;
316670eb
A
108}
109
cb323159 110CC_INLINE int cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, const void *in, void *out)
316670eb 111{
cb323159 112 return mode->cbc(ctx, iv, nblocks, in, out);
316670eb
A
113}
114
5ba3f43e 115int cccbc_one_shot(const struct ccmode_cbc *mode,
cb323159
A
116 size_t key_len,
117 const void *key,
118 const void *iv,
119 size_t nblocks,
120 const void *in,
121 void *out);
316670eb
A
122
123/* CFB mode. */
124
125/* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
fe8ab488 126 for _size_. */
316670eb 127#define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
3e170ce0 128#define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
129
130CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
131{
132 return mode->size;
133}
134
39037602 135CC_INLINE size_t cccfb_block_size(const struct ccmode_cfb *mode)
316670eb 136{
cb323159 137 return mode->block_size;
316670eb
A
138}
139
cb323159 140CC_INLINE int cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 141{
d190cdc3 142 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
143}
144
cb323159 145CC_INLINE int cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 146{
cb323159 147 return mode->cfb(ctx, nbytes, in, out);
316670eb
A
148}
149
d190cdc3 150CC_INLINE int cccfb_one_shot(const struct ccmode_cfb *mode,
cb323159
A
151 size_t key_len,
152 const void *key,
153 const void *iv,
154 size_t nbytes,
155 const void *in,
156 void *out)
316670eb 157{
d190cdc3 158 int rc;
cb323159
A
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);
d190cdc3 165 return rc;
316670eb
A
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_)
3e170ce0 173#define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
174
175CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
176{
177 return mode->size;
178}
179
39037602 180CC_INLINE size_t cccfb8_block_size(const struct ccmode_cfb8 *mode)
316670eb 181{
cb323159 182 return mode->block_size;
316670eb
A
183}
184
cb323159 185CC_INLINE int cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 186{
d190cdc3 187 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
188}
189
cb323159 190CC_INLINE int cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 191{
cb323159 192 return mode->cfb8(ctx, nbytes, in, out);
316670eb
A
193}
194
d190cdc3 195CC_INLINE int cccfb8_one_shot(const struct ccmode_cfb8 *mode,
cb323159
A
196 size_t key_len,
197 const void *key,
198 const void *iv,
199 size_t nbytes,
200 const void *in,
201 void *out)
316670eb 202{
d190cdc3 203 int rc;
cb323159
A
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);
d190cdc3 210 return rc;
316670eb
A
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_)
3e170ce0 218#define ccctr_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
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
224CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
225{
226 return mode->size;
227}
228
39037602 229CC_INLINE size_t ccctr_block_size(const struct ccmode_ctr *mode)
316670eb 230{
cb323159 231 return mode->block_size;
316670eb
A
232}
233
cb323159 234CC_INLINE int ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 235{
d190cdc3 236 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
237}
238
cb323159 239CC_INLINE int ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 240{
cb323159 241 return mode->ctr(ctx, nbytes, in, out);
316670eb
A
242}
243
d190cdc3 244CC_INLINE int ccctr_one_shot(const struct ccmode_ctr *mode,
cb323159
A
245 size_t key_len,
246 const void *key,
247 const void *iv,
248 size_t nbytes,
249 const void *in,
250 void *out)
316670eb 251{
d190cdc3 252 int rc;
cb323159
A
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);
d190cdc3 259 return rc;
316670eb
A
260}
261
316670eb
A
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_)
3e170ce0 267#define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
268
269CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
270{
271 return mode->size;
272}
273
39037602 274CC_INLINE size_t ccofb_block_size(const struct ccmode_ofb *mode)
316670eb 275{
cb323159 276 return mode->block_size;
316670eb
A
277}
278
cb323159 279CC_INLINE int ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t key_len, const void *key, const void *iv)
316670eb 280{
d190cdc3 281 return mode->init(mode, ctx, key_len, key, iv);
316670eb
A
282}
283
cb323159 284CC_INLINE int ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 285{
cb323159 286 return mode->ofb(ctx, nbytes, in, out);
316670eb
A
287}
288
d190cdc3 289CC_INLINE int ccofb_one_shot(const struct ccmode_ofb *mode,
cb323159
A
290 size_t key_len,
291 const void *key,
292 const void *iv,
293 size_t nbytes,
294 const void *in,
295 void *out)
316670eb 296{
d190cdc3 297 int rc;
cb323159 298 ccofb_ctx_decl(mode->size, ctx);
d190cdc3 299 rc = mode->init(mode, ctx, key_len, key, iv);
cb323159
A
300 if (rc == 0) {
301 rc = mode->ofb(ctx, nbytes, in, out);
302 }
303 ccofb_ctx_clear(mode->size, ctx);
d190cdc3 304 return rc;
316670eb
A
305}
306
316670eb
A
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_)
3e170ce0 312#define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb 313
fe8ab488
A
314/* Declare a xts tweak named _name_. Pass the tweak_size field of a
315 struct ccmode_xts for _size_. */
316670eb 316#define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
3e170ce0 317#define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
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
fe8ab488
A
324 you can dynamically initialize a struct ccmode_xts
325 ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
316670eb
A
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
332CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
333{
334 return mode->size;
335}
336
39037602 337CC_INLINE size_t ccxts_block_size(const struct ccmode_xts *mode)
316670eb 338{
cb323159 339 return mode->block_size;
316670eb
A
340}
341
d190cdc3
A
342/*!
343 @function ccxts_init
344 @abstract Initialize an XTS context.
cb323159 345
d190cdc3
A
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
cb323159 351
d190cdc3 352 @result 0 iff successful.
cb323159 353
d190cdc3
A
354 @discussion For security reasons, the two keys must be different.
355 */
cb323159
A
356CC_INLINE int
357ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx, size_t key_nbytes, const void *data_key, const void *tweak_key)
316670eb 358{
d190cdc3 359 return mode->init(mode, ctx, key_nbytes, data_key, tweak_key);
316670eb
A
360}
361
d190cdc3
A
362/*!
363 @function ccxts_set_tweak
364 @abstract Initialize the tweak for a sector.
cb323159 365
d190cdc3
A
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
cb323159 370
d190cdc3
A
371 @discussion The IV must be exactly one block in length.
372 */
cb323159 373CC_INLINE int ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv)
d190cdc3 374{
cb323159 375 return mode->set_tweak(ctx, tweak, iv);
d190cdc3
A
376}
377
378/*!
379 @function ccxts_update
380 @abstract Encrypt or decrypt data.
cb323159 381
d190cdc3
A
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
cb323159 388
d190cdc3
A
389 @result The updated internal buffer of the tweak context. May be ignored.
390 */
cb323159
A
391CC_INLINE void *
392ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, size_t nblocks, const void *in, void *out)
316670eb 393{
cb323159 394 return mode->xts(ctx, tweak, nblocks, in, out);
316670eb
A
395}
396
d190cdc3
A
397/*!
398 @function ccxts_one_shot
399 @abstract Encrypt or decrypt data in XTS mode.
cb323159 400
d190cdc3
A
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
cb323159 409
d190cdc3 410 @result 0 iff successful.
cb323159 411
d190cdc3
A
412 @discussion For security reasons, the two keys must be different.
413 */
414int ccxts_one_shot(const struct ccmode_xts *mode,
cb323159
A
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);
d190cdc3
A
422
423/* Authenticated cipher modes. */
316670eb
A
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_)
3e170ce0 430#define ccgcm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb 431
d190cdc3
A
432#define CCGCM_IV_NBYTES 12
433#define CCGCM_BLOCK_NBYTES 16
434
5ba3f43e
A
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
316670eb
A
441CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
442{
443 return mode->size;
444}
445
39037602 446CC_INLINE size_t ccgcm_block_size(const struct ccmode_gcm *mode)
316670eb 447{
cb323159 448 return mode->block_size;
316670eb
A
449}
450
d190cdc3
A
451/*!
452 @function ccgcm_init
453 @abstract Initialize a GCM context.
cb323159 454
d190cdc3
A
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)
cb323159 459
d190cdc3 460 @result 0 iff successful.
cb323159 461
d190cdc3 462 @discussion The correct sequence of calls is:
cb323159 463
d190cdc3
A
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(...)
cb323159 469
d190cdc3 470 To reuse the context for additional encryptions, follow this sequence:
cb323159 471
d190cdc3
A
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(...)
cb323159 477
d190cdc3 478 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
cb323159
A
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.
316670eb 482
5ba3f43e 483 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
d190cdc3 484 */
cb323159 485CC_INLINE int ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *key)
d190cdc3
A
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.
cb323159 493
d190cdc3
A
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
cb323159 499
d190cdc3 500 @result 0 iff successful.
cb323159 501
d190cdc3 502 @discussion The correct sequence of calls is:
cb323159 503
d190cdc3
A
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(...)
cb323159 508
d190cdc3 509 To reuse the context for additional encryptions, follow this sequence:
cb323159 510
d190cdc3
A
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(...)
cb323159 516
d190cdc3 517 The IV must be exactly 12 bytes in length.
cb323159
A
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.
d190cdc3 528 */
cb323159 529int ccgcm_init_with_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *key, const void *iv);
d190cdc3
A
530
531/*!
532 @function ccgcm_set_iv
533 @abstract Set the IV for encryption.
cb323159 534
d190cdc3
A
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
cb323159 539
d190cdc3 540 @result 0 iff successful.
cb323159 541
d190cdc3 542 @discussion Set the initialization vector for encryption.
cb323159 543
d190cdc3 544 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
cb323159
A
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
5ba3f43e 555 @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
d190cdc3 556 */
cb323159 557CC_INLINE int ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv)
d190cdc3 558{
cb323159 559 return mode->set_iv(ctx, iv_nbytes, iv);
d190cdc3
A
560}
561
562/*!
563 @function ccgcm_set_iv_legacy
564 @abstract Set the IV for encryption.
cb323159 565
d190cdc3
A
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
cb323159 570
d190cdc3 571 @result 0 iff successful.
cb323159 572
d190cdc3 573 @discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.
cb323159 574
d190cdc3 575 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
cb323159 576
d190cdc3
A
577 @warning Do not use this function in new applications.
578 */
cb323159 579int ccgcm_set_iv_legacy(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv);
d190cdc3
A
580
581/*!
582 @function ccgcm_inc_iv
583 @abstract Increment the IV for another encryption.
cb323159 584
d190cdc3
A
585 @param mode Descriptor for the mode
586 @param ctx Context for this instance
587 @param iv Updated initialization vector
cb323159 588
d190cdc3 589 @result 0 iff successful.
cb323159 590
d190cdc3 591 @discussion Updates the IV internally for another encryption.
cb323159
A
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
d190cdc3
A
599 @warning This function may be used only after initializing the cipher via @p ccgcm_init_with_iv.
600 */
601int ccgcm_inc_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, void *iv);
602
d190cdc3
A
603/*!
604 @function ccgcm_aad
605 @abstract Authenticate additional data.
cb323159 606
d190cdc3
A
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
cb323159 611
d190cdc3 612 @result 0 iff successful.
cb323159 613
d190cdc3 614 @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
cb323159 615
d190cdc3
A
616 This function may be called zero or more times.
617 */
cb323159 618CC_INLINE int ccgcm_aad(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *additional_data)
39037602
A
619{
620 return mode->gmac(ctx, nbytes, additional_data);
316670eb
A
621}
622
d190cdc3
A
623/*!
624 @function ccgcm_gmac
cb323159
A
625
626 @discussion ccgcm_gmac is deprecated. Use the drop-in replacement 'ccgcm_aad' instead.
d190cdc3 627 */
cb323159
A
628CC_INLINE int ccgcm_gmac (const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *in)
629cc_deprecate_with_replacement("ccgcm_aad", 13.0, 10.15, 13.0, 6.0, 4.0)
316670eb 630{
cb323159 631 return mode->gmac(ctx, nbytes, in);
316670eb
A
632}
633
d190cdc3
A
634/*!
635 @function ccgcm_update
636 @abstract Encrypt or decrypt data.
cb323159 637
d190cdc3
A
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
cb323159 643
d190cdc3 644 @result 0 iff successful.
cb323159 645
d190cdc3 646 @discussion In-place processing is supported.
cb323159 647
d190cdc3
A
648 This function may be called zero or more times.
649 */
cb323159 650CC_INLINE int ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *in, void *out)
316670eb 651{
cb323159 652 return mode->gcm(ctx, nbytes, in, out);
316670eb
A
653}
654
d190cdc3
A
655/*!
656 @function ccgcm_finalize
657 @abstract Finish processing and authenticate.
cb323159 658
d190cdc3
A
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
cb323159 663
d190cdc3 664 @result 0 iff successful.
cb323159 665
d190cdc3 666 @discussion Finish processing a packet and generate the authentication tag.
cb323159 667
d190cdc3 668 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
cb323159
A
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.
d190cdc3 676 */
cb323159 677CC_INLINE int ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t tag_nbytes, void *tag)
316670eb 678{
cb323159 679 return mode->finalize(ctx, tag_nbytes, tag);
316670eb
A
680}
681
d190cdc3
A
682/*!
683 @function ccgcm_reset
684 @abstract Reset the context for another encryption.
cb323159 685
d190cdc3
A
686 @param mode Descriptor for the mode
687 @param ctx Context for this instance
cb323159 688
d190cdc3 689 @result 0 iff successful.
cb323159 690
d190cdc3
A
691 @discussion Refer to @p ccgcm_init for correct usage.
692 */
39037602 693CC_INLINE int ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
316670eb 694{
39037602 695 return mode->reset(ctx);
316670eb
A
696}
697
d190cdc3
A
698/*!
699 @function ccgcm_one_shot
700 @abstract Encrypt or decrypt with GCM.
cb323159 701
d190cdc3
A
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
cb323159 714
d190cdc3 715 @result 0 iff successful.
cb323159 716
d190cdc3 717 @discussion Perform GCM encryption or decryption.
cb323159 718
d190cdc3 719 @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
cb323159
A
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
d190cdc3 727 In-place processing is supported.
cb323159 728
d190cdc3 729 On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
cb323159
A
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.
d190cdc3 737 */
39037602 738int ccgcm_one_shot(const struct ccmode_gcm *mode,
cb323159
A
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);
d190cdc3
A
750
751/*!
752 @function ccgcm_one_shot_legacy
753 @abstract Encrypt or decrypt with GCM.
cb323159 754
d190cdc3
A
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
cb323159 767
d190cdc3 768 @result 0 iff successful.
cb323159 769
d190cdc3 770 @discussion Identical to @p ccgcm_one_shot except that it allows zero-length IVs.
cb323159 771
d190cdc3 772 @warning Zero-length IVs nullify the authenticity guarantees of GCM.
cb323159 773
d190cdc3
A
774 @warning Do not use this function in new applications.
775 */
39037602 776int ccgcm_one_shot_legacy(const struct ccmode_gcm *mode,
cb323159
A
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);
316670eb 788
fe8ab488
A
789/* CCM */
790
791#define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
3e170ce0 792#define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
fe8ab488
A
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_)
3e170ce0 796#define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
fe8ab488 797
fe8ab488
A
798CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
799{
800 return mode->size;
801}
802
39037602 803CC_INLINE size_t ccccm_block_size(const struct ccmode_ccm *mode)
fe8ab488 804{
cb323159 805 return mode->block_size;
fe8ab488
A
806}
807
cb323159 808CC_INLINE int ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx, size_t key_len, const void *key)
fe8ab488 809{
39037602 810 return mode->init(mode, ctx, key_len, key);
fe8ab488
A
811}
812
cb323159
A
813CC_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)
fe8ab488 821{
cb323159 822 return mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
fe8ab488
A
823}
824
cb323159 825CC_INLINE int ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in)
fe8ab488 826{
cb323159 827 return mode->cbcmac(ctx, nonce_ctx, nbytes, in);
fe8ab488
A
828}
829
cb323159
A
830CC_INLINE int
831ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out)
fe8ab488 832{
cb323159 833 return mode->ccm(ctx, nonce_ctx, nbytes, in, out);
fe8ab488
A
834}
835
cb323159 836CC_INLINE int ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, void *mac)
fe8ab488 837{
cb323159 838 return mode->finalize(ctx, nonce_ctx, mac);
fe8ab488
A
839}
840
39037602 841CC_INLINE int ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
fe8ab488 842{
39037602 843 return mode->reset(ctx, nonce_ctx);
fe8ab488
A
844}
845
39037602 846CC_INLINE int ccccm_one_shot(const struct ccmode_ccm *mode,
cb323159
A
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);
5ba3f43e 876 ccccm_nonce_clear(mode->nonce_size, nonce_ctx);
39037602
A
877
878 return rc;
fe8ab488
A
879}
880
316670eb
A
881/* OMAC mode. */
882
316670eb
A
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_)
3e170ce0 886#define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
316670eb
A
887
888CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
889{
890 return mode->size;
891}
892
39037602 893CC_INLINE size_t ccomac_block_size(const struct ccmode_omac *mode)
316670eb 894{
cb323159 895 return mode->block_size;
316670eb
A
896}
897
cb323159 898CC_INLINE int ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t tweak_len, size_t key_len, const void *key)
316670eb 899{
d190cdc3 900 return mode->init(mode, ctx, tweak_len, key_len, key);
316670eb
A
901}
902
cb323159
A
903CC_INLINE int
904ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t nblocks, const void *tweak, const void *in, void *out)
316670eb 905{
cb323159 906 return mode->omac(ctx, nblocks, tweak, in, out);
316670eb
A
907}
908
909CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
cb323159
A
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)
316670eb 917{
d190cdc3 918 int rc;
cb323159
A
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);
d190cdc3 925 return rc;
316670eb
A
926}
927
316670eb 928#endif /* _CORECRYPTO_CCMODE_H_ */