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. */
19cc_aligned_struct(16) ccecb_ctx;
20
21/* Actual symmetric algorithm implementation should provide you one of these. */
22struct 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
62cc_aligned_struct(16) cccbc_ctx;
63cc_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
69struct 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
79cc_aligned_struct(16) cccfb_ctx;
80
81struct 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
91cc_aligned_struct(16) cccfb8_ctx;
92
93struct 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
103cc_aligned_struct(16) ccctr_ctx;
104
105struct 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
117cc_aligned_struct(16) ccofb_ctx;
118
119struct 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
129cc_aligned_struct(16) ccxts_ctx;
130cc_aligned_struct(16) ccxts_tweak;
131
132struct 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
168cc_aligned_struct(16) ccgcm_ctx;
169#define CCMODE_GCM_DECRYPTOR 78647
170#define CCMODE_GCM_ENCRYPTOR 4073947
171
172struct 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
186cc_aligned_struct(16) ccccm_ctx;
187cc_aligned_struct(16) ccccm_nonce;
188
189struct 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. */
213struct _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. */
228cc_aligned_struct(16) ccomac_ctx;
229
230struct 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
245cc_aligned_struct(16) ccsiv_ctx;
246
247struct 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
267cc_aligned_struct(16) ccsiv_hmac_ctx;
268
269struct 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