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