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_ctx_clear(ccecb_ctx, _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 unsigned long 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 in_len, const void *in, void *out) 41{ 42 unsigned long numBlocks = (in_len / mode->block_size); 43 mode->ecb(ctx, numBlocks, in, out); 44} 45 46CC_INLINE void ccecb_one_shot(const struct ccmode_ecb *mode, 47 unsigned long key_len, const void *key, unsigned long in_len, 48 const void *in, void *out) 49{ 50 unsigned long numBlocks = (in_len / mode->block_size); 51 ccecb_ctx_decl(mode->size, ctx); 52 mode->init(mode, ctx, key_len, key); 53 mode->ecb(ctx, numBlocks, in, out); 54 ccecb_ctx_clear(mode->size, ctx); 55} 56 57/* CBC mode. */ 58 59/* The CBC interface changed due to rdar://11468135. This macros is to indicate 60 to client which CBC API is implemented. Clients can support old versions of 61 corecrypto at build time using this. 62 */ 63#define __CC_HAS_FIX_FOR_11468135__ 1 64 65/* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc 66 for _size_. */ 67#define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_) 68#define cccbc_ctx_clear(_size_, _name_) cc_ctx_clear(cccbc_ctx, _size_, _name_) 69 70/* Declare a cbc iv tweak named _name_. Pass the blocksize field of a struct ccmode_cbc 71 for _size_. */ 72#define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_) 73#define cccbc_iv_clear(_size_, _name_) cc_ctx_clear(cccbc_iv, _size_, _name_) 74 75/* Actual symmetric algorithm implementation can provide you one of these. 76 77 Alternatively you can create a ccmode_cbc instance from any ccmode_ecb 78 cipher. To do so, statically initialize a struct ccmode_cbc using the 79 CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros. Alternatively 80 you can dynamically initialize a struct ccmode_cbc ccmode_factory_cbc_decrypt() 81 or ccmode_factory_cbc_encrypt(). */ 82 83CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode) 84{ 85 return mode->size; 86} 87 88CC_INLINE unsigned long cccbc_block_size(const struct ccmode_cbc *mode) 89{ 90 return mode->block_size; 91} 92 93CC_INLINE void cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx, 94 unsigned long key_len, const void *key) 95{ 96 mode->init(mode, ctx, key_len, key); 97} 98 99CC_INLINE void cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx, const void *iv) 100{ 101 if(iv) 102 cc_copy(mode->block_size, iv_ctx, iv); 103 else 104 cc_zero(mode->block_size, iv_ctx); 105} 106 107CC_INLINE void cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx, cccbc_iv *iv, 108 unsigned long nblocks, 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, const void *iv, unsigned long nblocks, 115 const void *in, void *out) 116{ 117 cccbc_ctx_decl(mode->size, ctx); 118 cccbc_iv_decl(mode->block_size, iv_ctx); 119 mode->init(mode, ctx, key_len, key); 120 if(iv) 121 cccbc_set_iv (mode, iv_ctx, iv); 122 else 123 cc_zero(mode->block_size, iv_ctx); 124 mode->cbc(ctx, iv_ctx, nblocks, in, out); 125 cccbc_ctx_clear(mode->size, ctx); 126} 127 128/* CFB mode. */ 129 130/* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb 131 for _size_. */ 132#define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_) 133#define cccfb_ctx_clear(_size_, _name_) cc_ctx_clear(cccfb_ctx, _size_, _name_) 134 135CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode) 136{ 137 return mode->size; 138} 139 140CC_INLINE unsigned long cccfb_block_size(const struct ccmode_cfb *mode) 141{ 142 return mode->block_size; 143} 144 145CC_INLINE void cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx, 146 unsigned long key_len, const void *key, const void *iv) 147{ 148 mode->init(mode, ctx, key_len, key, iv); 149} 150 151CC_INLINE void cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx, 152 unsigned long in_len, const void *in, void *out) 153{ 154 mode->cfb(ctx, in_len, in, out); 155} 156 157CC_INLINE void cccfb_one_shot(const struct ccmode_cfb *mode, 158 unsigned long key_len, const void *key, const void *iv, 159 unsigned long in_len, const void *in, void *out) 160{ 161 cccfb_ctx_decl(mode->size, ctx); 162 mode->init(mode, ctx, key_len, key, iv); 163 mode->cfb(ctx, in_len, in, out); 164 cccfb_ctx_clear(mode->size, ctx); 165} 166 167/* CFB8 mode. */ 168 169/* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8 170 for _size_. */ 171#define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_) 172#define cccfb8_ctx_clear(_size_, _name_) cc_ctx_clear(cccfb8_ctx, _size_, _name_) 173 174CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode) 175{ 176 return mode->size; 177} 178 179CC_INLINE unsigned long cccfb8_block_size(const struct ccmode_cfb8 *mode) 180{ 181 return mode->block_size; 182} 183 184CC_INLINE void cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, 185 unsigned long key_len, const void *key, const void *iv) 186{ 187 mode->init(mode, ctx, key_len, key, iv); 188} 189 190CC_INLINE void cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, 191 unsigned long in_len, const void *in, void *out) 192{ 193 mode->cfb8(ctx, in_len, in, out); 194} 195 196CC_INLINE void cccfb8_one_shot(const struct ccmode_cfb8 *mode, 197 unsigned long key_len, const void *key, const void *iv, 198 unsigned long in_len, const void *in, void *out) 199{ 200 cccfb8_ctx_decl(mode->size, ctx); 201 mode->init(mode, ctx, key_len, key, iv); 202 mode->cfb8(ctx, in_len, in, out); 203 cccfb8_ctx_clear(mode->size, ctx); 204} 205 206/* CTR mode. */ 207 208/* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr 209 for _size_. */ 210#define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_) 211#define ccctr_ctx_clear(_size_, _name_) cc_ctx_clear(ccctr_ctx, _size_, _name_) 212 213/* This is Integer Counter Mode: The IV is the initial value of the counter 214 that is incremented by 1 for each new block. Use the mode flags to select 215 if the IV/Counter is stored in big or little endian. */ 216 217CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode) 218{ 219 return mode->size; 220} 221 222CC_INLINE unsigned long ccctr_block_size(const struct ccmode_ctr *mode) 223{ 224 return mode->block_size; 225} 226 227CC_INLINE void ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx, 228 unsigned long key_len, const void *key, const void *iv) 229{ 230 mode->init(mode, ctx, key_len, key, iv); 231} 232 233CC_INLINE void ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx, 234 unsigned long in_len, const void *in, void *out) 235{ 236 unsigned long numBlocks = (in_len / mode->block_size); 237 mode->ctr(ctx, numBlocks, in, out); 238} 239 240CC_INLINE void ccctr_one_shot(const struct ccmode_ctr *mode, 241 unsigned long key_len, const void *key, const void *iv, 242 unsigned long in_len, const void *in, void *out) 243{ 244 unsigned long numBlocks = (in_len / mode->block_size); 245 ccctr_ctx_decl(mode->size, ctx); 246 mode->init(mode, ctx, key_len, key, iv); 247 mode->ctr(ctx, numBlocks, 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_ctx_clear(ccofb_ctx, _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 unsigned long 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 unsigned long in_len, const void *in, void *out) 277{ 278 mode->ofb(ctx, in_len, in, out); 279} 280 281CC_INLINE void ccofb_one_shot(const struct ccmode_ofb *mode, 282 unsigned long key_len, const void *key, const void *iv, 283 unsigned long in_len, 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, in_len, 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_ctx_clear(ccxts_ctx, _size_, _name_) 299 300/* Declare a xts tweak named _name_. Pass the tweak_size field of a struct ccmode_xts 301 for _size_. */ 302#define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_) 303#define ccxts_tweak_clear(_size_, _name_) cc_ctx_clear(ccxts_tweak, _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 ccmode_factory_xts_decrypt() 311 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 unsigned long key_len, const void *key, const void *tweak_key) 330{ 331 mode->init(mode, ctx, key_len, key, tweak_key); 332} 333 334CC_INLINE void ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv) 335{ 336 mode->set_tweak(ctx, tweak, iv); 337} 338 339CC_INLINE void *ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx, 340 ccxts_tweak *tweak, unsigned long in_len, const void *in, void *out) 341{ 342 return mode->xts(ctx, tweak, in_len, in, out); 343} 344 345CC_INLINE void ccxts_one_shot(const struct ccmode_xts *mode, 346 unsigned long key_len, const void *key, const void *tweak_key, 347 const void* iv, 348 unsigned long in_len, const void *in, void *out) 349{ 350 ccxts_ctx_decl(mode->size, ctx); 351 ccxts_tweak_decl(mode->tweak_size, tweak); 352 mode->init(mode, ctx, key_len, key, tweak_key); 353 mode->set_tweak(ctx, tweak, iv); 354 mode->xts(ctx, tweak, in_len, in, out); 355 ccxts_ctx_clear(mode->size, ctx); 356 ccxts_tweak_clear(mode->tweak_size, tweak); 357} 358 359/* GCM mode. */ 360 361/* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm 362 for _size_. */ 363#define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_) 364#define ccgcm_ctx_clear(_size_, _name_) cc_ctx_clear(ccgcm_ctx, _size_, _name_) 365 366CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode) 367{ 368 return mode->size; 369} 370 371CC_INLINE unsigned long ccgcm_block_size(const struct ccmode_gcm *mode) 372{ 373 return mode->block_size; 374} 375 376CC_INLINE void ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, 377 unsigned long key_len, const void *key) 378{ 379 mode->init(mode, ctx, key_len, key); 380} 381 382CC_INLINE void ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_size, const void *iv) 383{ 384 mode->set_iv(ctx, iv_size, iv); 385} 386 387CC_INLINE void ccgcm_gmac(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, 388 unsigned long nbytes, const void *in) 389{ 390 mode->gmac(ctx, nbytes, in); 391} 392 393CC_INLINE void ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, 394 unsigned long nbytes, const void *in, void *out) 395{ 396 mode->gcm(ctx, nbytes, in, out); 397} 398 399CC_INLINE void ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, 400 size_t tag_size, void *tag) 401{ 402 mode->finalize(ctx, tag_size, tag); 403} 404 405CC_INLINE void ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx) 406{ 407 mode->reset(ctx); 408} 409 410 411CC_INLINE void ccgcm_one_shot(const struct ccmode_gcm *mode, 412 unsigned long key_len, const void *key, 413 unsigned long iv_len, const void *iv, 414 unsigned long nbytes, const void *in, void *out, 415 unsigned long adata_len, const void* adata, 416 size_t tag_len, void *tag) 417{ 418 ccgcm_ctx_decl(mode->size, ctx); 419 mode->init(mode, ctx, key_len, key); 420 mode->set_iv(ctx, iv_len, iv); 421 mode->gmac(ctx, adata_len, adata); 422 mode->gcm(ctx, nbytes, in, out); 423 mode->finalize(ctx, tag_len, tag); 424 ccgcm_ctx_clear(mode->size, ctx); 425} 426 427/* OMAC mode. */ 428 429 430/* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac 431 for _size_. */ 432#define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_) 433#define ccomac_ctx_clear(_size_, _name_) cc_ctx_clear(ccomac_ctx, _size_, _name_) 434 435CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode) 436{ 437 return mode->size; 438} 439 440CC_INLINE unsigned long ccomac_block_size(const struct ccmode_omac *mode) 441{ 442 return mode->block_size; 443} 444 445CC_INLINE void ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx, 446 unsigned long tweak_len, unsigned long key_len, const void *key) 447{ 448 return mode->init(mode, ctx, tweak_len, key_len, key); 449} 450 451CC_INLINE int ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx, 452 unsigned long in_len, const void *tweak, const void *in, void *out) 453{ 454 return mode->omac(ctx, in_len, tweak, in, out); 455} 456 457CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode, 458 unsigned long tweak_len, unsigned long key_len, const void *key, 459 const void *tweak, unsigned long in_len, const void *in, void *out) 460{ 461 ccomac_ctx_decl(mode->size, ctx); 462 mode->init(mode, ctx, tweak_len, key_len, key); 463 int result = mode->omac(ctx, in_len, tweak, in, out); 464 ccomac_ctx_clear(mode->size, ctx); 465 return result; 466} 467 468 469#endif /* _CORECRYPTO_CCMODE_H_ */ 470