1/* 2 * Copyright (c) 2012 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include "corecryptoSymmetricBridge.h" 25#include "ccMemory.h" 26#include <corecrypto/ccrc4.h> 27 28static void *noMode(void) { return NULL; } 29 30// RC4 as a mode trick ... 31 32static void rc4ModeInit(const struct ccmode_ofb *ofb, ccofb_ctx *ctx, 33 unsigned long key_len, const void *key, 34 const void *iv) 35{ 36 ccrc4_eay.init((ccrc4_ctx *)ctx, key_len, key); 37} 38 39static void rc4crypt(ccofb_ctx *ctx, unsigned long nbytes, const void *in, void *out) 40{ 41 ccrc4_eay.crypt((ccrc4_ctx *) ctx, nbytes, in, out); 42} 43 44typedef struct eay_rc4_key_st 45{ 46 uint32_t x,y; 47 uint32_t data[256]; 48} eay_RC4_KEY; 49 50static const struct ccmode_ofb rc4mode = { 51 .size = sizeof(eay_RC4_KEY), 52 .block_size = 1, 53 .init = rc4ModeInit, 54 .ofb = rc4crypt, 55}; 56 57 58 59static const struct ccmode_ofb *cc_rc4_crypt_mode(void) 60{ 61 return &rc4mode; 62} 63 64 65// 2 dimensional array of various mode/cipher contexts 66// encrypt/decrypt x algorithm matching the list in CommonCryptor.h 67 68const modeList ccmodeList[CC_SUPPORTED_CIPHERS][CC_DIRECTIONS] = { 69 { // AES 70 { ccaes_ecb_encrypt_mode, ccaes_cbc_encrypt_mode, ccaes_cfb_encrypt_mode, ccaes_cfb8_encrypt_mode, ccaes_ctr_crypt_mode, ccaes_ofb_crypt_mode, ccaes_xts_encrypt_mode, ccaes_gcm_encrypt_mode, ccaes_ccm_encrypt_mode }, 71 { ccaes_ecb_decrypt_mode, ccaes_cbc_decrypt_mode, ccaes_cfb_decrypt_mode, ccaes_cfb8_decrypt_mode, ccaes_ctr_crypt_mode, ccaes_ofb_crypt_mode, ccaes_xts_decrypt_mode, ccaes_gcm_decrypt_mode, ccaes_ccm_decrypt_mode } 72 }, 73 74 { // DES 75 { ccdes_ecb_encrypt_mode, ccdes_cbc_encrypt_mode, ccdes_cfb_encrypt_mode, ccdes_cfb8_encrypt_mode, ccdes_ctr_crypt_mode, ccdes_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode }, 76 { ccdes_ecb_decrypt_mode, ccdes_cbc_decrypt_mode, ccdes_cfb_decrypt_mode, ccdes_cfb8_decrypt_mode, ccdes_ctr_crypt_mode, ccdes_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode } 77 }, 78 79 { // DES3 80 { ccdes3_ecb_encrypt_mode, ccdes3_cbc_encrypt_mode, ccdes3_cfb_encrypt_mode, ccdes3_cfb8_encrypt_mode, ccdes3_ctr_crypt_mode, ccdes3_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode }, 81 { ccdes3_ecb_decrypt_mode, ccdes3_cbc_decrypt_mode, ccdes3_cfb_decrypt_mode, ccdes3_cfb8_decrypt_mode, ccdes3_ctr_crypt_mode, ccdes3_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode } 82 }, 83 84 { // CAST 85 { cccast_ecb_encrypt_mode, cccast_cbc_encrypt_mode, cccast_cfb_encrypt_mode, cccast_cfb8_encrypt_mode, cccast_ctr_crypt_mode, cccast_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode }, 86 { cccast_ecb_decrypt_mode, cccast_cbc_decrypt_mode, cccast_cfb_decrypt_mode, cccast_cfb8_decrypt_mode, cccast_ctr_crypt_mode, cccast_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode } 87 }, 88 89 { // RC4 - hijack OFB to put in streaming cipher descriptor 90 { (ecb_p) noMode, (cbc_p) noMode, (cfb_p) noMode, (cfb8_p) noMode, (ctr_p) noMode, cc_rc4_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode }, 91 { (ecb_p) noMode, (cbc_p) noMode, (cfb_p) noMode, (cfb8_p) noMode, (ctr_p) noMode, cc_rc4_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode }, 92 }, 93 94 95 { // RC2 96 { ccrc2_ecb_encrypt_mode, ccrc2_cbc_encrypt_mode, ccrc2_cfb_encrypt_mode, ccrc2_cfb8_encrypt_mode, ccrc2_ctr_crypt_mode, ccrc2_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode }, 97 { ccrc2_ecb_decrypt_mode, ccrc2_cbc_decrypt_mode, ccrc2_cfb_decrypt_mode, ccrc2_cfb8_decrypt_mode, ccrc2_ctr_crypt_mode, ccrc2_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode } 98 }, 99 100 { // Blowfish 101 { ccblowfish_ecb_encrypt_mode, ccblowfish_cbc_encrypt_mode, ccblowfish_cfb_encrypt_mode, ccblowfish_cfb8_encrypt_mode, ccblowfish_ctr_crypt_mode, ccblowfish_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode }, 102 { ccblowfish_ecb_decrypt_mode, ccblowfish_cbc_decrypt_mode, ccblowfish_cfb_decrypt_mode, ccblowfish_cfb8_decrypt_mode, ccblowfish_ctr_crypt_mode, ccblowfish_ofb_crypt_mode, (xts_p) noMode, (gcm_p) noMode, (ccm_p) noMode } 103 }, 104}; 105 106 107// Thunks 108//ECB 109 110static size_t ccecb_mode_get_ctx_size(corecryptoMode modeObject) { return modeObject.ecb->size; } 111static size_t ccecb_mode_get_block_size(corecryptoMode modeObject) { return modeObject.ecb->block_size; } 112static void ccecb_mode_setup(corecryptoMode modeObj, const void *IV, 113 const void *key, size_t keylen, const void *tweak, 114 size_t tweaklen, int options, modeCtx ctx) 115{ 116 modeObj.ecb->init(modeObj.ecb, ctx.ecb, keylen, key); 117} 118 119static void ccecb_mode_crypt(corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 120{ 121 modeObj.ecb->ecb(ctx.ecb, len / ccecb_mode_get_block_size(modeObj), in, out); 122} 123 124const cc2CCModeDescriptor ccecb_mode = { 125 .mode_get_ctx_size = ccecb_mode_get_ctx_size, 126 .mode_get_block_size = ccecb_mode_get_block_size, 127 .mode_setup = ccecb_mode_setup, 128 .mode_encrypt = ccecb_mode_crypt, 129 .mode_decrypt = ccecb_mode_crypt, 130 .mode_encrypt_tweaked = NULL, 131 .mode_decrypt_tweaked = NULL, 132 .mode_done = NULL, 133 .mode_setiv = NULL, 134 .mode_getiv = NULL 135}; 136 137// CBC 138 139static size_t cccbc_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.cbc->size + 16; } 140static size_t cccbc_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.cbc->block_size; } 141static void cccbc_mode_setup(const corecryptoMode modeObj, const void *iv, 142 const void *key, size_t keylen, const void *tweak, 143 size_t tweaklen, int options, modeCtx ctx) 144{ 145 CC_XMEMCPY(ctx.cbc->iv, iv, modeObj.cbc->block_size); 146 modeObj.cbc->init(modeObj.cbc, &ctx.cbc->cbc, keylen, key); 147} 148 149static void cccbc_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 150{ 151 modeObj.cbc->cbc(&ctx.cbc->cbc, (cccbc_iv *) ctx.cbc->iv, len / cccbc_mode_get_block_size(modeObj), in, out); 152} 153 154static int cccbc_getiv(const corecryptoMode modeObj, void *iv, uint32_t *len, modeCtx ctx) 155{ 156 if(*len < cccbc_mode_get_block_size(modeObj)) { 157 *len = (uint32_t) cccbc_mode_get_block_size(modeObj); 158 return -1; 159 } 160 CC_XMEMCPY(iv, ctx.cbc->iv, *len = (uint32_t) cccbc_mode_get_block_size(modeObj)); 161 return 0; 162} 163 164static int cccbc_setiv(const corecryptoMode modeObj, const void *iv, uint32_t len, modeCtx ctx) 165{ 166 if(len != cccbc_mode_get_block_size(modeObj)) return -1; 167 CC_XMEMCPY(ctx.cbc->iv, iv, cccbc_mode_get_block_size(modeObj)); 168 return 0; 169} 170 171const cc2CCModeDescriptor cccbc_mode = { 172 .mode_get_ctx_size = cccbc_mode_get_ctx_size, 173 .mode_get_block_size = cccbc_mode_get_block_size, 174 .mode_setup = cccbc_mode_setup, 175 .mode_encrypt = cccbc_mode_crypt, 176 .mode_decrypt = cccbc_mode_crypt, 177 .mode_encrypt_tweaked = NULL, 178 .mode_decrypt_tweaked = NULL, 179 .mode_done = NULL, 180 .mode_setiv = cccbc_setiv, 181 .mode_getiv = cccbc_getiv 182}; 183 184// CFB 185 186static size_t cccfb_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.cfb->size; } 187static size_t cccfb_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.cfb->block_size; } 188static void cccfb_mode_setup(const corecryptoMode modeObj, const void *iv, 189 const void *key, size_t keylen, const void *tweak, 190 size_t tweaklen, int options, modeCtx ctx) 191{ 192 modeObj.cfb->init(modeObj.cfb, ctx.cfb, keylen, key, iv); 193} 194 195static void cccfb_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 196{ 197 modeObj.cfb->cfb(ctx.cfb, len / cccfb_mode_get_block_size(modeObj), in, out); 198} 199 200const cc2CCModeDescriptor cccfb_mode = { 201 .mode_get_ctx_size = cccfb_mode_get_ctx_size, 202 .mode_get_block_size = cccfb_mode_get_block_size, 203 .mode_setup = cccfb_mode_setup, 204 .mode_encrypt = cccfb_mode_crypt, 205 .mode_decrypt = cccfb_mode_crypt, 206 .mode_encrypt_tweaked = NULL, 207 .mode_decrypt_tweaked = NULL, 208 .mode_done = NULL, 209 .mode_setiv = NULL, 210 .mode_getiv = NULL 211}; 212 213 214// CFB8 215 216static size_t cccfb8_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.cfb8->size; } 217static size_t cccfb8_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.cfb8->block_size; } 218static void cccfb8_mode_setup(const corecryptoMode modeObj, const void *iv, 219 const void *key, size_t keylen, const void *tweak, 220 size_t tweaklen, int options, modeCtx ctx) 221{ 222 modeObj.cfb8->init(modeObj.cfb8, ctx.cfb8, keylen, key, iv); 223} 224 225static void cccfb8_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 226{ 227 modeObj.cfb8->cfb8(ctx.cfb8, len / cccfb8_mode_get_block_size(modeObj), in, out); 228} 229 230const cc2CCModeDescriptor cccfb8_mode = { 231 .mode_get_ctx_size = cccfb8_mode_get_ctx_size, 232 .mode_get_block_size = cccfb8_mode_get_block_size, 233 .mode_setup = cccfb8_mode_setup, 234 .mode_encrypt = cccfb8_mode_crypt, 235 .mode_decrypt = cccfb8_mode_crypt, 236 .mode_encrypt_tweaked = NULL, 237 .mode_decrypt_tweaked = NULL, 238 .mode_done = NULL, 239 .mode_setiv = NULL, 240 .mode_getiv = NULL 241}; 242 243// CTR 244 245static size_t ccctr_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.ctr->size; } 246static size_t ccctr_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.ctr->block_size; } 247static void ccctr_mode_setup(const corecryptoMode modeObj, const void *iv, 248 const void *key, size_t keylen, const void *tweak, 249 size_t tweaklen, int options, modeCtx ctx) 250{ 251 modeObj.ctr->init(modeObj.ctr, ctx.ctr, keylen, key, iv); 252} 253 254static void ccctr_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 255{ 256 modeObj.ctr->ctr(ctx.ctr, len / ccctr_mode_get_block_size(modeObj), in, out); 257} 258 259const cc2CCModeDescriptor ccctr_mode = { 260 .mode_get_ctx_size = ccctr_mode_get_ctx_size, 261 .mode_get_block_size = ccctr_mode_get_block_size, 262 .mode_setup = ccctr_mode_setup, 263 .mode_encrypt = ccctr_mode_crypt, 264 .mode_decrypt = ccctr_mode_crypt, 265 .mode_encrypt_tweaked = NULL, 266 .mode_decrypt_tweaked = NULL, 267 .mode_done = NULL, 268 .mode_setiv = NULL, 269 .mode_getiv = NULL 270}; 271 272// OFB 273 274static size_t ccofb_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.ofb->size; } 275static size_t ccofb_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.ofb->block_size; } 276static void ccofb_mode_setup(const corecryptoMode modeObj, const void *iv, 277 const void *key, size_t keylen, const void *tweak, 278 size_t tweaklen, int options, modeCtx ctx) 279{ 280 modeObj.ofb->init(modeObj.ofb, ctx.ofb, keylen, key, iv); 281} 282 283static void ccofb_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 284{ 285 modeObj.ofb->ofb(ctx.ofb, len / ccofb_mode_get_block_size(modeObj), in, out); 286} 287 288const cc2CCModeDescriptor ccofb_mode = { 289 .mode_get_ctx_size = ccofb_mode_get_ctx_size, 290 .mode_get_block_size = ccofb_mode_get_block_size, 291 .mode_setup = ccofb_mode_setup, 292 .mode_encrypt = ccofb_mode_crypt, 293 .mode_decrypt = ccofb_mode_crypt, 294 .mode_encrypt_tweaked = NULL, 295 .mode_decrypt_tweaked = NULL, 296 .mode_done = NULL, 297 .mode_setiv = NULL, 298 .mode_getiv = NULL 299}; 300 301// XTS 302/* For now we always schedule both encrypt and decrypt contexts for AES-XTS. Original CommonCrypto support 303 * allowed a "both" (kCCEncrypt and kCCDecrypt) capability used for AES-XTS block I/O. The initialization 304 * and correct mode objext and context passing are done at the CommonCryptor layer. 305 */ 306 307 308static size_t ccxts_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.xts->size; } 309static size_t ccxts_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.xts->block_size; } 310static void ccxts_mode_setup(const corecryptoMode modeObj, const void *iv, 311 const void *key, size_t keylen, const void *tweak, 312 size_t tweaklen, int options, modeCtx ctx) 313{ 314 modeObj.xts->init(modeObj.xts, ctx.xts, keylen, key, tweak); 315} 316 317#ifdef UNUSED_INTERFACE 318static void ccxts_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 319{ 320 modeObj.xts->xts(ctx.xts, len / ccxts_mode_get_block_size(modeObj), in, out); 321} 322 323static int ccxts_setiv(const corecryptoMode modeObj, const void *iv, uint32_t len, modeCtx ctx) 324{ 325 if(len != modeObj.xts->block_size) return -1; 326 modeObj.xts->set_tweak(ctx.xts, iv); 327 return 0; 328} 329 330static int ccxts_getiv(const corecryptoMode modeObj, void *iv, uint32_t *len, modeCtx ctx) 331{ 332 if(*len < modeObj.xts->block_size) { 333 *len = modeObj.xts->block_size; 334 return -1; 335 } 336 CC_XMEMCPY(iv, modeObj.xts->xts(ctx.xts, 0, NULL, NULL), *len = modeObj.xts->block_size); 337 return 0; 338} 339#endif 340 341/* 342 * These match what we had in libtomcrypt - they really are "this is a logical block" routines, so need 343 * to handle partial blocks - so we use corecrypto's xts pad routines in every case. 344 */ 345 346static void ccxts_mode_encrypt_tweak(const corecryptoMode modeObj, const void *in, size_t len, void *out, const void *iv, modeCtx ctx) 347{ 348 ccxts_tweak_decl(ccxts_context_size(modeObj.xts), tweak); 349 modeObj.xts->set_tweak(ctx.xts, tweak, iv); 350 ccpad_xts_encrypt(modeObj.xts, ctx.xts, tweak, len, in, out); 351} 352 353static void ccxts_mode_decrypt_tweak(const corecryptoMode modeObj, const void *in, size_t len, void *out, const void *iv, modeCtx ctx) 354{ 355 ccxts_tweak_decl(ccxts_context_size(modeObj.xts), tweak); 356 modeObj.xts->set_tweak(ctx.xts, tweak, iv); 357 ccpad_xts_decrypt(modeObj.xts, ctx.xts, tweak, len, in, out); 358} 359 360 361const cc2CCModeDescriptor ccxts_mode = { 362 .mode_get_ctx_size = ccxts_mode_get_ctx_size, 363 .mode_get_block_size = ccxts_mode_get_block_size, 364 .mode_setup = ccxts_mode_setup, 365 .mode_encrypt = NULL, 366 .mode_decrypt = NULL, 367 .mode_encrypt_tweaked = ccxts_mode_encrypt_tweak, 368 .mode_decrypt_tweaked = ccxts_mode_decrypt_tweak, 369 .mode_done = NULL, 370 .mode_setiv = NULL, 371 .mode_getiv = NULL 372}; 373 374// GCM 375 376static size_t ccgcm_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.gcm->size; } 377static size_t ccgcm_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.gcm->block_size; } 378static void ccgcm_mode_setup(const corecryptoMode modeObj, const void *iv, 379 const void *key, size_t keylen, const void *tweak, 380 size_t tweaklen, int options, modeCtx ctx) 381{ 382 modeObj.gcm->init(modeObj.gcm, ctx.gcm, keylen, key); 383} 384 385static void ccgcm_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 386{ 387 modeObj.gcm->gcm(ctx.gcm, len, in, out); 388} 389 390static int ccgcm_setiv(const corecryptoMode modeObj, const void *iv, uint32_t len, modeCtx ctx) 391{ 392 modeObj.gcm->set_iv(ctx.gcm, len, iv); 393 return 0; 394} 395 396 397const cc2CCModeDescriptor ccgcm_mode = { 398 .mode_get_ctx_size = ccgcm_mode_get_ctx_size, 399 .mode_get_block_size = ccgcm_mode_get_block_size, 400 .mode_setup = ccgcm_mode_setup, 401 .mode_encrypt = ccgcm_mode_crypt, 402 .mode_decrypt = ccgcm_mode_crypt, 403 .mode_encrypt_tweaked = NULL, 404 .mode_decrypt_tweaked = NULL, 405 .mode_done = NULL, 406 .mode_setiv = ccgcm_setiv, 407 .mode_getiv = NULL 408}; 409 410// CCM 411 412static size_t ccccm_mode_get_ctx_size(const corecryptoMode modeObject) { return modeObject.ccm->size + sizeof(ccm_nonce_ctx); } 413static size_t ccccm_mode_get_block_size(const corecryptoMode modeObject) { return modeObject.ccm->block_size; } 414static void ccccm_mode_setup(const corecryptoMode modeObj, const void *iv, 415 const void *key, size_t keylen, const void *tweak, 416 size_t tweaklen, int options, modeCtx ctx) 417{ 418 modeObj.ccm->init(modeObj.ccm, &ctx.ccm->ccm, keylen, key); 419 ctx.ccm->nonce_size = (size_t) 0xffffffffffffffff; 420 ctx.ccm->mac_size = (size_t) 0xffffffffffffffff; 421 ctx.ccm->ad_len = (size_t) 0xffffffffffffffff; 422 ctx.ccm->total_len = (size_t) 0xffffffffffffffff; 423} 424 425static void ccccm_mode_crypt(const corecryptoMode modeObj, const void *in, void *out, size_t len, modeCtx ctx) 426{ 427 modeObj.ccm->ccm(&ctx.ccm->ccm, (ccccm_nonce *) &ctx.ccm->nonce, len, in, out); 428} 429 430static int ccccm_mode_done(const corecryptoMode modeObj, modeCtx ctx) 431{ 432 modeObj.ccm->finalize(&ctx.ccm->ccm, (ccccm_nonce *) &ctx.ccm->nonce, ctx.ccm->mac); 433 ctx.ccm->mac_size = ctx.ccm->nonce.mac_size; 434 return 0; 435} 436 437const cc2CCModeDescriptor ccccm_mode = { 438 .mode_get_ctx_size = ccccm_mode_get_ctx_size, 439 .mode_get_block_size = ccccm_mode_get_block_size, 440 .mode_setup = ccccm_mode_setup, 441 .mode_encrypt = ccccm_mode_crypt, 442 .mode_decrypt = ccccm_mode_crypt, 443 .mode_encrypt_tweaked = NULL, 444 .mode_decrypt_tweaked = NULL, 445 .mode_done = ccccm_mode_done, 446 .mode_setiv = NULL, 447 .mode_getiv = NULL 448}; 449 450 451// Padding 452 453static int ccpkcs7_encrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *cipherText, size_t *moved) 454{ 455 ccpad_pkcs7_encrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, cipherText); 456 *moved = modeptr->mode_get_block_size(modeObj); 457 return 0; 458} 459static int ccpkcs7_decrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *plainText, size_t *moved) 460{ 461 *moved = ccpad_pkcs7_decrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, plainText); 462 return 0; 463} 464 465 466static int ccpkcs7_encrypt_ecb_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *cipherText, size_t *moved) 467{ 468 ccpad_pkcs7_ecb_encrypt(modeObj.ecb, ctx.ecb, len, buff, cipherText); 469 *moved = modeptr->mode_get_block_size(modeObj); 470 return 0; 471} 472static int ccpkcs7_decrypt_ecb_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *plainText, size_t *moved) 473{ 474 *moved = ccpad_pkcs7_ecb_decrypt(modeObj.ecb, ctx.ecb, len, buff, plainText); 475 return 0; 476} 477 478 479/* 480 * Maximum space needed for padding. 481 */ 482 483// Utility functions 484static inline size_t cc_round_down_by_blocksize(const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, size_t length) { 485 size_t blocksize = modeptr->mode_get_block_size(modeObj); 486 return length / blocksize * blocksize; 487} 488 489static inline size_t cc_round_up_by_blocksize(const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, size_t length) { 490 return cc_round_down_by_blocksize(modeptr, modeObj, length + modeptr->mode_get_block_size(modeObj) - 1); 491} 492 493#define MAXBLOCKSIZE_PKCS7 128 494 495static size_t ccpkcs7_padlen(int encrypting, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, size_t inputLength, bool final) 496{ 497 size_t retval; 498 499 if(final) { 500 if(encrypting) retval = cc_round_down_by_blocksize(modeptr, modeObj, inputLength+modeptr->mode_get_block_size(modeObj)); // round up to blocksize 501 else retval = inputLength; // largest would be inputLength - 1 actually. 502 } else { 503 if(encrypting) retval = cc_round_down_by_blocksize(modeptr, modeObj, inputLength); // round down to blocksize 504 else { 505 if(inputLength && (inputLength % modeptr->mode_get_block_size(modeObj) == 0)) inputLength--; 506 retval = cc_round_down_by_blocksize(modeptr, modeObj, inputLength); 507 } 508 } 509 510 return retval; 511} 512 513/* 514 * How many bytes to reserve to enable padding - this is pre-encrypt/decrypt bytes. 515 */ 516 517static size_t ccpkcs7_reserve(int encrypt, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj) 518{ 519 if(encrypt) { 520 return 0; 521 } else { 522 return modeptr->mode_get_block_size(modeObj); 523 } 524} 525 526const cc2CCPaddingDescriptor ccpkcs7_pad = { 527 .encrypt_pad = ccpkcs7_encrypt_pad, 528 .decrypt_pad = ccpkcs7_decrypt_pad, 529 .padlen = ccpkcs7_padlen, 530 .padreserve = ccpkcs7_reserve, 531}; 532 533const cc2CCPaddingDescriptor ccpkcs7_ecb_pad = { 534 .encrypt_pad = ccpkcs7_encrypt_ecb_pad, 535 .decrypt_pad = ccpkcs7_decrypt_ecb_pad, 536 .padlen = ccpkcs7_padlen, 537 .padreserve = ccpkcs7_reserve, 538}; 539 540 541static int cccts1_encrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *cipherText, size_t *moved) 542{ 543 ccpad_cts1_encrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, cipherText); 544 *moved = len; 545 return 0; 546} 547static int cccts1_decrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *plainText, size_t *moved) 548{ 549 ccpad_cts1_decrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, plainText); 550 *moved = len; 551 return 0; 552} 553 554static int cccts2_encrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *cipherText, size_t *moved) 555{ 556 ccpad_cts2_encrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, cipherText); 557 *moved = len; 558 return 0; 559} 560static int cccts2_decrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *plainText, size_t *moved) 561{ 562 ccpad_cts2_decrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, plainText); 563 *moved = len; 564 return 0; 565} 566 567 568static int cccts3_encrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *cipherText, size_t *moved) 569{ 570 ccpad_cts3_encrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, cipherText); 571 *moved = len; 572 return 0; 573} 574static int cccts3_decrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *plainText, size_t *moved) 575{ 576 ccpad_cts3_decrypt(modeObj.cbc, &ctx.cbc->cbc, (cccbc_iv*) ctx.cbc->iv, len, buff, plainText); 577 *moved = len; 578 return 0; 579} 580 581 582 583/* 584 * Maximum space needed for padding. 585 */ 586 587#define MAXBLOCKSIZE_PKCS7 128 588 589static size_t ccctsX_padlen(int encrypting, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, size_t inputLength, bool final) 590{ 591 size_t retval; 592 size_t blocksize = modeptr->mode_get_block_size(modeObj); 593 if(final) { 594 if(encrypting) retval = cc_round_up_by_blocksize(modeptr, modeObj, inputLength); // round up to blocksize 595 else retval = inputLength; // largest would be inputLength - 1 actually. 596 } else { 597 if(encrypting) { 598 if(inputLength <= blocksize) retval = 0; 599 else retval = cc_round_down_by_blocksize(modeptr, modeObj, inputLength - blocksize); 600 } 601 else retval = inputLength; // largest would be inputLength - 1 actually. 602 } 603 604 return retval; 605} 606 607/* 608 * How many bytes to reserve to enable padding - this is pre-encrypt/decrypt bytes. 609 */ 610 611static size_t ccctsX_reserve(int encrypt, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj) 612{ 613 return modeptr->mode_get_block_size(modeObj) * 2; 614} 615 616const cc2CCPaddingDescriptor cccts1_pad = { 617 .encrypt_pad = cccts1_encrypt_pad, 618 .decrypt_pad = cccts1_decrypt_pad, 619 .padlen = ccctsX_padlen, 620 .padreserve = ccctsX_reserve, 621}; 622 623const cc2CCPaddingDescriptor cccts2_pad = { 624 .encrypt_pad = cccts2_encrypt_pad, 625 .decrypt_pad = cccts2_decrypt_pad, 626 .padlen = ccctsX_padlen, 627 .padreserve = ccctsX_reserve, 628}; 629 630 631const cc2CCPaddingDescriptor cccts3_pad = { 632 .encrypt_pad = cccts3_encrypt_pad, 633 .decrypt_pad = cccts3_decrypt_pad, 634 .padlen = ccctsX_padlen, 635 .padreserve = ccctsX_reserve, 636}; 637 638 639static int ccnopad_encrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *cipherText, size_t *moved) 640{ 641 *moved = 0; 642 if(len != 0) return -1; 643 return 0; 644} 645static int ccnopad_decrypt_pad(modeCtx ctx, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, void *buff, size_t len, void *plainText, size_t *moved) 646{ 647 *moved = 0; 648 if(len != 0) return -1; 649 return 0; 650} 651 652/* 653 * Maximum space needed for padding. 654 */ 655 656static size_t ccnopad_padlen(int encrypting, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj, size_t inputLength, bool final) 657{ 658 return cc_round_down_by_blocksize(modeptr, modeObj, inputLength); 659} 660 661/* 662 * How many bytes to reserve to enable padding - this is pre-encrypt/decrypt bytes. 663 */ 664 665static size_t ccnopad_reserve(int encrypt, const cc2CCModeDescriptor *modeptr, const corecryptoMode modeObj) 666{ 667 return 0; 668} 669 670const cc2CCPaddingDescriptor ccnopad_pad = { 671 .encrypt_pad = ccnopad_encrypt_pad, 672 .decrypt_pad = ccnopad_decrypt_pad, 673 .padlen = ccnopad_padlen, 674 .padreserve = ccnopad_reserve, 675}; 676 677 678