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