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