1 /* Copyright (c) (2010-2012,2015-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 12 #ifndef _CORECRYPTO_CCMODE_IMPL_H_ 13 #define _CORECRYPTO_CCMODE_IMPL_H_ 14 #include <corecrypto/cc.h> 15 16 #define CCMODE_MAX_BLOCK_SIZE 16 17 18 /* ECB mode. */ 19 cc_aligned_struct(16) ccecb_ctx; 20 21 /* Actual symmetric algorithm implementation should provide you one of these. */ 22 struct ccmode_ecb { 23 size_t size; /* first argument to ccecb_ctx_decl(). */ 24 size_t block_size; 25 int (*CC_SPTR(ccmode_ecb, init))(const struct ccmode_ecb *ecb, ccecb_ctx *ctx, size_t key_nbytes, const void *key); 26 int (*CC_SPTR(ccmode_ecb, ecb))(const ccecb_ctx *ctx, size_t nblocks, const void *in, void *out); 27 void (*CC_SPTR(ccmode_ecb, roundkey))(const ccecb_ctx *ctx, unsigned r, void *key); 28 cc_impl_t impl; 29 }; 30 31 /*! 32 * @brief corecrypto symmetrical encryption and decryption modes 33 * 34 * corecrypto supports 6 stateless en(de)cryption modes and 2 stateful authenticated en(de)cryption modes 35 * stateless modes CBC, CFB, CFB8, CTR, OFB, XTS: They provide 3 interface functions that do not return errors codes 36 * 1- ccmod_xxx_init() 37 * 2- ccmod_xxx_decrypt() 38 * 3- ccmod_xxx_encrypt() 39 * 40 * stateful modes CCM and GCM: They provide 7 interface functions that return error codes if a function is called out of state 41 * 1- ccmod_xxx_init() 42 * 2- ccmod_xxx_setiv() 43 * 3- ccmod_xxx_aad() 44 * 4- ccmod_xxx_decrypt() 45 * 5- ccmod_xxx_encrypt() 46 * 6- ccmod_xxx_finalize() 47 * 7- ccmod_xxx_reset() 48 * 49 * the correct call sequences are: 50 * 51 * calls to 1, 2 and 6 arerequired 52 * 2 and 3 can be called as mant times as needed 53 * calls to 3, 4, 5 can be skipped 54 * 55 * 1, 2*n, 3*n, 4|5, 6 56 * 1, 2*n, , 4|5, 6 57 * 1, 2*n, , , 6 58 * 1, 2*n, 3*n, , 6 59 */ 60 61 // 1- CBC mode, stateless 62 cc_aligned_struct(16) cccbc_ctx; 63 cc_aligned_struct(16) cccbc_iv; 64 65 // This value was derived empirically. It may need to be updated to 66 // match changes in implementation. 67 #define CCCBC_MAX_CTX_SIZE 512 68 69 struct ccmode_cbc { 70 size_t size; /* first argument to cccbc_ctx_decl(). */ 71 size_t block_size; 72 int (*CC_SPTR(ccmode_cbc, init))(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, size_t key_len, const void *key); 73 /* cbc encrypt or decrypt nblocks from in to out, iv will be used and updated. */ 74 int (*CC_SPTR(ccmode_cbc, cbc))(const cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, const void *in, void *out); 75 const void *custom; 76 }; 77 78 // 2- CFB mode, stateless 79 cc_aligned_struct(16) cccfb_ctx; 80 81 struct ccmode_cfb { 82 size_t size; /* first argument to cccfb_ctx_decl(). */ 83 size_t block_size; 84 int (*CC_SPTR(ccmode_cfb, 85 init))(const struct ccmode_cfb *cfb, cccfb_ctx *ctx, size_t key_len, const void *key, const void *iv); 86 int (*CC_SPTR(ccmode_cfb, cfb))(cccfb_ctx *ctx, size_t nbytes, const void *in, void *out); 87 const void *custom; 88 }; 89 90 // 3- CFB8 mode, stateless 91 cc_aligned_struct(16) cccfb8_ctx; 92 93 struct ccmode_cfb8 { 94 size_t size; /* first argument to cccfb8_ctx_decl(). */ 95 size_t block_size; 96 int (*CC_SPTR(ccmode_cfb8, 97 init))(const struct ccmode_cfb8 *cfb8, cccfb8_ctx *ctx, size_t key_len, const void *key, const void *iv); 98 int (*CC_SPTR(ccmode_cfb8, cfb8))(cccfb8_ctx *ctx, size_t nbytes, const void *in, void *out); 99 const void *custom; 100 }; 101 102 // 4- CTR mode, stateless 103 cc_aligned_struct(16) ccctr_ctx; 104 105 struct ccmode_ctr { 106 size_t size; /* first argument to ccctr_ctx_decl(). */ 107 size_t block_size; /* for historical reasons, this is set to 1 */ 108 size_t ecb_block_size; /* the actual block size of the underlying cipher */ 109 int (*CC_SPTR(ccmode_ctr, 110 init))(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t key_len, const void *key, const void *iv); 111 int (*CC_SPTR(ccmode_ctr, setctr))(const struct ccmode_ctr *mode, ccctr_ctx *ctx, const void *ctr); 112 int (*CC_SPTR(ccmode_ctr, ctr))(ccctr_ctx *ctx, size_t nbytes, const void *in, void *out); 113 const void *custom; 114 }; 115 116 // 5- OFB mode, stateless 117 cc_aligned_struct(16) ccofb_ctx; 118 119 struct ccmode_ofb { 120 size_t size; /* first argument to ccofb_ctx_decl(). */ 121 size_t block_size; 122 int (*CC_SPTR(ccmode_ofb, 123 init))(const struct ccmode_ofb *ofb, ccofb_ctx *ctx, size_t key_len, const void *key, const void *iv); 124 int (*CC_SPTR(ccmode_ofb, ofb))(ccofb_ctx *ctx, size_t nbytes, const void *in, void *out); 125 const void *custom; 126 }; 127 128 // 6- XTS mode, stateless 129 cc_aligned_struct(16) ccxts_ctx; 130 cc_aligned_struct(16) ccxts_tweak; 131 132 struct ccmode_xts { 133 size_t size; /* first argument to ccxts_ctx_decl(). Size of the ctx data structure */ 134 size_t tweak_size; /* first argument to ccxts_tweak_decl(). Size of the tweak structure, not the expected tweak size */ 135 size_t block_size; 136 137 /* Create a xts key from a xts mode object. 138 key must point to at least 'size' bytes of free storage. 139 tweak_key must point to at least 'tweak_size' bytes of free storage. 140 key and tweak_key must differ. 141 Returns nonzero on failure. 142 */ 143 int (*CC_SPTR(ccmode_xts, init))(const struct ccmode_xts *xts, 144 ccxts_ctx *ctx, 145 size_t key_nbytes, 146 const void *data_key, 147 const void *tweak_key); 148 149 void (*CC_SPTR(ccmode_xts, key_sched))(const struct ccmode_xts *xts, 150 ccxts_ctx *ctx, 151 size_t key_nbytes, 152 const void *data_key, 153 const void *tweak_key); 154 155 /* Set the tweak (sector number), the block within the sector zero. */ 156 int (*CC_SPTR(ccmode_xts, set_tweak))(const ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv); 157 158 /* Encrypt blocks for a sector, clients must call set_tweak before calling 159 this function. Return a pointer to the tweak buffer */ 160 void *(*CC_SPTR(ccmode_xts, xts))(const ccxts_ctx *ctx, ccxts_tweak *tweak, size_t nblocks, const void *in, void *out); 161 162 const void *custom; 163 const void *custom1; 164 cc_impl_t impl; 165 }; 166 167 // 7- GCM mode, statful 168 cc_aligned_struct(16) ccgcm_ctx; 169 #define CCMODE_GCM_DECRYPTOR 78647 170 #define CCMODE_GCM_ENCRYPTOR 4073947 171 172 struct ccmode_gcm { 173 size_t size; /* first argument to ccgcm_ctx_decl(). */ 174 int encdec; // is it encrypt or decrypt object 175 size_t block_size; 176 int (*CC_SPTR(ccmode_gcm, init))(const struct ccmode_gcm *gcm, ccgcm_ctx *ctx, size_t key_nbytes, const void *key); 177 int (*CC_SPTR(ccmode_gcm, set_iv))(ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv); 178 int (*CC_SPTR(ccmode_gcm, gmac))(ccgcm_ctx *ctx, size_t nbytes, const void *in); // could just be gcm with NULL out 179 int (*CC_SPTR(ccmode_gcm, gcm))(ccgcm_ctx *ctx, size_t nbytes, const void *in, void *out); 180 int (*CC_SPTR(ccmode_gcm, finalize))(ccgcm_ctx *key, size_t tag_nbytes, void *tag); 181 int (*CC_SPTR(ccmode_gcm, reset))(ccgcm_ctx *ctx); 182 const void *custom; 183 }; 184 185 // 8- CCM mode, stateful 186 cc_aligned_struct(16) ccccm_ctx; 187 cc_aligned_struct(16) ccccm_nonce; 188 189 struct ccmode_ccm { 190 size_t size; /* first argument to ccccm_ctx_decl(). */ 191 size_t nonce_size; /* first argument to ccccm_nonce_decl(). */ 192 size_t block_size; 193 int (*CC_SPTR(ccmode_ccm, init))(const struct ccmode_ccm *ccm, ccccm_ctx *ctx, size_t key_len, const void *key); 194 int (*CC_SPTR(ccmode_ccm, set_iv))(ccccm_ctx *ctx, 195 ccccm_nonce *nonce_ctx, 196 size_t nonce_len, 197 const void *nonce, 198 size_t mac_size, 199 size_t auth_len, 200 size_t data_len); 201 int (*CC_SPTR(ccmode_ccm, cbcmac))(ccccm_ctx *ctx, 202 ccccm_nonce *nonce_ctx, 203 size_t nbytes, 204 const void *in); // could just be ccm with NULL out 205 int (*CC_SPTR(ccmode_ccm, ccm))(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out); 206 int (*CC_SPTR(ccmode_ccm, finalize))(ccccm_ctx *key, ccccm_nonce *nonce_ctx, void *mac); 207 int (*CC_SPTR(ccmode_ccm, reset))(ccccm_ctx *key, ccccm_nonce *nonce_ctx); 208 const void *custom; 209 bool enc_mode; 210 }; 211 212 /* We need to expose this (currently)to keep CommonCrypto happy. */ 213 struct _ccmode_ccm_nonce { 214 unsigned char A_i[16]; /* crypto block iv */ 215 unsigned char B_i[16]; /* mac block iv */ 216 unsigned char MAC[16]; /* crypted mac */ 217 unsigned char buf[16]; /* crypt buffer */ 218 219 uint32_t mode; /* mode: IV -> AD -> DATA */ 220 uint32_t buflen; /* length of data in buf */ 221 uint32_t b_i_len; /* length of cbcmac data in B_i */ 222 223 size_t nonce_size; 224 size_t mac_size; 225 }; 226 227 /* OMAC mode. */ 228 cc_aligned_struct(16) ccomac_ctx; 229 230 struct ccmode_omac { 231 size_t size; /* first argument to ccomac_ctx_decl(). */ 232 size_t block_size; 233 int (*CC_SPTR(ccmode_omac, 234 init))(const struct ccmode_omac *omac, ccomac_ctx *ctx, size_t tweak_len, size_t key_len, const void *key); 235 int (*CC_SPTR(ccmode_omac, omac))(ccomac_ctx *ctx, size_t nblocks, const void *tweak, const void *in, void *out); 236 const void *custom; 237 }; 238 239 /* This provide an implementation of SIV 240 as specified in https://tools.ietf.org/html/rfc5297 241 also in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/siv/siv.pdf 242 Counter Mode where IV is based on CMAC 243 */ 244 245 cc_aligned_struct(16) ccsiv_ctx; 246 247 struct ccmode_siv { 248 size_t size; /* first argument to ccsiv_ctx_decl(). */ 249 size_t block_size; 250 int (*CC_SPTR(ccmode_siv, init))(const struct ccmode_siv *siv, ccsiv_ctx *ctx, 251 size_t key_len, const uint8_t *key); 252 int (*CC_SPTR(ccmode_siv, set_nonce))(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out 253 int (*CC_SPTR(ccmode_siv, auth))(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out 254 int (*CC_SPTR(ccmode_siv, crypt))(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out); 255 int (*CC_SPTR(ccmode_siv, reset))(ccsiv_ctx *ctx); 256 const struct ccmode_cbc *cbc; 257 const struct ccmode_ctr *ctr; 258 }; 259 260 /* This provides an implementation of SIV using AES CTR mode with HMAC as the MAC, 261 allowing for a tagging mechanism with collision resistant tags. This is a modification of the 262 standard specified in https://tools.ietf.org/html/rfc5297 263 also in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/siv/siv.pdf 264 Counter Mode where IV is based on HMAC. 265 */ 266 267 cc_aligned_struct(16) ccsiv_hmac_ctx; 268 269 struct ccmode_siv_hmac { 270 size_t size; /* first argument to ccsiv_hmac_ctx_decl(). */ 271 size_t block_size; 272 273 int (*CC_SPTR(ccmode_siv_hmac, init))(const struct ccmode_siv_hmac *sivhmac, 274 ccsiv_hmac_ctx *ctx, 275 size_t key_len, 276 const uint8_t *key, 277 const size_t tag_size); 278 int (*CC_SPTR(ccmode_siv_hmac, set_nonce))(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in); 279 int (*CC_SPTR(ccmode_siv_hmac, auth))(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in); 280 int (*CC_SPTR(ccmode_siv_hmac, crypt))(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out); 281 int (*CC_SPTR(ccmode_siv_hmac, reset))(ccsiv_hmac_ctx *ctx); 282 const struct ccdigest_info *hmac_digest; // Digest to be used in HMAC; 283 const struct ccmode_ctr *ctr; 284 }; 285 286 #endif /* _CORECRYPTO_CCMODE_IMPL_H_ */ 287