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