xref: /xnu-10002.61.3/EXTERNAL_HEADERS/corecrypto/ccmode.h (revision 0f4c859e951fba394238ab619495c4e1d54d0f34)
1 /* Copyright (c) (2010-2012,2014-2021) Apple Inc. All rights reserved.
2  *
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.
10  */
11 
12 #ifndef _CORECRYPTO_CCMODE_H_
13 #define _CORECRYPTO_CCMODE_H_
14 
15 #include <corecrypto/cc_config.h>
16 #include <corecrypto/cc.h>
17 #include <corecrypto/ccmode_impl.h>
18 #include <corecrypto/ccmode_siv.h>
19 #include <corecrypto/ccmode_siv_hmac.h>
20 
21 
22 
CC_PTRCHECK_CAPABLE_HEADER()23 CC_PTRCHECK_CAPABLE_HEADER()
24 
25 /* ECB mode. */
26 
27 /* Declare a ecb key named _name_.  Pass the size field of a struct ccmode_ecb
28    for _size_. */
29 #define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccecb_ctx, _size_, _name_)
30 #define ccecb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
31 
32 CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
33 {
34     return mode->size;
35 }
36 
ccecb_block_size(const struct ccmode_ecb * mode)37 CC_INLINE size_t ccecb_block_size(const struct ccmode_ecb *mode)
38 {
39     return mode->block_size;
40 }
41 
ccecb_init(const struct ccmode_ecb * mode,ccecb_ctx * ctx,size_t key_len,const void * cc_sized_by (key_len)key)42 CC_INLINE int ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx, size_t key_len, const void *cc_sized_by(key_len) key)
43 {
44     return mode->init(mode, ctx, key_len, key);
45 }
46 
ccecb_update(const struct ccmode_ecb * mode,const ccecb_ctx * ctx,size_t nblocks,const void * cc_indexable in,void * cc_indexable out)47 CC_INLINE int ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx, size_t nblocks, const void *cc_indexable in, void *cc_indexable out)
48 {
49     return mode->ecb(ctx, nblocks, in, out);
50 }
51 
52 CC_INLINE int
ccecb_one_shot(const struct ccmode_ecb * mode,size_t key_len,const void * key,size_t nblocks,const void * cc_indexable in,void * cc_indexable out)53 ccecb_one_shot(const struct ccmode_ecb *mode, size_t key_len, const void *key, size_t nblocks, const void *cc_indexable in, void *cc_indexable out)
54 {
55     int rc;
56     ccecb_ctx_decl(mode->size, ctx);
57     rc = mode->init(mode, ctx, key_len, key);
58     if (rc == 0) {
59         rc = mode->ecb(ctx, nblocks, in, out);
60     }
61     ccecb_ctx_clear(mode->size, ctx);
62     return rc;
63 }
64 
65 /* CBC mode. */
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_vla(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_vla(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 
cccbc_context_size(const struct ccmode_cbc * mode)85 CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
86 {
87     return mode->size;
88 }
89 
cccbc_block_size(const struct ccmode_cbc * mode)90 CC_INLINE size_t cccbc_block_size(const struct ccmode_cbc *mode)
91 {
92     return mode->block_size;
93 }
94 
cccbc_init(const struct ccmode_cbc * mode,cccbc_ctx * ctx,size_t key_len,const void * cc_sized_by (key_len)key)95 CC_INLINE int cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx, size_t key_len, const void *cc_sized_by(key_len) key)
96 {
97     return mode->init(mode, ctx, key_len, key);
98 }
99 
cccbc_copy_iv(cccbc_iv * cc_sized_by (len)iv_ctx,const void * cc_sized_by (len)iv,size_t len)100 CC_INLINE int cccbc_copy_iv(cccbc_iv *cc_sized_by(len) iv_ctx, const void *cc_sized_by(len) iv, size_t len) {
101     cc_copy(len, iv_ctx, iv);
102     return 0;
103 }
cccbc_clear_iv(cccbc_iv * cc_sized_by (len)iv_ctx,size_t len)104 CC_INLINE int cccbc_clear_iv(cccbc_iv *cc_sized_by(len) iv_ctx, size_t len) {
105     cc_clear(len, iv_ctx);
106     return 0;
107 }
108 
109 #if CC_PTRCHECK
110 cc_unavailable() // Use cccbc_copy_iv() or cccbc_clear_iv() directly.
111 int cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx, const void *iv);
112 #else
cccbc_set_iv(const struct ccmode_cbc * mode,cccbc_iv * iv_ctx,const void * iv)113 CC_INLINE int cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx, const void *iv)
114 {
115     return iv ? cccbc_copy_iv(iv_ctx, iv, mode->block_size) : cccbc_clear_iv(iv_ctx, mode->block_size);
116 }
117 #endif
118 
cccbc_update(const struct ccmode_cbc * mode,cccbc_ctx * ctx,cccbc_iv * iv,size_t nblocks,const void * cc_indexable in,void * cc_indexable out)119 CC_INLINE int cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, const void *cc_indexable in, void *cc_indexable out)
120 {
121     return mode->cbc(ctx, iv, nblocks, in, out);
122 }
123 
124 int cccbc_one_shot(const struct ccmode_cbc *mode,
125                    size_t key_len,
126                    const void *cc_sized_by(key_len) key,
127                    const void *cc_sized_by(key_len) iv,
128                    size_t nblocks,
129                    const void *cc_indexable in,
130                    void *cc_indexable out);
131 
132 /* CFB mode. */
133 
134 /* Declare a cfb key named _name_.  Pass the size field of a struct ccmode_cfb
135    for _size_. */
136 #define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl_vla(cccfb_ctx, _size_, _name_)
137 #define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
138 
cccfb_context_size(const struct ccmode_cfb * mode)139 CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
140 {
141     return mode->size;
142 }
143 
cccfb_block_size(const struct ccmode_cfb * mode)144 CC_INLINE size_t cccfb_block_size(const struct ccmode_cfb *mode)
145 {
146     return mode->block_size;
147 }
148 
cccfb_init(const struct ccmode_cfb * mode,cccfb_ctx * ctx,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv)149 CC_INLINE int cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t key_len, const void *cc_sized_by(key_len) key, const void *cc_indexable iv)
150 {
151     return mode->init(mode, ctx, key_len, key, iv);
152 }
153 
cccfb_update(const struct ccmode_cfb * mode,cccfb_ctx * ctx,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)154 CC_INLINE int cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) in, void *cc_sized_by(nbytes) out)
155 {
156     return mode->cfb(ctx, nbytes, in, out);
157 }
158 
cccfb_one_shot(const struct ccmode_cfb * mode,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)159 CC_INLINE int cccfb_one_shot(const struct ccmode_cfb *mode,
160                              size_t key_len,
161                              const void *cc_sized_by(key_len) key,
162                              const void *cc_indexable iv,
163                              size_t nbytes,
164                              const void *cc_sized_by(nbytes) in,
165                              void *cc_sized_by(nbytes) out)
166 {
167     int rc;
168     cccfb_ctx_decl(mode->size, ctx);
169     rc = mode->init(mode, ctx, key_len, key, iv);
170     if (rc == 0) {
171         rc = mode->cfb(ctx, nbytes, in, out);
172     }
173     cccfb_ctx_clear(mode->size, ctx);
174     return rc;
175 }
176 
177 /* CFB8 mode. */
178 
179 /* Declare a cfb8 key named _name_.  Pass the size field of a struct ccmode_cfb8
180  for _size_. */
181 #define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl_vla(cccfb8_ctx, _size_, _name_)
182 #define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
183 
cccfb8_context_size(const struct ccmode_cfb8 * mode)184 CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
185 {
186     return mode->size;
187 }
188 
cccfb8_block_size(const struct ccmode_cfb8 * mode)189 CC_INLINE size_t cccfb8_block_size(const struct ccmode_cfb8 *mode)
190 {
191     return mode->block_size;
192 }
193 
cccfb8_init(const struct ccmode_cfb8 * mode,cccfb8_ctx * ctx,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv)194 CC_INLINE int cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t key_len, const void *cc_sized_by(key_len) key, const void *cc_indexable iv)
195 {
196     return mode->init(mode, ctx, key_len, key, iv);
197 }
198 
cccfb8_update(const struct ccmode_cfb8 * mode,cccfb8_ctx * ctx,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)199 CC_INLINE int cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) in, void *cc_sized_by(nbytes) out)
200 {
201     return mode->cfb8(ctx, nbytes, in, out);
202 }
203 
cccfb8_one_shot(const struct ccmode_cfb8 * mode,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)204 CC_INLINE int cccfb8_one_shot(const struct ccmode_cfb8 *mode,
205                               size_t key_len,
206                               const void *cc_sized_by(key_len) key,
207                               const void *cc_indexable iv,
208                               size_t nbytes,
209                               const void *cc_sized_by(nbytes) in,
210                               void *cc_sized_by(nbytes) out)
211 {
212     int rc;
213     cccfb8_ctx_decl(mode->size, ctx);
214     rc = mode->init(mode, ctx, key_len, key, iv);
215     if (rc == 0) {
216         rc = mode->cfb8(ctx, nbytes, in, out);
217     }
218     cccfb8_ctx_clear(mode->size, ctx);
219     return rc;
220 }
221 
222 /* CTR mode. */
223 
224 /* Declare a ctr key named _name_.  Pass the size field of a struct ccmode_ctr
225  for _size_. */
226 #define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccctr_ctx, _size_, _name_)
227 #define ccctr_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
228 
229 /* This is Integer Counter Mode: The IV is the initial value of the counter
230  that is incremented by 1 for each new block. Use the mode flags to select
231  if the IV/Counter is stored in big or little endian. */
232 
ccctr_context_size(const struct ccmode_ctr * mode)233 CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
234 {
235     return mode->size;
236 }
237 
ccctr_block_size(const struct ccmode_ctr * mode)238 CC_INLINE size_t ccctr_block_size(const struct ccmode_ctr *mode)
239 {
240     return mode->block_size;
241 }
242 
ccctr_init(const struct ccmode_ctr * mode,ccctr_ctx * ctx,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv)243 CC_INLINE int ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t key_len, const void *cc_sized_by(key_len) key, const void *cc_indexable iv)
244 {
245     return mode->init(mode, ctx, key_len, key, iv);
246 }
247 
ccctr_update(const struct ccmode_ctr * mode,ccctr_ctx * ctx,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)248 CC_INLINE int ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) in, void *cc_sized_by(nbytes) out)
249 {
250     return mode->ctr(ctx, nbytes, in, out);
251 }
252 
ccctr_one_shot(const struct ccmode_ctr * mode,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)253 CC_INLINE int ccctr_one_shot(const struct ccmode_ctr *mode,
254                              size_t key_len,
255                              const void *cc_sized_by(key_len) key,
256                              const void *cc_indexable iv,
257                              size_t nbytes,
258                              const void *cc_sized_by(nbytes) in,
259                              void *cc_sized_by(nbytes) out)
260 {
261     int rc;
262     ccctr_ctx_decl(mode->size, ctx);
263     rc = mode->init(mode, ctx, key_len, key, iv);
264     if (rc == 0) {
265         rc = mode->ctr(ctx, nbytes, in, out);
266     }
267     ccctr_ctx_clear(mode->size, ctx);
268     return rc;
269 }
270 
271 /* OFB mode. */
272 
273 /* Declare a ofb key named _name_.  Pass the size field of a struct ccmode_ofb
274  for _size_. */
275 #define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccofb_ctx, _size_, _name_)
276 #define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
277 
ccofb_context_size(const struct ccmode_ofb * mode)278 CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
279 {
280     return mode->size;
281 }
282 
ccofb_block_size(const struct ccmode_ofb * mode)283 CC_INLINE size_t ccofb_block_size(const struct ccmode_ofb *mode)
284 {
285     return mode->block_size;
286 }
287 
ccofb_init(const struct ccmode_ofb * mode,ccofb_ctx * ctx,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv)288 CC_INLINE int ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t key_len, const void *cc_sized_by(key_len) key, const void *cc_indexable iv)
289 {
290     return mode->init(mode, ctx, key_len, key, iv);
291 }
292 
ccofb_update(const struct ccmode_ofb * mode,ccofb_ctx * ctx,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)293 CC_INLINE int ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) in, void *cc_sized_by(nbytes) out)
294 {
295     return mode->ofb(ctx, nbytes, in, out);
296 }
297 
ccofb_one_shot(const struct ccmode_ofb * mode,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_indexable iv,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)298 CC_INLINE int ccofb_one_shot(const struct ccmode_ofb *mode,
299                              size_t key_len,
300                              const void *cc_sized_by(key_len) key,
301                              const void *cc_indexable iv,
302                              size_t nbytes,
303                              const void *cc_sized_by(nbytes) in,
304                              void *cc_sized_by(nbytes) out)
305 {
306     int rc;
307     ccofb_ctx_decl(mode->size, ctx);
308     rc = mode->init(mode, ctx, key_len, key, iv);
309     if (rc == 0) {
310         rc = mode->ofb(ctx, nbytes, in, out);
311     }
312     ccofb_ctx_clear(mode->size, ctx);
313     return rc;
314 }
315 
316 /* XTS mode. */
317 
318 /* Declare a xts key named _name_.  Pass the size field of a struct ccmode_xts
319  for _size_. */
320 #define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccxts_ctx, _size_, _name_)
321 #define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
322 
323 /* Declare a xts tweak named _name_.  Pass the tweak_size field of a
324    struct ccmode_xts for _size_. */
325 #define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl_vla(ccxts_tweak, _size_, _name_)
326 #define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
327 
328 /* Actual symmetric algorithm implementation can provide you one of these.
329 
330  Alternatively you can create a ccmode_xts instance from any ccmode_ecb
331  cipher.  To do so, statically initialize a struct ccmode_xts using the
332  CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
333  you can dynamically initialize a struct ccmode_xts
334  ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
335 
336 /* NOTE that xts mode does not do cts padding.  It's really an xex mode.
337    If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
338    functions.   Also note that xts only works for ecb modes with a block_size
339    of 16.  */
340 
ccxts_context_size(const struct ccmode_xts * mode)341 CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
342 {
343     return mode->size;
344 }
345 
ccxts_block_size(const struct ccmode_xts * mode)346 CC_INLINE size_t ccxts_block_size(const struct ccmode_xts *mode)
347 {
348     return mode->block_size;
349 }
350 
351 /*!
352  @function   ccxts_init
353  @abstract   Initialize an XTS context.
354 
355  @param      mode       Descriptor for the mode
356  @param      ctx        Context for this instance
357  @param      key_nbytes Length of the key arguments in bytes
358  @param      data_key   Key for data encryption
359  @param      tweak_key  Key for tweak generation
360 
361  @result     0 iff successful.
362 
363  @discussion For security reasons, the two keys must be different.
364  */
365 CC_INLINE int
ccxts_init(const struct ccmode_xts * mode,ccxts_ctx * ctx,size_t key_nbytes,const void * cc_sized_by (key_nbytes)data_key,const void * cc_sized_by (key_nbytes)tweak_key)366 ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx, size_t key_nbytes, const void *cc_sized_by(key_nbytes) data_key, const void *cc_sized_by(key_nbytes) tweak_key)
367 {
368     return mode->init(mode, ctx, key_nbytes, data_key, tweak_key);
369 }
370 
371 /*!
372  @function   ccxts_set_tweak
373  @abstract   Initialize the tweak for a sector.
374 
375  @param      mode       Descriptor for the mode
376  @param      ctx        Context for this instance
377  @param      tweak      Context for the tweak for this sector
378  @param      iv         Data used to generate the tweak
379 
380  @discussion The IV must be exactly one block in length.
381  */
ccxts_set_tweak(const struct ccmode_xts * mode,ccxts_ctx * ctx,ccxts_tweak * tweak,const void * cc_indexable iv)382 CC_INLINE int ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, const void *cc_indexable iv)
383 {
384     return mode->set_tweak(ctx, tweak, iv);
385 }
386 
387 /*!
388  @function   ccxts_update
389  @abstract   Encrypt or decrypt data.
390 
391  @param      mode       Descriptor for the mode
392  @param      ctx        Context for an instance
393  @param      tweak      Context for the tweak for this sector
394  @param      nblocks    Length of the data in blocks
395  @param      in         Input data
396  @param      out        Output buffer
397 
398  @result     The updated internal buffer of the tweak context. May be ignored.
399   */
400 CC_INLINE void *cc_unsafe_indexable
ccxts_update(const struct ccmode_xts * mode,ccxts_ctx * ctx,ccxts_tweak * tweak,size_t nblocks,const void * cc_indexable in,void * cc_indexable out)401 ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, size_t nblocks, const void *cc_indexable in, void *cc_indexable out)
402 {
403     return mode->xts(ctx, tweak, nblocks, in, out);
404 }
405 
406 /*!
407  @function   ccxts_one_shot
408  @abstract   Encrypt or decrypt data in XTS mode.
409 
410  @param      mode       Descriptor for the mode
411  @param      key_nbytes Length of the key arguments in bytes
412  @param      data_key   Key for data encryption
413  @param      tweak_key  Key for tweak generation
414  @param      iv         Data used to generate the tweak
415  @param      nblocks    Length of the data in blocks
416  @param      in         Input data
417  @param      out        Output buffer
418 
419  @result     0 iff successful.
420 
421  @discussion For security reasons, the two keys must be different.
422  */
423 int ccxts_one_shot(const struct ccmode_xts *mode,
424                    size_t key_nbytes,
425                    const void *cc_sized_by(key_nbytes) data_key,
426                    const void *cc_sized_by(key_nbytes) tweak_key,
427                    const void *cc_unsafe_indexable iv,
428                    size_t nblocks,
429                    const void *cc_unsafe_indexable in,
430                    void *cc_unsafe_indexable out);
431 
432 /* Authenticated cipher modes. */
433 
434 /* GCM mode. */
435 
436 /* Declare a gcm key named _name_.  Pass the size field of a struct ccmode_gcm
437  for _size_. */
438 #define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccgcm_ctx, _size_, _name_)
439 #define ccgcm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
440 
441 #define CCGCM_IV_NBYTES 12
442 #define CCGCM_BLOCK_NBYTES 16
443 
444 /* (2^32 - 2) blocks */
445 /* (2^36 - 32) bytes */
446 /* (2^39 - 256) bits */
447 /* Exceeding this figure breaks confidentiality and authenticity. */
448 #define CCGCM_TEXT_MAX_NBYTES ((1ULL << 36) - 32ULL)
449 
ccgcm_context_size(const struct ccmode_gcm * mode)450 CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
451 {
452     return mode->size;
453 }
454 
ccgcm_block_size(const struct ccmode_gcm * mode)455 CC_INLINE size_t ccgcm_block_size(const struct ccmode_gcm *mode)
456 {
457     return mode->block_size;
458 }
459 
460 /*!
461  @function   ccgcm_init
462  @abstract   Initialize a GCM context.
463 
464  @param      mode       Descriptor for the mode
465  @param      ctx        Context for this instance
466  @param      key_nbytes Length of the key in bytes
467  @param      key        Key for the underlying blockcipher (AES)
468 
469  @result     0 iff successful.
470 
471  @discussion The correct sequence of calls is:
472 
473  @code ccgcm_init(...)
474  ccgcm_set_iv(...)
475  ccgcm_aad(...)       (may be called zero or more times)
476  ccgcm_update(...)    (may be called zero or more times)
477  ccgcm_finalize(...)
478 
479  To reuse the context for additional encryptions, follow this sequence:
480 
481  @code ccgcm_reset(...)
482  ccgcm_set_iv(...)
483  ccgcm_aad(...)       (may be called zero or more times)
484  ccgcm_update(...)    (may be called zero or more times)
485  ccgcm_finalize(...)
486 
487  @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
488 
489  @warning It is not permitted to call @p ccgcm_inc_iv after initializing the cipher via the @p ccgcm_init interface. Nonzero is
490  returned in the event of an improper call sequence.
491 
492  @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
493  */
ccgcm_init(const struct ccmode_gcm * mode,ccgcm_ctx * ctx,size_t key_nbytes,const void * cc_sized_by (key_nbytes)key)494 CC_INLINE int ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *cc_sized_by(key_nbytes) key)
495 {
496     return mode->init(mode, ctx, key_nbytes, key);
497 }
498 
499 /*!
500  @function   ccgcm_init_with_iv
501  @abstract   Initialize a GCM context to manage IVs internally.
502 
503  @param      mode       Descriptor for the mode
504  @param      ctx        Context for this instance
505  @param      key_nbytes Length of the key in bytes
506  @param      key        Key for the underlying blockcipher (AES)
507  @param      iv         IV for the first encryption
508 
509  @result     0 iff successful.
510 
511  @discussion The correct sequence of calls is:
512 
513  @code ccgcm_init_with_iv(...)
514  ccgcm_aad(...)       (may be called zero or more times)
515  ccgcm_update(...)    (may be called zero or more times)
516  ccgcm_finalize(...)
517 
518  To reuse the context for additional encryptions, follow this sequence:
519 
520  @code ccgcm_reset(...)
521  ccgcm_inc_iv(...)
522  ccgcm_aad(...)       (may be called zero or more times)
523  ccgcm_update(...)    (may be called zero or more times)
524  ccgcm_finalize(...)
525 
526  The IV must be exactly 12 bytes in length.
527 
528  Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain
529  protocols (e.g. TLS). In the call to @p ccgcm_inc_iv, the counter component will be interpreted as a big-endian, unsigned value
530  and incremented in place.
531 
532  @warning It is not permitted to call @p ccgcm_set_iv after initializing the cipher via the @p ccgcm_init_with_iv interface.
533  Nonzero is returned in the event of an improper call sequence.
534 
535  @warning The security of GCM depends on the uniqueness of key-IV pairs. To avoid key-IV repetition, callers should not initialize
536  multiple contexts with the same key material via the @p ccgcm_init_with_iv interface.
537  */
538 int ccgcm_init_with_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *cc_sized_by(key_nbytes) key, const void *cc_unsafe_indexable iv);
539 
540 /*!
541  @function   ccgcm_set_iv
542  @abstract   Set the IV for encryption.
543 
544  @param      mode       Descriptor for the mode
545  @param      ctx        Context for this instance
546  @param      iv_nbytes  Length of the IV in bytes
547  @param      iv         Initialization vector
548 
549  @result     0 iff successful.
550 
551  @discussion Set the initialization vector for encryption.
552 
553  @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
554 
555  In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
556  use as the IV.
557 
558  In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number
559  generator (e.g. @p ccrng).
560 
561  @warning This function may not be used after initializing the cipher via @p ccgcm_init_with_iv. Nonzero is returned in the event
562  of an improper call sequence.
563 
564  @warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
565  */
ccgcm_set_iv(const struct ccmode_gcm * mode,ccgcm_ctx * ctx,size_t iv_nbytes,const void * cc_sized_by (iv_nbytes)iv)566 CC_INLINE int ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *cc_sized_by(iv_nbytes) iv)
567 {
568     return mode->set_iv(ctx, iv_nbytes, iv);
569 }
570 
571 /*!
572  @function   ccgcm_set_iv_legacy
573  @abstract   Set the IV for encryption.
574 
575  @param      mode       Descriptor for the mode
576  @param      ctx        Context for this instance
577  @param      iv_nbytes  Length of the IV in bytes
578  @param      iv         Initialization vector
579 
580  @result     0 iff successful.
581 
582  @discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.
583 
584  @warning Zero-length IVs nullify the authenticity guarantees of GCM.
585 
586  @warning Do not use this function in new applications.
587  */
588 int ccgcm_set_iv_legacy(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *cc_sized_by(iv_nbytes) iv);
589 
590 /*!
591  @function   ccgcm_inc_iv
592  @abstract   Increment the IV for another encryption.
593 
594  @param      mode       Descriptor for the mode
595  @param      ctx        Context for this instance
596  @param      iv         Updated initialization vector
597 
598  @result     0 iff successful.
599 
600  @discussion Updates the IV internally for another encryption.
601 
602  Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain
603  protocols (e.g. TLS). The counter component is interpreted as a big-endian, unsigned value and incremented in place.
604 
605  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
606  packet (e.g. TLS).
607 
608  @warning This function may be used only after initializing the cipher via @p ccgcm_init_with_iv.
609  */
610 int ccgcm_inc_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, void *cc_unsafe_indexable iv);
611 
612 /*!
613  @function   ccgcm_aad
614  @abstract   Authenticate additional data.
615 
616  @param      mode               Descriptor for the mode
617  @param      ctx                Context for this instance
618  @param      nbytes             Length of the additional data in bytes
619  @param      additional_data    Additional data to authenticate
620 
621  @result     0 iff successful.
622 
623  @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
624 
625  This function may be called zero or more times.
626  */
ccgcm_aad(const struct ccmode_gcm * mode,ccgcm_ctx * ctx,size_t nbytes,const void * cc_sized_by (nbytes)additional_data)627 CC_INLINE int ccgcm_aad(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) additional_data)
628 {
629     return mode->gmac(ctx, nbytes, additional_data);
630 }
631 
632 /*!
633  @function   ccgcm_gmac
634 
635  @discussion ccgcm_gmac is deprecated. Use the drop-in replacement 'ccgcm_aad' instead.
636  */
ccgcm_gmac(const struct ccmode_gcm * mode,ccgcm_ctx * ctx,size_t nbytes,const void * cc_sized_by (nbytes)in)637 CC_INLINE int ccgcm_gmac (const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) in)
638 cc_deprecate_with_replacement("ccgcm_aad", 13.0, 10.15, 13.0, 6.0, 4.0)
639 {
640     return mode->gmac(ctx, nbytes, in);
641 }
642 
643 /*!
644  @function   ccgcm_update
645  @abstract   Encrypt or decrypt data.
646 
647  @param      mode       Descriptor for the mode
648  @param      ctx        Context for this instance
649  @param      nbytes     Length of the data in bytes
650  @param      in         Input plaintext or ciphertext
651  @param      out        Output ciphertext or plaintext
652 
653  @result     0 iff successful.
654 
655  @discussion In-place processing is supported.
656 
657  This function may be called zero or more times.
658  */
ccgcm_update(const struct ccmode_gcm * mode,ccgcm_ctx * ctx,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)659 CC_INLINE int ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) in, void *cc_sized_by(nbytes) out)
660 {
661     return mode->gcm(ctx, nbytes, in, out);
662 }
663 
664 /*!
665  @function   ccgcm_finalize
666  @abstract   Finish processing and authenticate.
667 
668  @param      mode       Descriptor for the mode
669  @param      ctx        Context for this instance
670  @param      tag_nbytes Length of the tag in bytes
671  @param      tag        Authentication tag
672 
673  @result     0 iff successful.
674 
675  @discussion Finish processing a packet and generate the authentication tag.
676 
677  On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
678 
679  On decryption, @p tag is both an input and an output parameter. Well-behaved callers should provide the authentication tag
680  generated during encryption. The function will return nonzero if the input tag does not match the generated tag. The generated
681  tag will be written into the @p tag buffer whether authentication succeeds or fails.
682 
683  @warning The generated tag is written to @p tag to support legacy applications that perform authentication manually. Do not
684  follow this usage pattern in new applications. Rely on the function's error code to verify authenticity.
685  */
ccgcm_finalize(const struct ccmode_gcm * mode,ccgcm_ctx * ctx,size_t tag_nbytes,void * cc_sized_by (tag_nbytes)tag)686 CC_INLINE int ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t tag_nbytes, void *cc_sized_by(tag_nbytes) tag)
687 {
688     return mode->finalize(ctx, tag_nbytes, tag);
689 }
690 
691 /*!
692  @function   ccgcm_reset
693  @abstract   Reset the context for another encryption.
694 
695  @param      mode       Descriptor for the mode
696  @param      ctx        Context for this instance
697 
698  @result     0 iff successful.
699 
700  @discussion Refer to @p ccgcm_init for correct usage.
701  */
ccgcm_reset(const struct ccmode_gcm * mode,ccgcm_ctx * ctx)702 CC_INLINE int ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
703 {
704     return mode->reset(ctx);
705 }
706 
707 /*!
708  @function   ccgcm_one_shot
709  @abstract   Encrypt or decrypt with GCM.
710 
711  @param      mode           Descriptor for the mode
712  @param      key_nbytes     Length of the key in bytes
713  @param      key            Key for the underlying blockcipher (AES)
714  @param      iv_nbytes      Length of the IV in bytes
715  @param      iv             Initialization vector
716  @param      adata_nbytes   Length of the additional data in bytes
717  @param      adata          Additional data to authenticate
718  @param      nbytes         Length of the data in bytes
719  @param      in             Input plaintext or ciphertext
720  @param      out            Output ciphertext or plaintext
721  @param      tag_nbytes     Length of the tag in bytes
722  @param      tag            Authentication tag
723 
724  @result     0 iff successful.
725 
726  @discussion Perform GCM encryption or decryption.
727 
728  @warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
729 
730  In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
731  use as the IV.
732 
733  In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number
734  generator (e.g. @p ccrng).
735 
736  In-place processing is supported.
737 
738  On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
739 
740  On decryption, @p tag is primarily an input parameter. The caller should provide the authentication tag generated during
741  encryption. The function will return nonzero if the input tag does not match the generated tag.
742 
743  @warning To support legacy applications, @p tag is also an output parameter during decryption. The generated tag is written to @p
744  tag. Legacy callers may choose to compare this to the tag generated during encryption. Do not follow this usage pattern in new
745  applications.
746  */
747 int ccgcm_one_shot(const struct ccmode_gcm *mode,
748                    size_t key_nbytes,
749                    const void *cc_sized_by(key_nbytes) key,
750                    size_t iv_nbytes,
751                    const void *cc_sized_by(iv_nbytes) iv,
752                    size_t adata_nbytes,
753                    const void *cc_sized_by(adata_nbytes) adata,
754                    size_t nbytes,
755                    const void *cc_sized_by(nbytes) in,
756                    void *cc_sized_by(nbytes) out,
757                    size_t tag_nbytes,
758                    void *cc_sized_by(tag_nbytes) tag);
759 
760 /*!
761  @function   ccgcm_one_shot_legacy
762  @abstract   Encrypt or decrypt with GCM.
763 
764  @param      mode           Descriptor for the mode
765  @param      key_nbytes     Length of the key in bytes
766  @param      key            Key for the underlying blockcipher (AES)
767  @param      iv_nbytes      Length of the IV in bytes
768  @param      iv             Initialization vector
769  @param      adata_nbytes   Length of the additional data in bytes
770  @param      adata          Additional data to authenticate
771  @param      nbytes         Length of the data in bytes
772  @param      in             Input plaintext or ciphertext
773  @param      out            Output ciphertext or plaintext
774  @param      tag_nbytes     Length of the tag in bytes
775  @param      tag            Authentication tag
776 
777  @result     0 iff successful.
778 
779  @discussion Identical to @p ccgcm_one_shot except that it allows zero-length IVs.
780 
781  @warning Zero-length IVs nullify the authenticity guarantees of GCM.
782 
783  @warning Do not use this function in new applications.
784  */
785 int ccgcm_one_shot_legacy(const struct ccmode_gcm *mode,
786                           size_t key_nbytes,
787                           const void *cc_sized_by(key_nbytes) key,
788                           size_t iv_nbytes,
789                           const void *cc_sized_by(iv_nbytes) iv,
790                           size_t adata_nbytes,
791                           const void *cc_sized_by(adata_nbytes) adata,
792                           size_t nbytes,
793                           const void *cc_sized_by(nbytes) in,
794                           void *cc_sized_by(nbytes) out,
795                           size_t tag_nbytes,
796                           void *cc_sized_by(tag_nbytes) tag);
797 
798 /* CCM */
799 #define CCM_MAX_TAG_SIZE 16
800 #define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccccm_ctx, _size_, _name_)
801 #define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
802 
803 /* Declare a ccm nonce named _name_.  Pass the mode->nonce_ctx_size for _size_. */
804 #define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl_vla(ccccm_nonce, _size_, _name_)
805 #define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
806 
ccccm_context_size(const struct ccmode_ccm * mode)807 CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
808 {
809     return mode->size;
810 }
811 
ccccm_block_size(const struct ccmode_ccm * mode)812 CC_INLINE size_t ccccm_block_size(const struct ccmode_ccm *mode)
813 {
814     return mode->block_size;
815 }
816 
817 /// Initialize a ccm authenticated encryption/decryption mode
818 /// @param mode mode descriptor
819 /// @param ctx  context for this instance
820 /// @param key_len length in bytes of key provided
821 /// @param key bytes defining key
ccccm_init(const struct ccmode_ccm * mode,ccccm_ctx * ctx,size_t key_len,const void * cc_sized_by (key_len)key)822 CC_INLINE int ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx, size_t key_len, const void *cc_sized_by(key_len) key)
823 {
824     return mode->init(mode, ctx, key_len, key);
825 }
826 
827 /// Set the initialization value/nonce for the ccm authenticated encryption/decryption
828 /// @param mode mode descriptor
829 /// @param ctx context for this ccm instance
830 /// @param nonce_ctx  context for this nonce
831 /// @param nonce_len length in bytes of cmac nonce/iv
832 /// @param nonce bytes defining none
833 /// @param mac_size length in bytes of mac tag
834 /// @param auth_len length in bytes of authenticating data
835 /// @param data_len length in bytes of plaintext
ccccm_set_iv(const struct ccmode_ccm * mode,ccccm_ctx * ctx,ccccm_nonce * nonce_ctx,size_t nonce_len,const void * cc_sized_by (nonce_len)nonce,size_t mac_size,size_t auth_len,size_t data_len)836 CC_INLINE int ccccm_set_iv(const struct ccmode_ccm *mode,
837                            ccccm_ctx *ctx,
838                            ccccm_nonce *nonce_ctx,
839                            size_t nonce_len,
840                            const void *cc_sized_by(nonce_len) nonce,
841                            size_t mac_size,
842                            size_t auth_len,
843                            size_t data_len)
844 {
845     return mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
846 }
847 
848 /// (Deprecated) Add associated data to the ccm authenticated encryption/decryption
849 /// @param mode mode descriptor
850 /// @param ctx context for this ccm instance
851 /// @param nonce_ctx  context for this nonce
852 /// @param nbytes nbytes length in bytes of associated data being provided in this invocation
853 /// @param in authenticated data being provided in this invocation
ccccm_cbcmac(const struct ccmode_ccm * mode,ccccm_ctx * ctx,ccccm_nonce * nonce_ctx,size_t nbytes,const void * cc_sized_by (nbytes)in)854 CC_INLINE int ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *cc_sized_by(nbytes) in)
855 {
856     return mode->cbcmac(ctx, nonce_ctx, nbytes, in);
857 }
858 
859 ///Add associated data to the ccm authenticated encryption/decryption
860 /// @param mode mode descriptor
861 /// @param ctx context for this ccm instance
862 /// @param nonce_ctx  context for this nonce
863 /// @param ad_nbytes nbytes length in bytes of associated data being provided in this invocation
864 /// @param ad authenticated data being provided in this invocation
ccccm_aad(const struct ccmode_ccm * mode,ccccm_ctx * ctx,ccccm_nonce * nonce_ctx,size_t ad_nbytes,const uint8_t * cc_sized_by (ad_nbytes)ad)865 CC_INLINE int ccccm_aad(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t ad_nbytes, const uint8_t *cc_sized_by(ad_nbytes) ad)
866 {
867     return mode->cbcmac(ctx, nonce_ctx, ad_nbytes, ad);
868 }
869 
870 /// Add plaintext data to the ccm authenticated encryption/decryption
871 /// @param mode mode descriptor
872 /// @param ctx context for this ccm instance
873 /// @param nonce_ctx  context for this nonce
874 /// @param nbytes length in bytes of both plaintext and encrypted plaintext
875 /// @param in In encryption mode plaintext data, in decryption mode encrypted plaintext data.
876 /// @param out in encryption mode resulting encrypted plaintext data. In decryption mode resulting plaintext data
ccccm_update(const struct ccmode_ccm * mode,ccccm_ctx * ctx,ccccm_nonce * nonce_ctx,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out)877 CC_INLINE int ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *cc_sized_by(nbytes) in, void *cc_sized_by(nbytes) out)
878 {
879     return mode->ccm(ctx, nonce_ctx, nbytes, in, out);
880 }
881 
882 /// Add plaintext data to the ccm authenticated encryption
883 /// @param mode mode descriptor
884 /// @param ctx context for this ccm instance
885 /// @param nonce_ctx  context for this nonce
886 /// @param nbytes length in bytes of both plaintext and encrypted plaintext
887 /// @param plaintext In encryption mode plaintext data, in decryption mode encrypted plaintext data.
888 /// @param encrypted_plaintext in encryption mode resulting encrypted plaintext data. In decryption mode resulting plaintext data
889 int ccccm_encrypt(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const uint8_t *cc_sized_by(nbytes) plaintext, uint8_t *cc_sized_by(nbytes) encrypted_plaintext);
890 
891 /// Add ciphertext data to the ccm authenticated decryption
892 /// @param mode mode descriptor
893 /// @param ctx context for this ccm instance
894 /// @param nonce_ctx  context for this nonce
895 /// @param nbytes length in bytes of both plaintext and encrypted plaintext
896 /// @param encrypted_plaintext In encryption mode plaintext data, in decryption mode encrypted plaintext data.
897 /// @param plaintext in encryption mode resulting encrypted plaintext data. In decryption mode resulting plaintext data
898 int ccccm_decrypt(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const uint8_t *cc_sized_by(nbytes) encrypted_plaintext, uint8_t *cc_sized_by(nbytes) plaintext);
899 
900 
901 /// (Deprecated) Compute tag for ccm
902 /// @param mode mode descriptor
903 /// @param ctx context for this ccm instance
904 /// @param nonce_ctx  context for this nonce
905 /// @param mac tag portion of ciphertext that is computed from ccm MAC.
906 /// @discussion This is being deprecated, as it requires the caller to manually verify that the returned mac tag is correct when decrypting. Please use ccccm_finalize_and_verify instead.
ccccm_finalize(const struct ccmode_ccm * mode,ccccm_ctx * ctx,ccccm_nonce * nonce_ctx,void * cc_indexable mac)907 CC_INLINE int ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, void *cc_indexable mac)
908 {
909     return mode->finalize(ctx, nonce_ctx, mac);
910 }
911 
912 /// Ends encryption and computes tag when in encryption mode
913 /// @param mode mode descriptor
914 /// @param ctx context for this ccm instance
915 /// @param nonce_ctx  context for this nonce
916 /// @param mac For encryption mode the resulting mac tag portion of the ciphertext is copied to this buffer. For decryption mode, it provides an input of the expected tag in the ciphertext
917 /// @return For decryption returns CCERR_OK if the provided mac matches the computed mac, and otherwise returns CCMODE_INTEGRITY_FAILURE.
918 int ccccm_finalize_and_generate_tag(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, uint8_t *cc_indexable mac);
919 
920 /// Ends decryption and verifies tag when in decryption mode
921 /// @param mode mode descriptor
922 /// @param ctx context for this ccm instance
923 /// @param nonce_ctx  context for this nonce
924 /// @param mac It provides an input of the expected tag in the ciphertext
925 /// @return Returns CCERR_OK if the provided mac matches the computed mac, and otherwise returns CCMODE_INTEGRITY_FAILURE.
926 int ccccm_finalize_and_verify_tag(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, const uint8_t *cc_indexable mac);
927 
928 /// Resets the state of the encryptor/decryptor, maintaining the key, but clearing the nonce/iv, allowing for a new encryption or decryption
929 /// @param mode mode descriptor
930 /// @param ctx context for this ccm instance
931 /// @param nonce_ctx  context for this nonce
ccccm_reset(const struct ccmode_ccm * mode,ccccm_ctx * ctx,ccccm_nonce * nonce_ctx)932 CC_INLINE int ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
933 {
934     return mode->reset(ctx, nonce_ctx);
935 }
936 
937 /// (Deprecated) Encrypts/Decrypts a plaintext/ciphertext using the AEAD CCM mode.
938 /// @param mode mode descriptor
939 /// @param key_len key length in bytes
940 /// @param key buffer holding key
941 /// @param nonce_len nonce length in bytes
942 /// @param nonce buffer holding nonce
943 /// @param nbytes the length of the plaintext and encrypted-plaintext
944 /// @param in buffer holding plaintext in encryption mode, and encrypted plaintext portion of ciphertext in decryption mode
945 /// @param out buffer receiving resulting encrypted plaintext in encryption mode, and resulting plaintext in decryption mode
946 /// @param adata_len length in bytes of associated data
947 /// @param adata authenticated data being provided in this invocation.
948 /// @param mac_size length in bytes of CCM mac tag
949 /// @param mac portion of ciphertext that is computed from ccm MAC.
950 /// @return This is being deprecated, as it requires the caller to manually  verify that the returned mac tag is correct when decrypting. Please use ccccm_one_shot_with_verify instead
ccccm_one_shot(const struct ccmode_ccm * mode,size_t key_len,const void * cc_sized_by (key_len)key,size_t nonce_len,const void * cc_sized_by (nonce_len)nonce,size_t nbytes,const void * cc_sized_by (nbytes)in,void * cc_sized_by (nbytes)out,size_t adata_len,const void * cc_sized_by (adata_len)adata,size_t mac_size,void * cc_sized_by (mac_size)mac)951 CC_INLINE int ccccm_one_shot(const struct ccmode_ccm *mode,
952                              size_t key_len,
953                              const void *cc_sized_by(key_len) key,
954                              size_t nonce_len,
955                              const void *cc_sized_by(nonce_len) nonce,
956                              size_t nbytes,
957                              const void *cc_sized_by(nbytes) in,
958                              void *cc_sized_by(nbytes) out,
959                              size_t adata_len,
960                              const void *cc_sized_by(adata_len) adata,
961                              size_t mac_size,
962                              void *cc_sized_by(mac_size) mac)
963 {
964     int rc;
965     ccccm_ctx_decl(mode->size, ctx);
966     ccccm_nonce_decl(mode->nonce_size, nonce_ctx);
967     rc = mode->init(mode, ctx, key_len, key);
968     if (rc == 0) {
969         rc = mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
970     }
971     if (rc == 0) {
972         rc = mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
973     }
974     if (rc == 0) {
975         rc = mode->ccm(ctx, nonce_ctx, nbytes, in, out);
976     }
977     if (rc == 0) {
978         rc = mode->finalize(ctx, nonce_ctx, mac);
979     }
980     ccccm_ctx_clear(mode->size, ctx);
981     ccccm_nonce_clear(mode->nonce_size, nonce_ctx);
982 
983     return rc;
984 }
985 
986 /// Encrypts a plaintext using the AEAD CCM mode, and provides corresponding  mac tag. The encrypted plaintext and tag together are the AEAD ciphertext
987 /// @param mode mode descriptor
988 /// @param key_nbytes key length in bytes
989 /// @param key buffer holding key
990 /// @param nonce_nbytes nonce length in bytes
991 /// @param nonce buffer holding nonce
992 /// @param nbytes  the length of the plaintext and encrypted-plaintext
993 /// @param plaintext buffer holding plaintext in encryption mode, and encrypted plaintext portion of ciphertext in decryption mode
994 /// @param encrypted_plaintext buffer receiving resulting encrypted plaintext in encryption mode
995 /// @param adata_nbytes length in bytes of associated data
996 /// @param adata authenticated data being provided in this invocation.
997 /// @param mac_tag_nbytes length in bytes of CCM mac tag
998 /// @param mac_tag portion of ciphertext that is computed from ccm MAC.
999 /// @return CERR_OK on successful encryption
1000 int ccccm_one_shot_encrypt(const struct ccmode_ccm *mode,
1001                              size_t key_nbytes,
1002                              const uint8_t *cc_sized_by(key_nbytes) key,
1003                              size_t nonce_nbytes,
1004                              const uint8_t *cc_sized_by(nonce_nbytes) nonce,
1005                              size_t nbytes,
1006                              const uint8_t *cc_sized_by(nbytes) plaintext,
1007                              uint8_t *cc_sized_by(nbytes) encrypted_plaintext,
1008                              size_t adata_nbytes,
1009                              const uint8_t *cc_sized_by(adata_nbytes) adata,
1010                              size_t mac_tag_nbytes,
1011                              uint8_t *cc_sized_by(mac_tag_nbytes) mac_tag);
1012 
1013 /// Decrypts a ciphertext using the AEAD CCM mode and ensures authenticity of the ciphertext. An AEAD CCM ciphertext consists of encrypted plaintext and mac tag
1014 /// @param mode mode descriptor
1015 /// @param key_nbytes key length in bytes
1016 /// @param key buffer holding key
1017 /// @param nonce_nbytes nonce length in bytes
1018 /// @param nonce buffer holding nonce
1019 /// @param nbytes  the length of the plaintext and encrypted-plaintext
1020 /// @param encrypted_plaintext buffer holding the encrypted plaintext portion of ciphertext
1021 /// @param plaintext buffer receiving resulting plaintext
1022 /// @param adata_nbytes length in bytes of associated data
1023 /// @param adata authenticated data being provided in this invocation.
1024 /// @param mac_tag_nbytes length in bytes of CCM mac tag
1025 /// @param mac_tag portion of ciphertext that is computed from ccm MAC.
1026 /// @return For decryption returns CCERR_OK if the provided mac matches the computed mac, and otherwise returns CCMODE_INTEGRITY_FAILURE.
1027 int ccccm_one_shot_decrypt(const struct ccmode_ccm *mode,
1028                              size_t key_nbytes,
1029                              const uint8_t *cc_sized_by(key_nbytes) key,
1030                              size_t nonce_nbytes,
1031                              const uint8_t *cc_sized_by(nonce_nbytes) nonce,
1032                              size_t nbytes,
1033                              const uint8_t *cc_sized_by(nbytes) encrypted_plaintext,
1034                              uint8_t *cc_sized_by(nbytes) plaintext,
1035                              size_t adata_nbytes,
1036                              const uint8_t *cc_sized_by(adata_nbytes) adata,
1037                              size_t mac_tag_nbytes,
1038                              const uint8_t *cc_sized_by(mac_tag_nbytes) mac_tag);
1039 
1040 /* OMAC mode. */
1041 
1042 /* Declare a omac key named _name_.  Pass the size field of a struct ccmode_omac
1043  for _size_. */
1044 #define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccomac_ctx, _size_, _name_)
1045 #define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
1046 
ccomac_context_size(const struct ccmode_omac * mode)1047 CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
1048 {
1049     return mode->size;
1050 }
1051 
ccomac_block_size(const struct ccmode_omac * mode)1052 CC_INLINE size_t ccomac_block_size(const struct ccmode_omac *mode)
1053 {
1054     return mode->block_size;
1055 }
1056 
ccomac_init(const struct ccmode_omac * mode,ccomac_ctx * ctx,size_t tweak_len,size_t key_len,const void * cc_sized_by (key_len)key)1057 CC_INLINE int ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t tweak_len, size_t key_len, const void *cc_sized_by(key_len) key)
1058 {
1059     return mode->init(mode, ctx, tweak_len, key_len, key);
1060 }
1061 
1062 CC_INLINE int
ccomac_update(const struct ccmode_omac * mode,ccomac_ctx * ctx,size_t nblocks,const void * tweak,const void * cc_indexable in,void * cc_indexable out)1063 ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t nblocks, const void *tweak, const void *cc_indexable in, void *cc_indexable out)
1064 {
1065     return mode->omac(ctx, nblocks, tweak, in, out);
1066 }
1067 
ccomac_one_shot(const struct ccmode_omac * mode,size_t tweak_len,size_t key_len,const void * cc_sized_by (key_len)key,const void * cc_sized_by (tweak_len)tweak,size_t nblocks,const void * cc_indexable in,void * cc_indexable out)1068 CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
1069                               size_t tweak_len,
1070                               size_t key_len,
1071                               const void *cc_sized_by(key_len) key,
1072                               const void *cc_sized_by(tweak_len) tweak,
1073                               size_t nblocks,
1074                               const void *cc_indexable in,
1075                               void *cc_indexable out)
1076 {
1077     int rc;
1078     ccomac_ctx_decl(mode->size, ctx);
1079     rc = mode->init(mode, ctx, tweak_len, key_len, key);
1080     if (rc == 0) {
1081         rc = mode->omac(ctx, nblocks, tweak, in, out);
1082     }
1083     ccomac_ctx_clear(mode->size, ctx);
1084     return rc;
1085 }
1086 
1087 #endif /* _CORECRYPTO_CCMODE_H_ */
1088