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