| 1 | /* Copyright (c) (2010-2012,2014-2022) Apple Inc. All rights reserved. |
| 2 | * |
| 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. |
| 10 | * |
| 11 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
| 12 | * |
| 13 | * This file contains Original Code and/or Modifications of Original Code |
| 14 | * as defined in and that are subject to the Apple Public Source License |
| 15 | * Version 2.0 (the 'License'). You may not use this file except in |
| 16 | * compliance with the License. The rights granted to you under the License |
| 17 | * may not be used to create, or enable the creation or redistribution of, |
| 18 | * unlawful or unlicensed copies of an Apple operating system, or to |
| 19 | * circumvent, violate, or enable the circumvention or violation of, any |
| 20 | * terms of an Apple operating system software license agreement. |
| 21 | * |
| 22 | * Please obtain a copy of the License at |
| 23 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
| 24 | * |
| 25 | * The Original Code and all software distributed under the License are |
| 26 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
| 27 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
| 28 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
| 29 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
| 30 | * Please see the License for the specific language governing rights and |
| 31 | * limitations under the License. |
| 32 | * |
| 33 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
| 34 | */ |
| 35 | |
| 36 | #ifndef _CORECRYPTO_CCMODE_INTERNAL_H_ |
| 37 | #define _CORECRYPTO_CCMODE_INTERNAL_H_ |
| 38 | |
| 39 | #include <corecrypto/ccmode.h> |
| 40 | #include <corecrypto/ccmode_factory.h> |
| 41 | #include <corecrypto/cc_priv.h> |
| 42 | #include "cc_memory.h" |
| 43 | #include "cc_macros.h" |
| 44 | |
| 45 | #include "ccmode_gcm_internal.h" |
| 46 | |
| 47 | /* Macros defined in this file are only to be used |
| 48 | * within corecrypto files. |
| 49 | */ |
| 50 | |
| 51 | /* For CBC, direction of underlying ecb is the same as the cbc direction */ |
| 52 | #define CCMODE_CBC_FACTORY(_cipher_, _dir_) \ |
| 53 | static CC_READ_ONLY_LATE(struct ccmode_cbc) cbc_##_cipher_##_##_dir_; \ |
| 54 | \ |
| 55 | const struct ccmode_cbc *cc##_cipher_##_cbc_##_dir_##_mode(void) \ |
| 56 | { \ |
| 57 | if (!CC_CACHE_DESCRIPTORS || NULL == cbc_##_cipher_##_##_dir_.init) { \ |
| 58 | const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_##_dir_##_mode(); \ |
| 59 | ccmode_factory_cbc_##_dir_(&cbc_##_cipher_##_##_dir_, ecb); \ |
| 60 | } \ |
| 61 | return &cbc_##_cipher_##_##_dir_; \ |
| 62 | } |
| 63 | |
| 64 | /* For CTR, only one direction, underlying ecb is always encrypt */ |
| 65 | #define CCMODE_CTR_FACTORY(_cipher_) \ |
| 66 | static struct ccmode_ctr ctr_##_cipher_; \ |
| 67 | \ |
| 68 | const struct ccmode_ctr *cc##_cipher_##_ctr_crypt_mode(void) \ |
| 69 | { \ |
| 70 | const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode(); \ |
| 71 | ccmode_factory_ctr_crypt(&ctr_##_cipher_, ecb); \ |
| 72 | return &ctr_##_cipher_; \ |
| 73 | } |
| 74 | |
| 75 | /* OFB, same as CTR */ |
| 76 | #define CCMODE_OFB_FACTORY(_cipher_) \ |
| 77 | static struct ccmode_ofb ofb_##_cipher_; \ |
| 78 | \ |
| 79 | const struct ccmode_ofb *cc##_cipher_##_ofb_crypt_mode(void) \ |
| 80 | { \ |
| 81 | const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode(); \ |
| 82 | ccmode_factory_ofb_crypt(&ofb_##_cipher_, ecb); \ |
| 83 | return &ofb_##_cipher_; \ |
| 84 | } |
| 85 | |
| 86 | |
| 87 | /* For CFB, the underlying ecb operation is encrypt for both directions */ |
| 88 | #define CCMODE_CFB_FACTORY(_cipher_, _mode_, _dir_) \ |
| 89 | static CC_READ_ONLY_LATE(struct ccmode_##_mode_) _mode_##_##_cipher_##_##_dir_; \ |
| 90 | \ |
| 91 | const struct ccmode_##_mode_ *cc##_cipher_##_##_mode_##_##_dir_##_mode(void) \ |
| 92 | { \ |
| 93 | if (!CC_CACHE_DESCRIPTORS || NULL == _mode_##_##_cipher_##_##_dir_.init) { \ |
| 94 | const struct ccmode_ecb *ecb=cc##_cipher_##_ecb_encrypt_mode(); \ |
| 95 | ccmode_factory_##_mode_##_##_dir_(&_mode_##_##_cipher_##_##_dir_, ecb); \ |
| 96 | } \ |
| 97 | return &_mode_##_##_cipher_##_##_dir_; \ |
| 98 | } |
| 99 | |
| 100 | void ccmode_xts_mult_alpha(cc_unit *tweak); |
| 101 | |
| 102 | int ccmode_cbc_init(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, |
| 103 | size_t rawkey_len, const void *rawkey); |
| 104 | int ccmode_cbc_decrypt(const cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, |
| 105 | const void *in, void *out); |
| 106 | int ccmode_cbc_encrypt(const cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, |
| 107 | const void *in, void *out); |
| 108 | |
| 109 | /* Use this to statically initialize a ccmode_cbc object for decryption. */ |
| 110 | #define CCMODE_FACTORY_CBC_DECRYPT(ECB) { \ |
| 111 | .size = ccn_sizeof_size(sizeof(struct _ccmode_cbc_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \ |
| 112 | .block_size = (ECB)->block_size, \ |
| 113 | .init = ccmode_cbc_init, \ |
| 114 | .cbc = ccmode_cbc_decrypt, \ |
| 115 | .custom = (ECB) \ |
| 116 | } |
| 117 | |
| 118 | /* Use this to statically initialize a ccmode_cbc object for encryption. */ |
| 119 | #define CCMODE_FACTORY_CBC_ENCRYPT(ECB) { \ |
| 120 | .size = ccn_sizeof_size(sizeof(struct _ccmode_cbc_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \ |
| 121 | .block_size = (ECB)->block_size, \ |
| 122 | .init = ccmode_cbc_init, \ |
| 123 | .cbc = ccmode_cbc_encrypt, \ |
| 124 | .custom = (ECB) \ |
| 125 | } |
| 126 | |
| 127 | struct _ccmode_cbc_key { |
| 128 | const struct ccmode_ecb *ecb; |
| 129 | cc_unit u[]; |
| 130 | }; |
| 131 | |
| 132 | /* Macros for accessing a CCMODE_CBC_KEY. |
| 133 | * { |
| 134 | * const struct ccmode_ecb *ecb |
| 135 | * ccn_unit ecb_key[ecb->n] |
| 136 | * } */ |
| 137 | #define _CCMODE_CBC_KEY(K) ((struct _ccmode_cbc_key *)(K)) |
| 138 | #define _CCMODE_CBC_KEY_CONST(K) ((const struct _ccmode_cbc_key *)(K)) |
| 139 | #define CCMODE_CBC_KEY_ECB(K) (_CCMODE_CBC_KEY(K)->ecb) |
| 140 | #define CCMODE_CBC_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CBC_KEY(K)->u[0]) |
| 141 | |
| 142 | CC_INLINE |
| 143 | const struct ccmode_ecb * |
| 144 | ccmode_cbc_key_ecb(const cccbc_ctx *K) |
| 145 | { |
| 146 | return ((const struct _ccmode_cbc_key *)K)->ecb; |
| 147 | } |
| 148 | |
| 149 | CC_INLINE |
| 150 | const ccecb_ctx * |
| 151 | ccmode_cbc_key_ecb_key(const cccbc_ctx *K) |
| 152 | { |
| 153 | return (const ccecb_ctx *)&((const struct _ccmode_cbc_key *)K)->u[0]; |
| 154 | } |
| 155 | |
| 156 | int ccmode_cfb_init(const struct ccmode_cfb *cfb, cccfb_ctx *ctx, |
| 157 | size_t rawkey_len, const void *rawkey, |
| 158 | const void *iv); |
| 159 | int ccmode_cfb_decrypt(cccfb_ctx *ctx, size_t nbytes, |
| 160 | const void *in, void *out); |
| 161 | int ccmode_cfb_encrypt(cccfb_ctx *ctx, size_t nbytes, |
| 162 | const void *in, void *out); |
| 163 | |
| 164 | /* Use this to statically initialize a ccmode_cfb object for decryption. */ |
| 165 | #define CCMODE_FACTORY_CFB_DECRYPT(ECB) { \ |
| 166 | .size = ccn_sizeof_size(sizeof(struct _ccmode_cfb_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \ |
| 167 | .block_size = 1, \ |
| 168 | .init = ccmode_cfb_init, \ |
| 169 | .cfb = ccmode_cfb_decrypt, \ |
| 170 | .custom = (ECB) \ |
| 171 | } |
| 172 | |
| 173 | /* Use this to statically initialize a ccmode_cfb object for encryption. */ |
| 174 | #define CCMODE_FACTORY_CFB_ENCRYPT(ECB) { \ |
| 175 | .size = ccn_sizeof_size(sizeof(struct _ccmode_cfb_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \ |
| 176 | .block_size = 1, \ |
| 177 | .init = ccmode_cfb_init, \ |
| 178 | .cfb = ccmode_cfb_encrypt, \ |
| 179 | .custom = (ECB) \ |
| 180 | } |
| 181 | |
| 182 | struct _ccmode_cfb_key { |
| 183 | const struct ccmode_ecb *ecb; |
| 184 | size_t pad_len; |
| 185 | cc_unit u[]; |
| 186 | }; |
| 187 | /* Macros for accessing a CCMODE_CFB_KEY. |
| 188 | * { |
| 189 | * const struct ccmode_ecb *ecb |
| 190 | * cc_size pad_len; |
| 191 | * ccn_unit pad[ecb->block_size / CCN_UNIT_SIZE]; |
| 192 | * ccn_unit iv[ecb->block_size / CCN_UNIT_SIZE]; |
| 193 | * ccn_unit ecb_key[ecb->n] |
| 194 | * } */ |
| 195 | #define _CCMODE_CFB_KEY(K) ((struct _ccmode_cfb_key *)(K)) |
| 196 | #define CCMODE_CFB_KEY_ECB(K) (_CCMODE_CFB_KEY(K)->ecb) |
| 197 | #define CCMODE_CFB_KEY_PAD_LEN(K) (_CCMODE_CFB_KEY(K)->pad_len) |
| 198 | #define CCMODE_CFB_KEY_PAD(K) (&_CCMODE_CFB_KEY(K)->u[0]) |
| 199 | #define CCMODE_CFB_KEY_IV(K) (&_CCMODE_CFB_KEY(K)->u[ccn_nof_size(CCMODE_CFB_KEY_ECB(K)->block_size)]) |
| 200 | #define CCMODE_CFB_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CFB_KEY(K)->u[2 * ccn_nof_size(CCMODE_CFB_KEY_ECB(K)->block_size)]) |
| 201 | |
| 202 | int ccmode_cfb8_init(const struct ccmode_cfb8 *cfb8, cccfb8_ctx *ctx, |
| 203 | size_t rawkey_len, const void *rawkey, const void *iv); |
| 204 | int ccmode_cfb8_decrypt(cccfb8_ctx *ctx, size_t nbytes, |
| 205 | const void *in, void *out); |
| 206 | int ccmode_cfb8_encrypt(cccfb8_ctx *ctx, size_t nbytes, |
| 207 | const void *in, void *out); |
| 208 | |
| 209 | /* Use this to statically initialize a ccmode_cfb8 object for decryption. */ |
| 210 | #define CCMODE_FACTORY_CFB8_DECRYPT(ECB) { \ |
| 211 | .size = ccn_sizeof_size(sizeof(struct _ccmode_cfb8_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \ |
| 212 | .block_size = 1, \ |
| 213 | .init = ccmode_cfb8_init, \ |
| 214 | .cfb8 = ccmode_cfb8_decrypt, \ |
| 215 | .custom = (ECB) \ |
| 216 | } |
| 217 | |
| 218 | /* Use this to statically initialize a ccmode_cfb8 object for encryption. */ |
| 219 | #define CCMODE_FACTORY_CFB8_ENCRYPT(ECB) { \ |
| 220 | .size = ccn_sizeof_size(sizeof(struct _ccmode_cfb8_key)) + 2 * ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \ |
| 221 | .block_size = 1, \ |
| 222 | .init = ccmode_cfb8_init, \ |
| 223 | .cfb8 = ccmode_cfb8_encrypt, \ |
| 224 | .custom = (ECB) \ |
| 225 | } |
| 226 | |
| 227 | struct _ccmode_cfb8_key { |
| 228 | const struct ccmode_ecb *ecb; |
| 229 | cc_unit u[]; |
| 230 | }; |
| 231 | |
| 232 | /* Macros for accessing a CCMODE_CFB8_KEY. |
| 233 | * { |
| 234 | * const struct ccmode_ecb *ecb |
| 235 | * ccn_unit pad[ecb->block_size / CCN_UNIT_SIZE]; |
| 236 | * ccn_unit iv[ecb->block_size / CCN_UNIT_SIZE]; |
| 237 | * ccn_unit ecb_key[ecb->n] |
| 238 | * } */ |
| 239 | #define _CCMODE_CFB8_KEY(K) ((struct _ccmode_cfb8_key *)(K)) |
| 240 | #define CCMODE_CFB8_KEY_ECB(K) (_CCMODE_CFB8_KEY(K)->ecb) |
| 241 | #define CCMODE_CFB8_KEY_PAD(K) (&_CCMODE_CFB8_KEY(K)->u[0]) |
| 242 | #define CCMODE_CFB8_KEY_IV(K) (&_CCMODE_CFB8_KEY(K)->u[ccn_nof_size(CCMODE_CFB8_KEY_ECB(K)->block_size)]) |
| 243 | #define CCMODE_CFB8_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CFB8_KEY(K)->u[2 * ccn_nof_size(CCMODE_CFB8_KEY_ECB(K)->block_size)]) |
| 244 | |
| 245 | int ccmode_ctr_init(const struct ccmode_ctr *ctr, ccctr_ctx *ctx, |
| 246 | size_t rawkey_len, const void *rawkey, const void *iv); |
| 247 | int ccmode_ctr_setctr(const struct ccmode_ctr *mode, ccctr_ctx *ctx, const void *ctr); |
| 248 | int ccmode_ctr_crypt(ccctr_ctx *ctx, size_t nbytes, |
| 249 | const void *in, void *out); |
| 250 | |
| 251 | /* Use this to statically initialize a ccmode_ctr object for decryption. */ |
| 252 | #define CCMODE_FACTORY_CTR_CRYPT(ECB_ENCRYPT) { \ |
| 253 | .size = ccn_sizeof_size(sizeof(struct _ccmode_ctr_key)) + 2 * ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \ |
| 254 | .block_size = 1, \ |
| 255 | .ecb_block_size = (ECB_ENCRYPT)->block_size, \ |
| 256 | .init = ccmode_ctr_init, \ |
| 257 | .setctr = ccmode_ctr_setctr, \ |
| 258 | .ctr = ccmode_ctr_crypt, \ |
| 259 | .custom = (ECB_ENCRYPT) \ |
| 260 | } |
| 261 | |
| 262 | struct _ccmode_ctr_key { |
| 263 | const struct ccmode_ecb *ecb; |
| 264 | size_t pad_offset; |
| 265 | cc_unit u[]; |
| 266 | }; |
| 267 | |
| 268 | /* Macros for accessing a CCMODE_CTR_KEY. |
| 269 | * { |
| 270 | * const struct ccmode_ecb *ecb |
| 271 | * cc_size pad_offset; |
| 272 | * ccn_unit pad[ecb->block_size / CCN_UNIT_SIZE]; |
| 273 | * ccn_unit ctr[ecb->block_size / CCN_UNIT_SIZE]; |
| 274 | * ccn_unit ecb_key[ecb->n] |
| 275 | * } */ |
| 276 | #define _CCMODE_CTR_KEY(K) ((struct _ccmode_ctr_key *)(K)) |
| 277 | #define CCMODE_CTR_KEY_ECB(K) (_CCMODE_CTR_KEY(K)->ecb) |
| 278 | #define CCMODE_CTR_KEY_PAD_OFFSET(K) (_CCMODE_CTR_KEY(K)->pad_offset) |
| 279 | #define CCMODE_CTR_KEY_PAD(K) (&_CCMODE_CTR_KEY(K)->u[0]) |
| 280 | #define CCMODE_CTR_KEY_CTR(K) (&_CCMODE_CTR_KEY(K)->u[ccn_nof_size(CCMODE_CTR_KEY_ECB(K)->block_size)]) |
| 281 | #define CCMODE_CTR_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CTR_KEY(K)->u[2 * ccn_nof_size(CCMODE_CTR_KEY_ECB(K)->block_size)]) |
| 282 | |
| 283 | CC_INLINE int |
| 284 | ccctr_setctr(const struct ccmode_ctr *mode, ccctr_ctx *ctx, const void *ctr) |
| 285 | { |
| 286 | return mode->setctr(mode, ctx, ctr); |
| 287 | } |
| 288 | |
| 289 | int ccmode_ofb_init(const struct ccmode_ofb *ofb, ccofb_ctx *ctx, |
| 290 | size_t rawkey_len, const void *rawkey, |
| 291 | const void *iv); |
| 292 | int ccmode_ofb_crypt(ccofb_ctx *ctx, size_t nbytes, |
| 293 | const void *in, void *out); |
| 294 | |
| 295 | /* Use this to statically initialize a ccmode_ofb object. */ |
| 296 | #define CCMODE_FACTORY_OFB_CRYPT(ECB) { \ |
| 297 | .size = ccn_sizeof_size(sizeof(struct _ccmode_ofb_key)) + ccn_sizeof_size((ECB)->block_size) + ccn_sizeof_size((ECB)->size), \ |
| 298 | .block_size = 1, \ |
| 299 | .init = ccmode_ofb_init, \ |
| 300 | .ofb = ccmode_ofb_crypt, \ |
| 301 | .custom = (ECB) \ |
| 302 | } |
| 303 | |
| 304 | struct _ccmode_ofb_key { |
| 305 | const struct ccmode_ecb *ecb; |
| 306 | size_t pad_len; |
| 307 | cc_unit u[]; |
| 308 | }; |
| 309 | |
| 310 | /* Macros for accessing a CCMODE_OFB_KEY. |
| 311 | * { |
| 312 | * const struct ccmode_ecb *ecb |
| 313 | * cc_size pad_len; |
| 314 | * ccn_unit iv[ecb->block_size / CCN_UNIT_SIZE]; |
| 315 | * ccn_unit ecb_key[ecb->n] |
| 316 | * } */ |
| 317 | #define _CCMODE_OFB_KEY(K) ((struct _ccmode_ofb_key *)(K)) |
| 318 | #define CCMODE_OFB_KEY_ECB(K) (_CCMODE_OFB_KEY(K)->ecb) |
| 319 | #define CCMODE_OFB_KEY_PAD_LEN(K) (_CCMODE_OFB_KEY(K)->pad_len) |
| 320 | #define CCMODE_OFB_KEY_IV(K) (&_CCMODE_OFB_KEY(K)->u[0]) |
| 321 | #define CCMODE_OFB_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_OFB_KEY(K)->u[ccn_nof_size(CCMODE_OFB_KEY_ECB(K)->block_size)]) |
| 322 | |
| 323 | |
| 324 | int ccmode_xts_init(const struct ccmode_xts *xts, ccxts_ctx *ctx, |
| 325 | size_t key_nbytes, const void *data_key, |
| 326 | const void *tweak_key); |
| 327 | void ccmode_xts_key_sched(const struct ccmode_xts *xts, ccxts_ctx *ctx, |
| 328 | size_t key_nbytes, const void *data_key, |
| 329 | const void *tweak_key); |
| 330 | void *ccmode_xts_crypt(const ccxts_ctx *ctx, ccxts_tweak *tweak, |
| 331 | size_t nblocks, const void *in, void *out); |
| 332 | int ccmode_xts_set_tweak(const ccxts_ctx *ctx, ccxts_tweak *tweak, |
| 333 | const void *iv); |
| 334 | |
| 335 | /* Use this to statically initialize a ccmode_xts object for decryption. */ |
| 336 | #define CCMODE_FACTORY_XTS_DECRYPT(ECB, ECB_ENCRYPT) { \ |
| 337 | .size = ccn_sizeof_size(sizeof(struct _ccmode_xts_key)) + 2 * ccn_sizeof_size((ECB)->size), \ |
| 338 | .tweak_size = ccn_sizeof_size(sizeof(struct _ccmode_xts_tweak)) + ccn_sizeof_size(ecb->block_size), \ |
| 339 | .block_size = ecb->block_size, \ |
| 340 | .init = ccmode_xts_init, \ |
| 341 | .key_sched = ccmode_xts_key_sched, \ |
| 342 | .set_tweak = ccmode_xts_set_tweak, \ |
| 343 | .xts = ccmode_xts_crypt, \ |
| 344 | .custom = (ECB), \ |
| 345 | .custom1 = (ECB_ENCRYPT), \ |
| 346 | .impl = CC_IMPL_AES_XTS_GENERIC, \ |
| 347 | } |
| 348 | |
| 349 | /* Use this to statically initialize a ccmode_xts object for encryption. */ |
| 350 | #define CCMODE_FACTORY_XTS_ENCRYPT(ECB, ECB_ENCRYPT) { \ |
| 351 | .size = ccn_sizeof_size(sizeof(struct _ccmode_xts_key)) + 2 * ccn_sizeof_size((ECB)->size), \ |
| 352 | .tweak_size = ccn_sizeof_size(sizeof(struct _ccmode_xts_tweak)) + ccn_sizeof_size(ecb->block_size), \ |
| 353 | .block_size = ecb->block_size, \ |
| 354 | .init = ccmode_xts_init, \ |
| 355 | .key_sched = ccmode_xts_key_sched, \ |
| 356 | .set_tweak = ccmode_xts_set_tweak, \ |
| 357 | .xts = ccmode_xts_crypt, \ |
| 358 | .custom = (ECB), \ |
| 359 | .custom1 = (ECB_ENCRYPT), \ |
| 360 | .impl = CC_IMPL_AES_XTS_GENERIC, \ |
| 361 | } |
| 362 | |
| 363 | struct _ccmode_xts_key { |
| 364 | const struct ccmode_ecb *ecb; |
| 365 | const struct ccmode_ecb *ecb_encrypt; |
| 366 | cc_unit u[]; |
| 367 | }; |
| 368 | |
| 369 | struct _ccmode_xts_tweak { |
| 370 | // FIPS requires that for XTS that no more that 2^20 AES blocks may be processed for any given |
| 371 | // Key, Tweak Key, and tweak combination |
| 372 | // the bytes_processed field in the context will accumuate the number of blocks processed and |
| 373 | // will fail the encrypt/decrypt if the size is violated. This counter will be reset to 0 |
| 374 | // when set_tweak is called. |
| 375 | size_t blocks_processed; |
| 376 | cc_unit u[]; |
| 377 | }; |
| 378 | |
| 379 | /* Macros for accessing a CCMODE_XTS_KEY. |
| 380 | * { |
| 381 | * const struct ccmode_ecb *ecb |
| 382 | * const struct ccmode_ecb *ecb_encrypt |
| 383 | * ccn_unit data_key[ecb->size] |
| 384 | * ccn_unit tweak_key[ecb_encrypt->size] |
| 385 | * } */ |
| 386 | #define _CCMODE_XTS_KEY(K) ((struct _ccmode_xts_key *)(K)) |
| 387 | #define CCMODE_XTS_KEY_ECB(K) (_CCMODE_XTS_KEY(K)->ecb) |
| 388 | #define CCMODE_XTS_KEY_ECB_ENCRYPT(K) (_CCMODE_XTS_KEY(K)->ecb_encrypt) |
| 389 | #define CCMODE_XTS_KEY_DATA_KEY(K) ((ccecb_ctx *)&_CCMODE_XTS_KEY(K)->u[0]) |
| 390 | #define CCMODE_XTS_KEY_TWEAK_KEY(K) ((ccecb_ctx *)&_CCMODE_XTS_KEY(K)->u[ccn_nof_size(CCMODE_XTS_KEY_ECB(K)->size)]) |
| 391 | |
| 392 | CC_INLINE |
| 393 | const struct ccmode_ecb * |
| 394 | ccmode_xts_key_ecb(const ccxts_ctx *K) |
| 395 | { |
| 396 | return ((const struct _ccmode_xts_key *)K)->ecb; |
| 397 | } |
| 398 | |
| 399 | CC_INLINE |
| 400 | const struct ccmode_ecb * |
| 401 | ccmode_xts_key_ecb_encrypt(const ccxts_ctx *K) |
| 402 | { |
| 403 | return ((const struct _ccmode_xts_key *)K)->ecb_encrypt; |
| 404 | } |
| 405 | |
| 406 | CC_INLINE |
| 407 | const ccecb_ctx * |
| 408 | ccmode_xts_key_data_key(const ccxts_ctx *K) |
| 409 | { |
| 410 | return (const ccecb_ctx *)&((const struct _ccmode_xts_key *)K)->u[0]; |
| 411 | } |
| 412 | |
| 413 | CC_INLINE |
| 414 | const ccecb_ctx * |
| 415 | ccmode_xts_key_tweak_key(const ccxts_ctx *K) |
| 416 | { |
| 417 | return (const ccecb_ctx *)&((const struct _ccmode_xts_key *)K)->u[ccn_nof_size(ccmode_xts_key_ecb(K)->size)]; |
| 418 | } |
| 419 | |
| 420 | /* Macros for accessing a CCMODE_XTS_TWEAK. |
| 421 | * { |
| 422 | * size_t blocks_processed; |
| 423 | * uint8_t value[16]; |
| 424 | * } */ |
| 425 | #define _CCMODE_XTS_TWEAK(T) ((struct _ccmode_xts_tweak *)(T)) |
| 426 | #define CCMODE_XTS_TWEAK_BLOCK_PROCESSED(T)(_CCMODE_XTS_TWEAK(T)->blocks_processed) |
| 427 | #define CCMODE_XTS_TWEAK_VALUE(T) (_CCMODE_XTS_TWEAK(T)->u) |
| 428 | |
| 429 | #define CCMODE_STATE_INIT 2 //first call to init |
| 430 | #define CCMODE_STATE_IV_START 3 //first call to set_iv |
| 431 | |
| 432 | #define CCMODE_STATE_IV_CONT CCMODE_STATE_IV_START |
| 433 | |
| 434 | #define CCMODE_STATE_AAD 4 |
| 435 | #define CCMODE_STATE_TEXT 5 |
| 436 | #define CCMODE_STATE_NONCE 6 |
| 437 | #define CCMODE_STATE_NONCE_NOADD 7 |
| 438 | |
| 439 | #define CCMODE_CCM_STATE_IV 1 |
| 440 | #define CCMODE_STATE_INVALID 255 |
| 441 | |
| 442 | /* CCM (only NIST approved with AES) */ |
| 443 | int ccmode_ccm_init(const struct ccmode_ccm *ccm, ccccm_ctx *ctx, |
| 444 | size_t rawkey_len, const void *rawkey); |
| 445 | int ccmode_ccm_set_iv(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nonce_len, const void *nonce, |
| 446 | size_t mac_size, size_t auth_len, size_t data_len); |
| 447 | /* internal function */ |
| 448 | void ccmode_ccm_macdata(ccccm_ctx *key, ccccm_nonce *nonce_ctx, unsigned new_block, size_t nbytes, const void *in); |
| 449 | /* api function - disallows only mac'd data after data to encrypt was sent */ |
| 450 | int ccmode_ccm_cbcmac(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in); |
| 451 | /* internal function */ |
| 452 | void ccmode_ccm_crypt(ccccm_ctx *key, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out); |
| 453 | int ccmode_ccm_decrypt(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, |
| 454 | void *out); |
| 455 | int ccmode_ccm_encrypt(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, |
| 456 | void *out); |
| 457 | int ccmode_ccm_finalize(ccccm_ctx *key, ccccm_nonce *nonce_ctx, void *mac); |
| 458 | int ccmode_ccm_finalize_and_verify(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, void *mac); |
| 459 | int ccmode_ccm_reset(ccccm_ctx *key, ccccm_nonce *nonce_ctx); |
| 460 | |
| 461 | /* Use this to statically initialize a ccmode_ccm object for decryption. */ |
| 462 | #define CCMODE_FACTORY_CCM_DECRYPT(ECB_ENCRYPT) { \ |
| 463 | .size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_key)) + ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \ |
| 464 | .nonce_size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_nonce)), \ |
| 465 | .block_size = 1, \ |
| 466 | .init = ccmode_ccm_init, \ |
| 467 | .set_iv = ccmode_ccm_set_iv, \ |
| 468 | .cbcmac = ccmode_ccm_cbcmac, \ |
| 469 | .ccm = ccmode_ccm_decrypt, \ |
| 470 | .finalize = ccmode_ccm_finalize, \ |
| 471 | .reset = ccmode_ccm_reset, \ |
| 472 | .custom = (ECB_ENCRYPT), \ |
| 473 | .enc_mode = false, \ |
| 474 | } |
| 475 | |
| 476 | /* Use this to statically initialize a ccmode_ccm object for encryption. */ |
| 477 | #define CCMODE_FACTORY_CCM_ENCRYPT(ECB_ENCRYPT) { \ |
| 478 | .size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_key)) + ccn_sizeof_size((ECB_ENCRYPT)->block_size) + ccn_sizeof_size((ECB_ENCRYPT)->size), \ |
| 479 | .nonce_size = ccn_sizeof_size(sizeof(struct _ccmode_ccm_nonce)), \ |
| 480 | .block_size = 1, \ |
| 481 | .init = ccmode_ccm_init, \ |
| 482 | .set_iv = ccmode_ccm_set_iv, \ |
| 483 | .cbcmac = ccmode_ccm_cbcmac, \ |
| 484 | .ccm = ccmode_ccm_encrypt, \ |
| 485 | .finalize = ccmode_ccm_finalize, \ |
| 486 | .reset = ccmode_ccm_reset, \ |
| 487 | .custom = (ECB_ENCRYPT), \ |
| 488 | .enc_mode = true, \ |
| 489 | } |
| 490 | |
| 491 | struct _ccmode_ccm_key { |
| 492 | const struct ccmode_ecb *ecb; |
| 493 | cc_unit u[]; |
| 494 | }; |
| 495 | |
| 496 | /* Macros for accessing a CCMODE_CCM_KEY. */ |
| 497 | #define _CCMODE_CCM_KEY(K) ((struct _ccmode_ccm_key *)(K)) |
| 498 | #define CCMODE_CCM_KEY_ECB(K) (_CCMODE_CCM_KEY(K)->ecb) |
| 499 | #define CCMODE_CCM_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CCM_KEY(K)->u[0]) |
| 500 | |
| 501 | #define _CCMODE_CCM_NONCE(N) ((struct _ccmode_ccm_nonce *)(N)) |
| 502 | #define CCMODE_CCM_KEY_MAC(N) (_CCMODE_CCM_NONCE(N)->MAC) |
| 503 | #define CCMODE_CCM_KEY_A_I(N) (_CCMODE_CCM_NONCE(N)->A_i) |
| 504 | #define CCMODE_CCM_KEY_B_I(N) (_CCMODE_CCM_NONCE(N)->B_i) |
| 505 | #define CCMODE_CCM_KEY_PAD_LEN(N) (_CCMODE_CCM_NONCE(N)->buflen) |
| 506 | #define CCMODE_CCM_KEY_PAD(N) (_CCMODE_CCM_NONCE(N)->buf) |
| 507 | #define CCMODE_CCM_KEY_MAC_LEN(N) (_CCMODE_CCM_NONCE(N)->mac_size) |
| 508 | #define CCMODE_CCM_KEY_NONCE_LEN(N) (_CCMODE_CCM_NONCE(N)->nonce_size) |
| 509 | #define CCMODE_CCM_KEY_AUTH_LEN(N) (_CCMODE_CCM_NONCE(N)->b_i_len) |
| 510 | |
| 511 | int ccmode_omac_decrypt(ccomac_ctx *ctx, size_t nblocks, |
| 512 | const void *tweak, const void *in, void *out); |
| 513 | int ccmode_omac_encrypt(ccomac_ctx *ctx, size_t nblocks, |
| 514 | const void *tweak, const void *in, void *out); |
| 515 | |
| 516 | /* Create a omac key from a omac mode object. The tweak_len here |
| 517 | * determines how long the tweak is in bytes, for each subsequent call to |
| 518 | * ccmode_omac->omac(). |
| 519 | * key must point to at least sizeof(CCMODE_OMAC_KEY(ecb)) bytes of free |
| 520 | * storage. */ |
| 521 | int ccmode_omac_init(const struct ccmode_omac *omac, ccomac_ctx *ctx, |
| 522 | size_t tweak_len, size_t rawkey_len, |
| 523 | const void *rawkey); |
| 524 | |
| 525 | /* Use this to statically initialize a ccmode_omac object for decryption. */ |
| 526 | #define CCMODE_FACTORY_OMAC_DECRYPT(ECB) { \ |
| 527 | .size = ccn_sizeof_size(sizeof(struct _ccmode_omac_key)) + 2 * ccn_sizeof_size((ECB)->size), \ |
| 528 | .block_size = (ECB)->block_size, \ |
| 529 | .init = ccmode_omac_init, \ |
| 530 | .omac = ccmode_omac_decrypt, \ |
| 531 | .custom = (ECB) \ |
| 532 | } |
| 533 | |
| 534 | /* Use this to statically initialize a ccmode_omac object for encryption. */ |
| 535 | #define CCMODE_FACTORY_OMAC_ENCRYPT(ECB) { \ |
| 536 | .size = ccn_sizeof_size(sizeof(struct _ccmode_omac_key)) + 2 * ccn_sizeof_size((ECB)->size), \ |
| 537 | .block_size = (ECB)->block_size, \ |
| 538 | .init = ccmode_omac_init, \ |
| 539 | .omac = ccmode_omac_encrypt, \ |
| 540 | .custom = (ECB) \ |
| 541 | } |
| 542 | |
| 543 | struct _ccmode_omac_key { |
| 544 | const struct ccmode_ecb *ecb; |
| 545 | size_t tweak_len; |
| 546 | cc_unit u[]; |
| 547 | }; |
| 548 | |
| 549 | /* Macros for accessing a CCMODE_OMAC_KEY. |
| 550 | * { |
| 551 | * const struct ccmode_ecb *ecb |
| 552 | * cc_size tweak_size; |
| 553 | * ccn_unit ecb_key1[ecb->n] |
| 554 | * ccn_unit ecb_key2[ecb->n] |
| 555 | * } */ |
| 556 | #define _CCMODE_OMAC_KEY(K) ((struct _ccmode_omac_key *)(K)) |
| 557 | #define CCMODE_OMAC_KEY_ECB(K) (_CCMODE_OMAC_KEY(K)->ecb) |
| 558 | #define CCMODE_OMAC_KEY_TWEAK_LEN(K) (_CCMODE_OMAC_KEY(K)->tweak_len) |
| 559 | #define CCMODE_OMAC_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_OMAC_KEY(K)->u[0]) |
| 560 | |
| 561 | #endif /* _CORECRYPTO_CCMODE_INTERNAL_H_ */ |
| 562 | |