| 1 | /* |
| 2 | * ccmode_impl.h |
| 3 | * corecrypto |
| 4 | * |
| 5 | * Created on 12/07/2010 |
| 6 | * |
| 7 | * Copyright (c) 2012,2015 Apple Inc. All rights reserved. |
| 8 | * |
| 9 | */ |
| 10 | |
| 11 | #ifndef _CORECRYPTO_CCMODE_IMPL_H_ |
| 12 | #define _CORECRYPTO_CCMODE_IMPL_H_ |
| 13 | |
| 14 | #include <corecrypto/cc.h> |
| 15 | |
| 16 | /* ECB mode. */ |
| 17 | cc_aligned_struct(16) ccecb_ctx; |
| 18 | |
| 19 | |
| 20 | /* Actual symmetric algorithm implementation should provide you one of these. */ |
| 21 | struct ccmode_ecb { |
| 22 | size_t size; /* first argument to ccecb_ctx_decl(). */ |
| 23 | size_t block_size; |
| 24 | int (*init)(const struct ccmode_ecb *ecb, ccecb_ctx *ctx, |
| 25 | size_t key_nbytes, const void *key); |
| 26 | int (*ecb)(const ccecb_ctx *ctx, size_t nblocks, const void *in, |
| 27 | void *out); |
| 28 | }; |
| 29 | |
| 30 | /*! |
| 31 | * @brief corecrypto symmetrical encryption and decryption modes |
| 32 | * |
| 33 | * corecrypto supports 6 stateless en(de)cryption modes and 2 stateful authenticated en(de)cryption modes |
| 34 | * stateless modes CBC, CFB, CFB8, CTR, OFB, XTS: They provide 3 interface functions that do not return errors codes |
| 35 | * 1- ccmod_xxx_init() |
| 36 | * 2- ccmod_xxx_decrypt() |
| 37 | * 3- ccmod_xxx_encrypt() |
| 38 | * |
| 39 | * stateful modes CCM and GCM: They provide 7 interface functions that return error codes if a function is called out of state |
| 40 | * 1- ccmod_xxx_init() |
| 41 | * 2- ccmod_xxx_setiv() |
| 42 | * 3- ccmod_xxx_aad() |
| 43 | * 4- ccmod_xxx_decrypt() |
| 44 | * 5- ccmod_xxx_encrypt() |
| 45 | * 6- ccmod_xxx_finalize() |
| 46 | * 7- ccmod_xxx_reset() |
| 47 | * |
| 48 | * the correct call sequences are: |
| 49 | * |
| 50 | * calls to 1, 2 and 6 arerequired |
| 51 | * 2 and 3 can be called as mant times as needed |
| 52 | * calls to 3, 4, 5 can be skipped |
| 53 | * |
| 54 | * 1, 2*n, 3*n, 4|5, 6 |
| 55 | * 1, 2*n, , 4|5, 6 |
| 56 | * 1, 2*n, , , 6 |
| 57 | * 1, 2*n, 3*n, , 6 |
| 58 | */ |
| 59 | |
| 60 | // 1- CBC mode, stateless |
| 61 | cc_aligned_struct(16) cccbc_ctx; |
| 62 | cc_aligned_struct(16) cccbc_iv; |
| 63 | |
| 64 | struct ccmode_cbc { |
| 65 | size_t size; /* first argument to cccbc_ctx_decl(). */ |
| 66 | size_t block_size; |
| 67 | int (*init)(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, |
| 68 | size_t key_len, const void *key); |
| 69 | /* cbc encrypt or decrypt nblocks from in to out, iv will be used and updated. */ |
| 70 | int (*cbc)(const cccbc_ctx *ctx, cccbc_iv *iv, |
| 71 | 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 (*init)(const struct ccmode_cfb *cfb, cccfb_ctx *ctx, |
| 82 | size_t key_len, const void *key, const void *iv); |
| 83 | int (*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 (*init)(const struct ccmode_cfb8 *cfb8, cccfb8_ctx *ctx, |
| 94 | size_t key_len, const void *key, const void *iv); |
| 95 | int (*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 (*init)(const struct ccmode_ctr *mode, ccctr_ctx *ctx, |
| 107 | size_t key_len, const void *key, const void *iv); |
| 108 | int (*setctr)(const struct ccmode_ctr *mode, ccctr_ctx *ctx, const void *ctr); |
| 109 | int (*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 (*init)(const struct ccmode_ofb *ofb, ccofb_ctx *ctx, |
| 120 | size_t key_len, const void *key, const void *iv); |
| 121 | int (*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 (*init)(const struct ccmode_xts *xts, ccxts_ctx *ctx, |
| 141 | size_t key_nbytes, const void *data_key, const void *tweak_key); |
| 142 | |
| 143 | void (*key_sched)(const struct ccmode_xts *xts, ccxts_ctx *ctx, |
| 144 | size_t key_nbytes, const void *data_key, const void *tweak_key); |
| 145 | |
| 146 | /* Set the tweak (sector number), the block within the sector zero. */ |
| 147 | int (*set_tweak)(const ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv); |
| 148 | |
| 149 | /* Encrypt blocks for a sector, clients must call set_tweak before calling |
| 150 | this function. Return a pointer to the tweak buffer */ |
| 151 | void *(*xts)(const ccxts_ctx *ctx, ccxts_tweak *tweak, |
| 152 | size_t nblocks, const void *in, void *out); |
| 153 | |
| 154 | const void *custom; |
| 155 | const void *custom1; |
| 156 | }; |
| 157 | |
| 158 | //7- GCM mode, statful |
| 159 | cc_aligned_struct(16) ccgcm_ctx; |
| 160 | #define CCMODE_GCM_DECRYPTOR 78647 |
| 161 | #define CCMODE_GCM_ENCRYPTOR 4073947 |
| 162 | |
| 163 | struct ccmode_gcm { |
| 164 | size_t size; /* first argument to ccgcm_ctx_decl(). */ |
| 165 | int encdec; //is it encrypt or decrypt object |
| 166 | size_t block_size; |
| 167 | int (*init)(const struct ccmode_gcm *gcm, ccgcm_ctx *ctx, |
| 168 | size_t key_nbytes, const void *key); |
| 169 | int (*set_iv)(ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv); |
| 170 | int (*gmac)(ccgcm_ctx *ctx, size_t nbytes, const void *in); // could just be gcm with NULL out |
| 171 | int (*gcm)(ccgcm_ctx *ctx, size_t nbytes, const void *in, void *out); |
| 172 | int (*finalize)(ccgcm_ctx *key, size_t tag_nbytes, void *tag); |
| 173 | int (*reset)(ccgcm_ctx *ctx); |
| 174 | const void *custom; |
| 175 | }; |
| 176 | |
| 177 | //8- CCM mode, stateful |
| 178 | cc_aligned_struct(16) ccccm_ctx; |
| 179 | cc_aligned_struct(16) ccccm_nonce; |
| 180 | |
| 181 | struct ccmode_ccm { |
| 182 | size_t size; /* first argument to ccccm_ctx_decl(). */ |
| 183 | size_t nonce_size; /* first argument to ccccm_nonce_decl(). */ |
| 184 | size_t block_size; |
| 185 | int (*init)(const struct ccmode_ccm *ccm, ccccm_ctx *ctx, |
| 186 | size_t key_len, const void *key); |
| 187 | int (*set_iv)(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nonce_len, const void *nonce, |
| 188 | size_t mac_size, size_t auth_len, size_t data_len); |
| 189 | int (*cbcmac)(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in); // could just be ccm with NULL out |
| 190 | int (*ccm)(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out); |
| 191 | int (*finalize)(ccccm_ctx *key, ccccm_nonce *nonce_ctx, void *mac); |
| 192 | int (*reset)(ccccm_ctx *key, ccccm_nonce *nonce_ctx); |
| 193 | const void *custom; |
| 194 | }; |
| 195 | |
| 196 | /* We need to expose this (currently)to keep CommonCrypto happy. */ |
| 197 | struct _ccmode_ccm_nonce { |
| 198 | unsigned char A_i[16]; /* crypto block iv */ |
| 199 | unsigned char B_i[16]; /* mac block iv */ |
| 200 | unsigned char MAC[16]; /* crypted mac */ |
| 201 | unsigned char buf[16]; /* crypt buffer */ |
| 202 | |
| 203 | uint32_t mode; /* mode: IV -> AD -> DATA */ |
| 204 | uint32_t buflen; /* length of data in buf */ |
| 205 | uint32_t b_i_len; /* length of cbcmac data in B_i */ |
| 206 | |
| 207 | size_t nonce_size; |
| 208 | size_t mac_size; |
| 209 | }; |
| 210 | |
| 211 | /* OMAC mode. */ |
| 212 | cc_aligned_struct(16) ccomac_ctx; |
| 213 | |
| 214 | struct ccmode_omac { |
| 215 | size_t size; /* first argument to ccomac_ctx_decl(). */ |
| 216 | size_t block_size; |
| 217 | int (*init)(const struct ccmode_omac *omac, ccomac_ctx *ctx, |
| 218 | size_t tweak_len, size_t key_len, const void *key); |
| 219 | int (*omac)(ccomac_ctx *ctx, size_t nblocks, |
| 220 | const void *tweak, const void *in, void *out); |
| 221 | const void *custom; |
| 222 | }; |
| 223 | |
| 224 | #endif /* _CORECRYPTO_CCMODE_IMPL_H_ */ |
| 225 | |