1/*
2 *  ccmode.h
3 *  corecrypto
4 *
5 *  Created by Michael Brouwer on 12/6/10.
6 *  Copyright 2010,2011 Apple Inc. All rights reserved.
7 *
8 */
9
10#ifndef _CORECRYPTO_CCMODE_H_
11#define _CORECRYPTO_CCMODE_H_
12
13#include <corecrypto/cc.h>
14#include <corecrypto/ccmode_impl.h>
15
16/* ECB mode. */
17
18/* Declare a ecb key named _name_.  Pass the size field of a struct ccmode_ecb
19   for _size_. */
20#define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl(ccecb_ctx, _size_, _name_)
21#define ccecb_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
22
23CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
24{
25    return mode->size;
26}
27
28CC_INLINE unsigned long ccecb_block_size(const struct ccmode_ecb *mode)
29{
30	return mode->block_size;
31}
32
33CC_INLINE void ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx,
34                          size_t key_len, const void *key)
35{
36    mode->init(mode, ctx, key_len, key);
37}
38
39CC_INLINE void ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx,
40                            unsigned long nblocks, const void *in, void *out)
41{
42	mode->ecb(ctx, nblocks, in, out);
43}
44
45CC_INLINE void ccecb_one_shot(const struct ccmode_ecb *mode,
46                              size_t key_len, const void *key,
47                              unsigned long nblocks, const void *in, void *out)
48{
49	ccecb_ctx_decl(mode->size, ctx);
50	mode->init(mode, ctx, key_len, key);
51	mode->ecb(ctx, nblocks, in, out);
52	ccecb_ctx_clear(mode->size, ctx);
53}
54
55/* CBC mode. */
56
57/* The CBC interface changed due to rdar://11468135. This macros is to indicate
58   to client which CBC API is implemented. Clients can support old versions of
59   corecrypto at build time using this.
60 */
61#define __CC_HAS_FIX_FOR_11468135__ 1
62
63/* Declare a cbc key named _name_.  Pass the size field of a struct ccmode_cbc
64   for _size_. */
65#define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
66#define cccbc_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
67
68/* Declare a cbc iv tweak named _name_.  Pass the blocksize field of a
69   struct ccmode_cbc for _size_. */
70#define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
71#define cccbc_iv_clear(_size_, _name_) cc_ctx_clear(cccbc_iv, _size_, _name_)
72
73/* Actual symmetric algorithm implementation can provide you one of these.
74
75   Alternatively you can create a ccmode_cbc instance from any ccmode_ecb
76   cipher.  To do so, statically initialize a struct ccmode_cbc using the
77   CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros.
78   Alternatively you can dynamically initialize a struct ccmode_cbc
79   ccmode_factory_cbc_decrypt() or ccmode_factory_cbc_encrypt(). */
80
81CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
82{
83    return mode->size;
84}
85
86CC_INLINE unsigned long cccbc_block_size(const struct ccmode_cbc *mode)
87{
88	return mode->block_size;
89}
90
91CC_INLINE void cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx,
92                          size_t key_len, const void *key)
93{
94    mode->init(mode, ctx, key_len, key);
95}
96
97CC_INLINE void cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx,
98                            const void *iv)
99{
100    if (iv)
101        cc_copy(mode->block_size, iv_ctx, iv);
102    else
103        cc_zero(mode->block_size, iv_ctx);
104}
105
106CC_INLINE void cccbc_update(const struct ccmode_cbc *mode,  cccbc_ctx *ctx,
107                            cccbc_iv *iv, unsigned long nblocks,
108                            const void *in, void *out)
109{
110	mode->cbc(ctx, iv, nblocks, in, out);
111}
112
113CC_INLINE void cccbc_one_shot(const struct ccmode_cbc *mode,
114                              unsigned long key_len, const void *key,
115                              const void *iv, unsigned long nblocks,
116                              const void *in, void *out)
117{
118	cccbc_ctx_decl(mode->size, ctx);
119	cccbc_iv_decl(mode->block_size, iv_ctx);
120	mode->init(mode, ctx, key_len, key);
121    if (iv)
122        cccbc_set_iv(mode, iv_ctx, iv);
123    else
124        cc_zero(mode->block_size, iv_ctx);
125    mode->cbc(ctx, iv_ctx, nblocks, in, out);
126	cccbc_ctx_clear(mode->size, ctx);
127}
128
129/* CFB mode. */
130
131/* Declare a cfb key named _name_.  Pass the size field of a struct ccmode_cfb
132   for _size_. */
133#define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
134#define cccfb_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
135
136CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
137{
138    return mode->size;
139}
140
141CC_INLINE unsigned long cccfb_block_size(const struct ccmode_cfb *mode)
142{
143	return mode->block_size;
144}
145
146CC_INLINE void cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
147                          size_t key_len, const void *key,
148                          const void *iv)
149{
150    mode->init(mode, ctx, key_len, key, iv);
151}
152
153CC_INLINE void cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx,
154                            size_t nbytes, const void *in, void *out)
155{
156	mode->cfb(ctx, nbytes, in, out);
157}
158
159CC_INLINE void cccfb_one_shot(const struct ccmode_cfb *mode,
160                              size_t key_len, const void *key, const void *iv,
161                              size_t nbytes, const void *in, void *out)
162{
163	cccfb_ctx_decl(mode->size, ctx);
164	mode->init(mode, ctx, key_len, key, iv);
165	mode->cfb(ctx, nbytes, in, out);
166	cccfb_ctx_clear(mode->size, ctx);
167}
168
169/* CFB8 mode. */
170
171/* Declare a cfb8 key named _name_.  Pass the size field of a struct ccmode_cfb8
172 for _size_. */
173#define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
174#define cccfb8_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
175
176CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
177{
178    return mode->size;
179}
180
181CC_INLINE unsigned long cccfb8_block_size(const struct ccmode_cfb8 *mode)
182{
183	return mode->block_size;
184}
185
186CC_INLINE void cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx,
187                           size_t key_len, const void *key, const void *iv)
188{
189    mode->init(mode, ctx, key_len, key, iv);
190}
191
192CC_INLINE void cccfb8_update(const struct ccmode_cfb8 *mode,  cccfb8_ctx *ctx,
193                             size_t nbytes, const void *in, void *out)
194{
195	mode->cfb8(ctx, nbytes, in, out);
196}
197
198CC_INLINE void cccfb8_one_shot(const struct ccmode_cfb8 *mode,
199                               size_t key_len, const void *key, const void *iv,
200                               size_t nbytes, const void *in, void *out)
201{
202	cccfb8_ctx_decl(mode->size, ctx);
203	mode->init(mode, ctx, key_len, key, iv);
204	mode->cfb8(ctx, nbytes, in, out);
205	cccfb8_ctx_clear(mode->size, ctx);
206}
207
208/* CTR mode. */
209
210/* Declare a ctr key named _name_.  Pass the size field of a struct ccmode_ctr
211 for _size_. */
212#define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
213#define ccctr_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
214
215/* This is Integer Counter Mode: The IV is the initial value of the counter
216 that is incremented by 1 for each new block. Use the mode flags to select
217 if the IV/Counter is stored in big or little endian. */
218
219CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
220{
221    return mode->size;
222}
223
224CC_INLINE unsigned long ccctr_block_size(const struct ccmode_ctr *mode)
225{
226	return mode->block_size;
227}
228
229CC_INLINE void ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
230                          size_t key_len, const void *key, const void *iv)
231{
232    mode->init(mode, ctx, key_len, key, iv);
233}
234
235CC_INLINE void ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx,
236                            size_t nbytes, const void *in, void *out)
237{
238	mode->ctr(ctx, nbytes, in, out);
239}
240
241CC_INLINE void ccctr_one_shot(const struct ccmode_ctr *mode,
242	size_t key_len, const void *key, const void *iv,
243    size_t nbytes, const void *in, void *out)
244{
245	ccctr_ctx_decl(mode->size, ctx);
246	mode->init(mode, ctx, key_len, key, iv);
247	mode->ctr(ctx, nbytes, in, out);
248	ccctr_ctx_clear(mode->size, ctx);
249}
250
251
252/* OFB mode. */
253
254/* Declare a ofb key named _name_.  Pass the size field of a struct ccmode_ofb
255 for _size_. */
256#define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
257#define ccofb_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
258
259CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
260{
261    return mode->size;
262}
263
264CC_INLINE unsigned long ccofb_block_size(const struct ccmode_ofb *mode)
265{
266	return mode->block_size;
267}
268
269CC_INLINE void ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
270                          size_t key_len, const void *key, const void *iv)
271{
272    mode->init(mode, ctx, key_len, key, iv);
273}
274
275CC_INLINE void ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx,
276                            size_t nbytes, const void *in, void *out)
277{
278	mode->ofb(ctx, nbytes, in, out);
279}
280
281CC_INLINE void ccofb_one_shot(const struct ccmode_ofb *mode,
282                              size_t key_len, const void *key, const void *iv,
283                              size_t nbytes, const void *in, void *out)
284{
285	ccofb_ctx_decl(mode->size, ctx);
286	mode->init(mode, ctx, key_len, key, iv);
287	mode->ofb(ctx, nbytes, in, out);
288	ccofb_ctx_clear(mode->size, ctx);
289}
290
291/* Authenticated cipher modes. */
292
293/* XTS mode. */
294
295/* Declare a xts key named _name_.  Pass the size field of a struct ccmode_xts
296 for _size_. */
297#define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
298#define ccxts_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
299
300/* Declare a xts tweak named _name_.  Pass the tweak_size field of a
301   struct ccmode_xts for _size_. */
302#define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
303#define ccxts_tweak_clear(_size_, _name_) cc_zero(_size_, _name_)
304
305/* Actual symmetric algorithm implementation can provide you one of these.
306
307 Alternatively you can create a ccmode_xts instance from any ccmode_ecb
308 cipher.  To do so, statically initialize a struct ccmode_xts using the
309 CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
310 you can dynamically initialize a struct ccmode_xts
311 ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
312
313/* NOTE that xts mode does not do cts padding.  It's really an xex mode.
314   If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
315   functions.   Also note that xts only works for ecb modes with a block_size
316   of 16.  */
317
318CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
319{
320    return mode->size;
321}
322
323CC_INLINE unsigned long ccxts_block_size(const struct ccmode_xts *mode)
324{
325	return mode->block_size;
326}
327
328CC_INLINE void ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx,
329                          size_t key_len, const void *key,
330                          const void *tweak_key)
331{
332    mode->init(mode, ctx, key_len, key, tweak_key);
333}
334
335CC_INLINE void ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx,
336                               ccxts_tweak *tweak, const void *iv)
337{
338	mode->set_tweak(ctx, tweak, iv);
339}
340
341CC_INLINE void *ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx,
342	ccxts_tweak *tweak, unsigned long nblocks, const void *in, void *out)
343{
344	return mode->xts(ctx, tweak, nblocks, in, out);
345}
346
347CC_INLINE void ccxts_one_shot(const struct ccmode_xts *mode,
348                              size_t key_len, const void *key,
349                              const void *tweak_key, const void *iv,
350                              unsigned long nblocks, const void *in, void *out)
351{
352	ccxts_ctx_decl(mode->size, ctx);
353    ccxts_tweak_decl(mode->tweak_size, tweak);
354	mode->init(mode, ctx, key_len, key, tweak_key);
355    mode->set_tweak(ctx, tweak, iv);
356	mode->xts(ctx, tweak, nblocks, in, out);
357	ccxts_ctx_clear(mode->size, ctx);
358    ccxts_tweak_clear(mode->tweak_size, tweak);
359}
360
361/* GCM mode. */
362
363/* Declare a gcm key named _name_.  Pass the size field of a struct ccmode_gcm
364 for _size_. */
365#define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_)
366#define ccgcm_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
367
368CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
369{
370    return mode->size;
371}
372
373CC_INLINE unsigned long ccgcm_block_size(const struct ccmode_gcm *mode)
374{
375	return mode->block_size;
376}
377
378CC_INLINE void ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
379                          size_t key_len, const void *key)
380{
381    mode->init(mode, ctx, key_len, key);
382}
383
384CC_INLINE void ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
385                            size_t iv_size, const void *iv)
386{
387	mode->set_iv(ctx, iv_size, iv);
388}
389
390CC_INLINE void ccgcm_gmac(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
391                          size_t nbytes, const void *in)
392{
393	mode->gmac(ctx, nbytes, in);
394}
395
396CC_INLINE void ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
397                            size_t nbytes, const void *in, void *out)
398{
399	mode->gcm(ctx, nbytes, in, out);
400}
401
402CC_INLINE void ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx,
403                              size_t tag_size, void *tag)
404{
405	mode->finalize(ctx, tag_size, tag);
406}
407
408CC_INLINE void ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
409{
410    mode->reset(ctx);
411}
412
413
414CC_INLINE void ccgcm_one_shot(const struct ccmode_gcm *mode,
415                              size_t key_len, const void *key,
416                              size_t iv_len, const void *iv,
417                              size_t adata_len, const void *adata,
418                              size_t nbytes, const void *in, void *out,
419                              size_t tag_len, void *tag)
420{
421	ccgcm_ctx_decl(mode->size, ctx);
422	mode->init(mode, ctx, key_len, key);
423	mode->set_iv(ctx, iv_len, iv);
424	mode->gmac(ctx, adata_len, adata);
425	mode->gcm(ctx, nbytes, in, out);
426	mode->finalize(ctx, tag_len, tag);
427	ccgcm_ctx_clear(mode->size, ctx);
428}
429
430/* CCM */
431
432#define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
433#define ccccm_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
434
435/* Declare a ccm nonce named _name_.  Pass the mode->nonce_ctx_size for _size_. */
436#define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl(ccccm_nonce, _size_, _name_)
437#define ccccm_nonce_clear(_size_, _name_) cc_zero(_size_, _name_)
438
439
440CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
441{
442    return mode->size;
443}
444
445CC_INLINE unsigned long ccccm_block_size(const struct ccmode_ccm *mode)
446{
447	return mode->block_size;
448}
449
450CC_INLINE void ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx,
451                          size_t key_len, const void *key)
452{
453    mode->init(mode, ctx, key_len, key);
454}
455
456CC_INLINE void ccccm_set_iv(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
457                            size_t nonce_len, const void *nonce,
458                            size_t mac_size, size_t auth_len, size_t data_len)
459{
460	mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
461}
462
463CC_INLINE void ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
464                          size_t nbytes, const void *in)
465{
466	mode->cbcmac(ctx, nonce_ctx, nbytes, in);
467}
468
469CC_INLINE void ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
470                            size_t nbytes, const void *in, void *out)
471{
472	mode->ccm(ctx, nonce_ctx, nbytes, in, out);
473}
474
475CC_INLINE void ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx,
476                              void *mac)
477{
478	mode->finalize(ctx, nonce_ctx, mac);
479}
480
481CC_INLINE void ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
482{
483    mode->reset(ctx, nonce_ctx);
484}
485
486
487CC_INLINE void ccccm_one_shot(const struct ccmode_ccm *mode,
488                              unsigned long key_len, const void *key,
489                              unsigned nonce_len, const void *nonce,
490                              unsigned long nbytes, const void *in, void *out,
491                              unsigned adata_len, const void* adata,
492                              unsigned mac_size, void *mac)
493{
494	ccccm_ctx_decl(mode->size, ctx);
495	ccccm_nonce_decl(mode->nonce_size, nonce_ctx);
496	mode->init(mode, ctx, key_len, key);
497	mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
498	mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
499	mode->ccm(ctx, nonce_ctx, nbytes, in, out);
500	mode->finalize(ctx, nonce_ctx, mac);
501	ccccm_ctx_clear(mode->size, ctx);
502    ccccm_nonce_clear(mode->size, nonce_ctx);
503}
504
505
506/* OMAC mode. */
507
508
509/* Declare a omac key named _name_.  Pass the size field of a struct ccmode_omac
510 for _size_. */
511#define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
512#define ccomac_ctx_clear(_size_, _name_) cc_zero(_size_, _name_)
513
514CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
515{
516    return mode->size;
517}
518
519CC_INLINE unsigned long ccomac_block_size(const struct ccmode_omac *mode)
520{
521	return mode->block_size;
522}
523
524CC_INLINE void ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx,
525                           size_t tweak_len, size_t key_len, const void *key)
526{
527    return mode->init(mode, ctx, tweak_len, key_len, key);
528}
529
530CC_INLINE int ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx,
531	unsigned long nblocks, const void *tweak, const void *in, void *out)
532{
533	return mode->omac(ctx, nblocks, tweak, in, out);
534}
535
536CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
537	size_t tweak_len, size_t key_len, const void *key,
538	const void *tweak, unsigned long nblocks, const void *in, void *out)
539{
540	ccomac_ctx_decl(mode->size, ctx);
541	mode->init(mode, ctx, tweak_len, key_len, key);
542	int result = mode->omac(ctx, nblocks, tweak, in, out);
543	ccomac_ctx_clear(mode->size, ctx);
544    return result;
545}
546
547
548#endif /* _CORECRYPTO_CCMODE_H_ */
549