1/*
2 *  ccmode_factory.h
3 *  corecrypto
4 *
5 *  Created by Fabrice Gautier on 1/21/11.
6 *  Copyright 2011 Apple, Inc. All rights reserved.
7 *
8 */
9
10#ifndef _CORECRYPTO_CCMODE_FACTORY_H_
11#define _CORECRYPTO_CCMODE_FACTORY_H_
12
13#include <corecrypto/ccn.h>  /* TODO: Remove dependancy on this header. */
14#include <corecrypto/ccmode_impl.h>
15
16/* For CBC, direction of underlying ecb is the same as the cbc direction */
17#define CCMODE_CBC_FACTORY(_cipher_, _dir_)                                     \
18static struct ccmode_cbc cbc_##_cipher_##_##_dir_;                              \
19                                                                                \
20const struct ccmode_cbc *cc##_cipher_##_cbc_##_dir_##_mode(void)                \
21{                                                                               \
22    const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_##_dir_##_mode();           \
23    ccmode_factory_cbc_##_dir_(&cbc_##_cipher_##_##_dir_, ecb);                 \
24    return &cbc_##_cipher_##_##_dir_;                                           \
25}
26
27/* For CTR, only one direction, underlying ecb is always encrypt */
28#define CCMODE_CTR_FACTORY(_cipher_)                                            \
29static struct ccmode_ctr ctr_##_cipher_;                                        \
30                                                                                \
31const struct ccmode_ctr *cc##_cipher_##_ctr_crypt_mode(void)                    \
32{                                                                               \
33    const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode();             \
34    ccmode_factory_ctr_crypt(&ctr_##_cipher_, ecb);                             \
35    return &ctr_##_cipher_;                                                     \
36}
37
38/* OFB, same as CTR */
39#define CCMODE_OFB_FACTORY(_cipher_)                                            \
40static struct ccmode_ofb ofb_##_cipher_;                                        \
41                                                                                \
42const struct ccmode_ofb *cc##_cipher_##_ofb_crypt_mode(void)                    \
43{                                                                               \
44    const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode();             \
45    ccmode_factory_ofb_crypt(&ofb_##_cipher_, ecb);                             \
46    return &ofb_##_cipher_;                                                     \
47}
48
49
50/* For CFB, the underlying ecb operation is encrypt for both directions */
51#define CCMODE_CFB_FACTORY(_cipher_, _mode_, _dir_)                             \
52static struct ccmode_##_mode_ _mode_##_##_cipher_##_##_dir_;                    \
53                                                                                \
54const struct ccmode_##_mode_ *cc##_cipher_##_##_mode_##_##_dir_##_mode(void)    \
55{                                                                               \
56    const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode();             \
57    ccmode_factory_##_mode_##_##_dir_(&_mode_##_##_cipher_##_##_dir_, ecb);     \
58    return &_mode_##_##_cipher_##_##_dir_;                                      \
59}
60
61/* For GCM, same as CFB */
62#define CCMODE_GCM_FACTORY(_cipher_, _dir_) CCMODE_CFB_FACTORY(_cipher_, gcm, _dir_)
63
64
65/* Fot XTS, you always need an ecb encrypt */
66#define CCMODE_XTS_FACTORY(_cipher_ , _dir_)                                    \
67static struct ccmode_xts xts##_cipher_##_##_dir_;                               \
68                                                                                \
69const struct ccmode_xts *cc##_cipher_##_xts_##_dir_##_mode(void)                \
70{                                                                               \
71    const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_##_dir_##_mode();           \
72    const struct ccmode_ecb *ecb_enc=cc##_cipher_##_ecb_encrypt_mode();         \
73                                                                                \
74    ccmode_factory_xts_##_dir_(&xts##_cipher_##_##_dir_, ecb, ecb_enc);         \
75    return &xts##_cipher_##_##_dir_;                                            \
76}
77
78#if 0
79
80/* example of how to make the selection function thread safe */
81
82struct ccmode_cbc cc3des_cbc_mode_encrypt;
83dispatch_once_t cc3des_mode_encrypt_init_once;
84
85void cc3des_mode_encrypt_init(void *ctx) {
86    struct ccmode_ecb *ecb = cc3des_ecb_encrypt_mode();
87    ccmode_factory_cbc_encrypt(&cc3des_mode_encrypt, ecb);
88}
89
90const struct ccmode_cbc *cc3des_cbc_encrypt_mode(void) {
91    dispatch_once_f(&cc3des_mode_encrypt_init_once, NULL, cc3des_mode_encrypt_init);
92    return &cc3des_mode_encrypt;
93}
94
95struct ccmode_cbc cc3des_cbc_mode_encrypt = {
96    .n = CC3DES_LTC_ECB_ENCRYPT_N,
97    .init = ccmode_cbc_init,
98    .cbc = ccmode_cbc_encrypt,
99    .custom = &cc3des_ltc_ecb_encrypt
100};
101
102const struct ccmode_cbc *cc3des_cbc_encrypt_mode(void) {
103    return &cc3des_mode_encrypt;
104}
105
106#endif
107
108
109
110void *ccmode_cbc_init(const struct ccmode_cbc *cbc, cccbc_ctx *ctx,
111                      unsigned long rawkey_len, const void *rawkey,
112                      const void *iv);
113void *ccmode_cbc_decrypt(cccbc_ctx *ctx, unsigned long nblocks,
114                         const void *in, void *out);
115void *ccmode_cbc_encrypt(cccbc_ctx *ctx, unsigned long nblocks,
116                         const void *in, void *out);
117
118struct _ccmode_cbc_key {
119    const struct ccmode_ecb *ecb;
120    cc_unit u[];
121};
122
123/* Use this to statically initialize a ccmode_cbc object for decryption. */
124#define CCMODE_FACTORY_CBC_DECRYPT(ECB) { \
125.size = ccn_sizeof_size(sizeof(struct _ccmode_cbc_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
126.block_size = (ECB)->block_size, \
127.init = ccmode_cbc_init, \
128.cbc = ccmode_cbc_decrypt, \
129.custom = (ECB) \
130}
131
132/* Use this to statically initialize a ccmode_cbc object for encryption. */
133#define CCMODE_FACTORY_CBC_ENCRYPT(ECB) { \
134.size = ccn_sizeof_size(sizeof(struct _ccmode_cbc_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
135.block_size = (ECB)->block_size, \
136.init = ccmode_cbc_init, \
137.cbc = ccmode_cbc_encrypt, \
138.custom = (ECB) \
139}
140
141/* Use these function to runtime initialize a ccmode_cbc decrypt object (for
142 example if it's part of a larger structure). Normally you would pass a
143 ecb decrypt mode implementation of some underlying algorithm as the ecb
144 parameter. */
145CC_INLINE
146void ccmode_factory_cbc_decrypt(struct ccmode_cbc *cbc,
147                                const struct ccmode_ecb *ecb) {
148    struct ccmode_cbc cbc_decrypt = CCMODE_FACTORY_CBC_DECRYPT(ecb);
149    *cbc = cbc_decrypt;
150}
151
152/* Use these function to runtime initialize a ccmode_cbc encrypt object (for
153 example if it's part of a larger structure). Normally you would pass a
154 ecb encrypt mode implementation of some underlying algorithm as the ecb
155 parameter. */
156CC_INLINE
157void ccmode_factory_cbc_encrypt(struct ccmode_cbc *cbc,
158                                const struct ccmode_ecb *ecb) {
159    struct ccmode_cbc cbc_encrypt = CCMODE_FACTORY_CBC_ENCRYPT(ecb);
160    *cbc = cbc_encrypt;
161}
162
163
164void ccmode_cfb_init(const struct ccmode_cfb *cfb, cccfb_ctx *ctx,
165                     unsigned long rawkey_len, const void *rawkey,
166                     const void *iv);
167void ccmode_cfb_decrypt(cccfb_ctx *ctx, unsigned long nblocks,
168                        const void *in, void *out);
169void ccmode_cfb_encrypt(cccfb_ctx *ctx, unsigned long nblocks,
170                        const void *in, void *out);
171
172struct _ccmode_cfb_key {
173    const struct ccmode_ecb *ecb;
174    size_t pad_len;
175    cc_unit u[];
176};
177
178/* Use this to statically initialize a ccmode_cfb object for decryption. */
179#define CCMODE_FACTORY_CFB_DECRYPT(ECB) { \
180.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
181.block_size = 1, \
182.init = ccmode_cfb_init, \
183.cfb = ccmode_cfb_decrypt, \
184.custom = (ECB) \
185}
186
187/* Use this to statically initialize a ccmode_cfb object for encryption. */
188#define CCMODE_FACTORY_CFB_ENCRYPT(ECB) { \
189.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
190.block_size = 1, \
191.init = ccmode_cfb_init, \
192.cfb = ccmode_cfb_encrypt, \
193.custom = (ECB) \
194}
195
196/* Use these function to runtime initialize a ccmode_cfb decrypt object (for
197 example if it's part of a larger structure). Normally you would pass a
198 ecb encrypt mode implementation of some underlying algorithm as the ecb
199 parameter. */
200CC_INLINE
201void ccmode_factory_cfb_decrypt(struct ccmode_cfb *cfb,
202                                const struct ccmode_ecb *ecb) {
203    struct ccmode_cfb cfb_decrypt = CCMODE_FACTORY_CFB_DECRYPT(ecb);
204    *cfb = cfb_decrypt;
205}
206
207/* Use these function to runtime initialize a ccmode_cfb encrypt object (for
208 example if it's part of a larger structure). Normally you would pass a
209 ecb encrypt mode implementation of some underlying algorithm as the ecb
210 parameter. */
211CC_INLINE
212void ccmode_factory_cfb_encrypt(struct ccmode_cfb *cfb,
213                             const struct ccmode_ecb *ecb) {
214    struct ccmode_cfb cfb_encrypt = CCMODE_FACTORY_CFB_ENCRYPT(ecb);
215    *cfb = cfb_encrypt;
216}
217
218
219void ccmode_cfb8_init(const struct ccmode_cfb8 *cfb8, cccfb8_ctx *ctx,
220                      unsigned long rawkey_len, const void *rawkey,
221                      const void *iv);
222void ccmode_cfb8_decrypt(cccfb8_ctx *ctx, unsigned long nbytes,
223                         const void *in, void *out);
224void ccmode_cfb8_encrypt(cccfb8_ctx *ctx, unsigned long nbytes,
225                         const void *in, void *out);
226
227struct _ccmode_cfb8_key {
228    const struct ccmode_ecb *ecb;
229    cc_unit u[];
230};
231
232/* Use this to statically initialize a ccmode_cfb8 object for decryption. */
233#define CCMODE_FACTORY_CFB8_DECRYPT(ECB) { \
234.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb8_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
235.block_size = 1, \
236.init = ccmode_cfb8_init, \
237.cfb8 = ccmode_cfb8_decrypt, \
238.custom = (ECB) \
239}
240
241/* Use this to statically initialize a ccmode_cfb8 object for encryption. */
242#define CCMODE_FACTORY_CFB8_ENCRYPT(ECB) { \
243.size = ccn_sizeof_size(sizeof(struct _ccmode_cfb8_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
244.block_size = 1, \
245.init = ccmode_cfb8_init, \
246.cfb8 = ccmode_cfb8_encrypt, \
247.custom = (ECB) \
248}
249
250/* Use these function to runtime initialize a ccmode_cfb8 decrypt object (for
251 example if it's part of a larger structure). Normally you would pass a
252 ecb decrypt mode implementation of some underlying algorithm as the ecb
253 parameter. */
254CC_INLINE
255void ccmode_factory_cfb8_decrypt(struct ccmode_cfb8 *cfb8,
256                              const struct ccmode_ecb *ecb) {
257    struct ccmode_cfb8 cfb8_decrypt = CCMODE_FACTORY_CFB8_DECRYPT(ecb);
258    *cfb8 = cfb8_decrypt;
259}
260
261/* Use these function to runtime initialize a ccmode_cfb8 encrypt object (for
262 example if it's part of a larger structure). Normally you would pass a
263 ecb encrypt mode implementation of some underlying algorithm as the ecb
264 parameter. */
265CC_INLINE
266void ccmode_factory_cfb8_encrypt(struct ccmode_cfb8 *cfb8,
267                              const struct ccmode_ecb *ecb) {
268    struct ccmode_cfb8 cfb8_encrypt = CCMODE_FACTORY_CFB8_ENCRYPT(ecb);
269    *cfb8 = cfb8_encrypt;
270}
271
272void ccmode_ctr_init(const struct ccmode_ctr *ctr, ccctr_ctx *ctx,
273                     unsigned long rawkey_len, const void *rawkey,
274                     const void *iv);
275void ccmode_ctr_crypt(ccctr_ctx *ctx, unsigned long nblocks,
276                      const void *in, void *out);
277
278struct _ccmode_ctr_key {
279    const struct ccmode_ecb *ecb;
280    size_t pad_len;
281    cc_unit u[];
282};
283
284/* Use this to statically initialize a ccmode_ctr object for decryption. */
285#define CCMODE_FACTORY_CTR_CRYPT(ECB_ENCRYPT) { \
286.size = ccn_sizeof_size(sizeof(struct _ccmode_ctr_key)) + 2 * ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \
287.block_size = 1, \
288.init = ccmode_ctr_init, \
289.ctr = ccmode_ctr_crypt, \
290.custom = (ECB_ENCRYPT) \
291}
292
293/* Use these function to runtime initialize a ccmode_ctr decrypt object (for
294 example if it's part of a larger structure). Normally you would pass a
295 ecb encrypt mode implementation of some underlying algorithm as the ecb
296 parameter. */
297CC_INLINE
298void ccmode_factory_ctr_crypt(struct ccmode_ctr *ctr,
299                             const struct ccmode_ecb *ecb) {
300    struct ccmode_ctr ctr_crypt = CCMODE_FACTORY_CTR_CRYPT(ecb);
301    *ctr = ctr_crypt;
302}
303
304/* GCM FEATURES. */
305//#define CCMODE_GCM_TABLES  1
306#define CCMODE_GCM_FAST  1
307
308#ifdef CCMODE_GCM_FAST
309#define CCMODE_GCM_FAST_TYPE cc_unit
310#endif
311
312#ifdef CCMODE_GCM_TABLES
313
314//#define CCMODE_GCM_TABLES_SSE2  1
315
316extern const unsigned char gcm_shift_table[256*2];
317#endif
318
319/* Create a gcm key from a gcm mode object.
320 key must point to at least sizeof(CCMODE_GCM_KEY(ecb)) bytes of free
321 storage. */
322void ccmode_gcm_init(const struct ccmode_gcm *gcm, ccgcm_ctx *ctx,
323                     unsigned long rawkey_len, const void *rawkey);
324void ccmode_gcm_set_iv(ccgcm_ctx *ctx, size_t iv_size, const void *iv);
325void ccmode_gcm_gmac(ccgcm_ctx *ctx, unsigned long nbytes, const void *in);
326void ccmode_gcm_decrypt(ccgcm_ctx *ctx, unsigned long nbytes, const void *in,
327                        void *out);
328void ccmode_gcm_encrypt(ccgcm_ctx *ctx, unsigned long nbytes, const void *in,
329                        void *out);
330void ccmode_gcm_finalize(ccgcm_ctx *key, size_t tag_size, void *tag);
331void ccmode_gcm_reset(ccgcm_ctx *key);
332
333struct _ccmode_gcm_key {
334    // 5 blocks of temp space.
335    unsigned char H[16];       /* multiplier */
336    unsigned char X[16];       /* accumulator */
337    unsigned char Y[16];       /* counter */
338    unsigned char Y_0[16];     /* initial counter */
339    unsigned char buf[16];      /* buffer for stuff */
340
341    const struct ccmode_ecb *ecb;
342    uint32_t ivmode;       /* Which mode is the IV in? */
343    uint32_t mode;         /* mode the GCM code is in */
344    uint32_t buflen;       /* length of data in buf */
345
346    uint64_t totlen;       /* 64-bit counter used for IV and AAD */
347    uint64_t pttotlen;     /* 64-bit counter for the PT */
348
349#ifdef CCMODE_GCM_TABLES
350    /* TODO: Make table based gcm a separate mode object. */
351    unsigned char       PC[16][256][16]  /* 16 tables of 8x128 */
352#ifdef CCMODE_GCM_TABLES_SSE2
353    __attribute__ ((aligned (16)))
354#endif /* CCMODE_GCM_TABLES_SSE2 */
355    ;
356#endif /* CCMODE_GCM_TABLES */
357
358    cc_unit u[];
359};
360
361/* Use this to statically initialize a ccmode_gcm object for decryption. */
362#define CCMODE_FACTORY_GCM_DECRYPT(ECB_ENCRYPT) { \
363.size = ccn_sizeof_size(sizeof(struct _ccmode_gcm_key)) + 5 * ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \
364.block_size = 1, \
365.init = ccmode_gcm_init, \
366.set_iv = ccmode_gcm_set_iv, \
367.gmac = ccmode_gcm_gmac, \
368.gcm = ccmode_gcm_decrypt, \
369.finalize = ccmode_gcm_finalize, \
370.reset = ccmode_gcm_reset, \
371.custom = (ECB_ENCRYPT) \
372}
373
374/* Use this to statically initialize a ccmode_gcm object for encryption. */
375#define CCMODE_FACTORY_GCM_ENCRYPT(ECB_ENCRYPT) { \
376.size = ccn_sizeof_size(sizeof(struct _ccmode_gcm_key)) + 5 * ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \
377.block_size = 1, \
378.init = ccmode_gcm_init, \
379.set_iv = ccmode_gcm_set_iv, \
380.gmac = ccmode_gcm_gmac, \
381.gcm = ccmode_gcm_encrypt, \
382.finalize = ccmode_gcm_finalize, \
383.reset = ccmode_gcm_reset, \
384.custom = (ECB_ENCRYPT) \
385}
386
387/* Use these function to runtime initialize a ccmode_gcm decrypt object (for
388 example if it's part of a larger structure). For GCM you always pass a
389 ecb encrypt mode implementation of some underlying algorithm as the ecb
390 parameter. */
391CC_INLINE
392void ccmode_factory_gcm_decrypt(struct ccmode_gcm *gcm,
393                             const struct ccmode_ecb *ecb_encrypt) {
394    struct ccmode_gcm gcm_decrypt = CCMODE_FACTORY_GCM_DECRYPT(ecb_encrypt);
395    *gcm = gcm_decrypt;
396}
397
398/* Use these function to runtime initialize a ccmode_gcm encrypt object (for
399 example if it's part of a larger structure). For GCM you always pass a
400 ecb encrypt mode implementation of some underlying algorithm as the ecb
401 parameter. */
402CC_INLINE
403void ccmode_factory_gcm_encrypt(struct ccmode_gcm *gcm,
404                             const struct ccmode_ecb *ecb_encrypt) {
405    struct ccmode_gcm gcm_encrypt = CCMODE_FACTORY_GCM_ENCRYPT(ecb_encrypt);
406    *gcm = gcm_encrypt;
407}
408
409
410void ccmode_ofb_init(const struct ccmode_ofb *ofb, ccofb_ctx *ctx,
411                     unsigned long rawkey_len, const void *rawkey,
412                     const void *iv);
413void ccmode_ofb_crypt(ccofb_ctx *ctx, unsigned long nblocks,
414                      const void *in, void *out);
415
416struct _ccmode_ofb_key {
417    const struct ccmode_ecb *ecb;
418    size_t pad_len;
419    cc_unit u[];
420};
421
422/* Use this to statically initialize a ccmode_ofb object. */
423#define CCMODE_FACTORY_OFB_CRYPT(ECB) { \
424.size = ccn_sizeof_size(sizeof(struct _ccmode_ofb_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \
425.block_size = 1, \
426.init = ccmode_ofb_init, \
427.ofb = ccmode_ofb_crypt, \
428.custom = (ECB) \
429}
430
431/* Use these function to runtime initialize a ccmode_ofb encrypt object (for
432 example if it's part of a larger structure). Normally you would pass a
433 ecb encrypt mode implementation of some underlying algorithm as the ecb
434 parameter. */
435CC_INLINE
436void ccmode_factory_ofb_crypt(struct ccmode_ofb *ofb,
437                             const struct ccmode_ecb *ecb) {
438    struct ccmode_ofb ofb_crypt = CCMODE_FACTORY_OFB_CRYPT(ecb);
439    *ofb = ofb_crypt;
440}
441
442
443int ccmode_omac_decrypt(ccomac_ctx *ctx, unsigned long nblocks,
444                        const void *tweak, const void *in, void *out);
445int ccmode_omac_encrypt(ccomac_ctx *ctx, unsigned long nblocks,
446                        const void *tweak, const void *in, void *out);
447
448/* Create a omac key from a omac mode object.  The tweak_len here
449 determines how long the tweak is in bytes, for each subsequent call to
450 ccmode_omac->omac().
451 key must point to at least sizeof(CCMODE_OMAC_KEY(ecb)) bytes of free
452 storage. */
453void ccmode_omac_init(const struct ccmode_omac *omac, ccomac_ctx *ctx,
454                      cc_size tweak_len, unsigned long rawkey_len,
455                      const void *rawkey);
456
457struct _ccmode_omac_key {
458    const struct ccmode_ecb *ecb;
459    size_t tweak_len;
460    cc_unit u[];
461};
462
463/* Use this to statically initialize a ccmode_omac object for decryption. */
464#define CCMODE_FACTORY_OMAC_DECRYPT(ECB) { \
465.size = ccn_sizeof_size(sizeof(struct _ccmode_omac_key)) + 2 * ccn_sizeof_size((ECB)->size), \
466.block_size = (ECB)->block_size, \
467.init = ccmode_omac_init, \
468.omac = ccmode_omac_decrypt, \
469.custom = (ECB) \
470}
471
472/* Use this to statically initialize a ccmode_omac object for encryption. */
473#define CCMODE_FACTORY_OMAC_ENCRYPT(ECB) { \
474.size = ccn_sizeof_size(sizeof(struct _ccmode_omac_key)) + 2 * ccn_sizeof_size((ECB)->size), \
475.block_size = (ECB)->block_size, \
476.init = ccmode_omac_init, \
477.omac = ccmode_omac_encrypt, \
478.custom = (ECB) \
479}
480
481/* Use these function to runtime initialize a ccmode_omac decrypt object (for
482 example if it's part of a larger structure). Normally you would pass a
483 ecb decrypt mode implementation of some underlying algorithm as the ecb
484 parameter. */
485CC_INLINE
486void ccmode_factory_omac_decrypt(struct ccmode_omac *omac,
487                              const struct ccmode_ecb *ecb) {
488    struct ccmode_omac omac_decrypt = CCMODE_FACTORY_OMAC_DECRYPT(ecb);
489    *omac = omac_decrypt;
490}
491
492/* Use these function to runtime initialize a ccmode_omac encrypt object (for
493 example if it's part of a larger structure). Normally you would pass a
494 ecb encrypt mode implementation of some underlying algorithm as the ecb
495 parameter. */
496CC_INLINE
497void ccmode_factory_omac_encrypt(struct ccmode_omac *omac,
498                              const struct ccmode_ecb *ecb) {
499    struct ccmode_omac omac_encrypt = CCMODE_FACTORY_OMAC_ENCRYPT(ecb);
500    *omac = omac_encrypt;
501}
502
503
504/* Function prototypes used by the macros below, do not call directly. */
505void ccmode_xts_init(const struct ccmode_xts *xts, ccxts_ctx *ctx,
506                     unsigned long key_len, const void *data_key,
507                     const void *tweak_key);
508void *ccmode_xts_crypt(ccxts_ctx *ctx, unsigned long nblocks,
509                       const void *in, void *out);
510void ccmode_xts_set_tweak(ccxts_ctx *ctx, const void *tweak);
511
512
513struct _ccmode_xts_key {
514    const struct ccmode_ecb *ecb;
515    const struct ccmode_ecb *ecb_encrypt;
516	// FIPS requires that for XTS that no more that 2^20 AES blocks may be processed for any given
517	// Key, Tweak Key, and tweak combination
518	// the bytes_processed field in the context will accumuate the number of blocks processed and
519	// will fail the encrypt/decrypt if the size is violated.  This counter will be reset to 0
520	// when set_tweak is called.
521	unsigned long  blocks_processed;
522    cc_unit u[];
523};
524
525/* Use this to statically initialize a ccmode_xts object for decryption. */
526#define CCMODE_FACTORY_XTS_DECRYPT(ECB, ECB_ENCRYPT) { \
527.size = ccn_sizeof_size(sizeof(struct _ccmode_xts_key)) + 2 * ccn_sizeof_size((ECB)->size) + ccn_sizeof_size(16), \
528.block_size = 16, \
529.init = ccmode_xts_init, \
530.set_tweak = ccmode_xts_set_tweak, \
531.xts = ccmode_xts_crypt, \
532.custom = (ECB), \
533.custom1 = (ECB_ENCRYPT) \
534}
535
536/* Use this to statically initialize a ccmode_xts object for encryption. */
537#define CCMODE_FACTORY_XTS_ENCRYPT(ECB, ECB_ENCRYPT) { \
538.size = ccn_sizeof_size(sizeof(struct _ccmode_xts_key)) + 2 * ccn_sizeof_size((ECB)->size) + ccn_sizeof_size(16), \
539.block_size = 16, \
540.init = ccmode_xts_init, \
541.set_tweak = ccmode_xts_set_tweak, \
542.xts = ccmode_xts_crypt, \
543.custom = (ECB), \
544.custom1 = (ECB_ENCRYPT) \
545}
546
547/* Use these function to runtime initialize a ccmode_xts decrypt object (for
548 example if it's part of a larger structure). Normally you would pass a
549 ecb decrypt mode implementation of some underlying algorithm as the ecb
550 parameter. */
551CC_INLINE
552void ccmode_factory_xts_decrypt(struct ccmode_xts *xts,
553                             const struct ccmode_ecb *ecb,
554                             const struct ccmode_ecb *ecb_encrypt) {
555    struct ccmode_xts xts_decrypt = CCMODE_FACTORY_XTS_DECRYPT(ecb, ecb_encrypt);
556    *xts = xts_decrypt;
557}
558
559/* Use these function to runtime initialize a ccmode_xts encrypt object (for
560 example if it's part of a larger structure). Normally you would pass a
561 ecb encrypt mode implementation of some underlying algorithm as the ecb
562 parameter. */
563CC_INLINE
564void ccmode_factory_xts_encrypt(struct ccmode_xts *xts,
565                             const struct ccmode_ecb *ecb,
566                             const struct ccmode_ecb *ecb_encrypt) {
567    struct ccmode_xts xts_encrypt = CCMODE_FACTORY_XTS_ENCRYPT(ecb, ecb_encrypt);
568    *xts = xts_encrypt;
569}
570
571#endif /* _CORECRYPTO_CCMODE_FACTORY_H_ */
572