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