xref: /freebsd/sys/contrib/openzfs/module/icp/include/modes/modes.h (revision 53a2e2635ab2d17bed1de7b4e0d782dd23ceb6ea)
161145dc2SMartin Matuska // SPDX-License-Identifier: CDDL-1.0
2eda14cbcSMatt Macy /*
3eda14cbcSMatt Macy  * CDDL HEADER START
4eda14cbcSMatt Macy  *
5eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
6eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
7eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
8eda14cbcSMatt Macy  *
9eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10271171e0SMartin Matuska  * or https://opensource.org/licenses/CDDL-1.0.
11eda14cbcSMatt Macy  * See the License for the specific language governing permissions
12eda14cbcSMatt Macy  * and limitations under the License.
13eda14cbcSMatt Macy  *
14eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
15eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
17eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
18eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
19eda14cbcSMatt Macy  *
20eda14cbcSMatt Macy  * CDDL HEADER END
21eda14cbcSMatt Macy  */
22eda14cbcSMatt Macy /*
23eda14cbcSMatt Macy  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24eda14cbcSMatt Macy  * Use is subject to license terms.
25eda14cbcSMatt Macy  */
26eda14cbcSMatt Macy 
27eda14cbcSMatt Macy #ifndef	_COMMON_CRYPTO_MODES_H
28eda14cbcSMatt Macy #define	_COMMON_CRYPTO_MODES_H
29eda14cbcSMatt Macy 
30eda14cbcSMatt Macy #ifdef	__cplusplus
31eda14cbcSMatt Macy extern "C" {
32eda14cbcSMatt Macy #endif
33eda14cbcSMatt Macy 
34eda14cbcSMatt Macy #include <sys/zfs_context.h>
35eda14cbcSMatt Macy #include <sys/crypto/common.h>
36eda14cbcSMatt Macy #include <sys/crypto/impl.h>
37eda14cbcSMatt Macy 
38eda14cbcSMatt Macy /*
39eda14cbcSMatt Macy  * Does the build chain support all instructions needed for the GCM assembler
40eda14cbcSMatt Macy  * routines. AVX support should imply AES-NI and PCLMULQDQ, but make sure
41eda14cbcSMatt Macy  * anyhow.
42eda14cbcSMatt Macy  */
43eda14cbcSMatt Macy #if defined(__x86_64__) && defined(HAVE_AVX) && \
44eda14cbcSMatt Macy     defined(HAVE_AES) && defined(HAVE_PCLMULQDQ)
45*53a2e263SMartin Matuska #define	CAN_USE_GCM_ASM (HAVE_VAES && HAVE_VPCLMULQDQ ? 2 : 1)
46eda14cbcSMatt Macy extern boolean_t gcm_avx_can_use_movbe;
47eda14cbcSMatt Macy #endif
48eda14cbcSMatt Macy 
49eda14cbcSMatt Macy #define	CCM_MODE			0x00000010
50eda14cbcSMatt Macy #define	GCM_MODE			0x00000020
51eda14cbcSMatt Macy 
52eda14cbcSMatt Macy /*
53eda14cbcSMatt Macy  * cc_keysched:		Pointer to key schedule.
54eda14cbcSMatt Macy  *
55eda14cbcSMatt Macy  * cc_keysched_len:	Length of the key schedule.
56eda14cbcSMatt Macy  *
57eda14cbcSMatt Macy  * cc_remainder:	This is for residual data, i.e. data that can't
58eda14cbcSMatt Macy  *			be processed because there are too few bytes.
59eda14cbcSMatt Macy  *			Must wait until more data arrives.
60eda14cbcSMatt Macy  *
61eda14cbcSMatt Macy  * cc_remainder_len:	Number of bytes in cc_remainder.
62eda14cbcSMatt Macy  *
63eda14cbcSMatt Macy  * cc_iv:		Scratch buffer that sometimes contains the IV.
64eda14cbcSMatt Macy  *
65eda14cbcSMatt Macy  * cc_lastp:		Pointer to previous block of ciphertext.
66eda14cbcSMatt Macy  *
67eda14cbcSMatt Macy  * cc_copy_to:		Pointer to where encrypted residual data needs
68eda14cbcSMatt Macy  *			to be copied.
69eda14cbcSMatt Macy  *
70eda14cbcSMatt Macy  * cc_flags:		PROVIDER_OWNS_KEY_SCHEDULE
71eda14cbcSMatt Macy  *			When a context is freed, it is necessary
72eda14cbcSMatt Macy  *			to know whether the key schedule was allocated
73eda14cbcSMatt Macy  *			by the caller, or internally, e.g. an init routine.
74eda14cbcSMatt Macy  *			If allocated by the latter, then it needs to be freed.
75eda14cbcSMatt Macy  *
7675e1fea6SMartin Matuska  *			CCM_MODE
77eda14cbcSMatt Macy  */
78eda14cbcSMatt Macy struct common_ctx {
79eda14cbcSMatt Macy 	void *cc_keysched;
80eda14cbcSMatt Macy 	size_t cc_keysched_len;
81eda14cbcSMatt Macy 	uint64_t cc_iv[2];
82eda14cbcSMatt Macy 	uint64_t cc_remainder[2];
83eda14cbcSMatt Macy 	size_t cc_remainder_len;
84eda14cbcSMatt Macy 	uint8_t *cc_lastp;
85eda14cbcSMatt Macy 	uint8_t *cc_copy_to;
86eda14cbcSMatt Macy 	uint32_t cc_flags;
87eda14cbcSMatt Macy };
88eda14cbcSMatt Macy 
89eda14cbcSMatt Macy typedef struct common_ctx common_ctx_t;
90eda14cbcSMatt Macy 
91eda14cbcSMatt Macy /*
92eda14cbcSMatt Macy  *
93eda14cbcSMatt Macy  * ccm_mac_len:		Stores length of the MAC in CCM mode.
94eda14cbcSMatt Macy  * ccm_mac_buf:		Stores the intermediate value for MAC in CCM encrypt.
95eda14cbcSMatt Macy  *			In CCM decrypt, stores the input MAC value.
96eda14cbcSMatt Macy  * ccm_data_len:	Length of the plaintext for CCM mode encrypt, or
97eda14cbcSMatt Macy  *			length of the ciphertext for CCM mode decrypt.
98eda14cbcSMatt Macy  * ccm_processed_data_len:
99eda14cbcSMatt Macy  *			Length of processed plaintext in CCM mode encrypt,
100eda14cbcSMatt Macy  *			or length of processed ciphertext for CCM mode decrypt.
101eda14cbcSMatt Macy  * ccm_processed_mac_len:
102eda14cbcSMatt Macy  *			Length of MAC data accumulated in CCM mode decrypt.
103eda14cbcSMatt Macy  *
104eda14cbcSMatt Macy  * ccm_pt_buf:		Only used in CCM mode decrypt.  It stores the
105eda14cbcSMatt Macy  *			decrypted plaintext to be returned when
106eda14cbcSMatt Macy  *			MAC verification succeeds in decrypt_final.
107eda14cbcSMatt Macy  *			Memory for this should be allocated in the AES module.
108eda14cbcSMatt Macy  *
109eda14cbcSMatt Macy  */
110eda14cbcSMatt Macy typedef struct ccm_ctx {
111eda14cbcSMatt Macy 	struct common_ctx ccm_common;
112eda14cbcSMatt Macy 	uint32_t ccm_tmp[4];
113eda14cbcSMatt Macy 	size_t ccm_mac_len;
114eda14cbcSMatt Macy 	uint64_t ccm_mac_buf[2];
115eda14cbcSMatt Macy 	size_t ccm_data_len;
116eda14cbcSMatt Macy 	size_t ccm_processed_data_len;
117eda14cbcSMatt Macy 	size_t ccm_processed_mac_len;
118eda14cbcSMatt Macy 	uint8_t *ccm_pt_buf;
119eda14cbcSMatt Macy 	uint64_t ccm_mac_input_buf[2];
120eda14cbcSMatt Macy 	uint64_t ccm_counter_mask;
121eda14cbcSMatt Macy } ccm_ctx_t;
122eda14cbcSMatt Macy 
123eda14cbcSMatt Macy #define	ccm_keysched		ccm_common.cc_keysched
124eda14cbcSMatt Macy #define	ccm_keysched_len	ccm_common.cc_keysched_len
125eda14cbcSMatt Macy #define	ccm_cb			ccm_common.cc_iv
126eda14cbcSMatt Macy #define	ccm_remainder		ccm_common.cc_remainder
127eda14cbcSMatt Macy #define	ccm_remainder_len	ccm_common.cc_remainder_len
128eda14cbcSMatt Macy #define	ccm_lastp		ccm_common.cc_lastp
129eda14cbcSMatt Macy #define	ccm_copy_to		ccm_common.cc_copy_to
130eda14cbcSMatt Macy #define	ccm_flags		ccm_common.cc_flags
131eda14cbcSMatt Macy 
132*53a2e263SMartin Matuska #ifdef CAN_USE_GCM_ASM
133*53a2e263SMartin Matuska typedef enum gcm_impl {
134*53a2e263SMartin Matuska 	GCM_IMPL_GENERIC = 0,
135*53a2e263SMartin Matuska 	GCM_IMPL_AVX,
136*53a2e263SMartin Matuska 	GCM_IMPL_AVX2,
137*53a2e263SMartin Matuska 	GCM_IMPL_MAX,
138*53a2e263SMartin Matuska } gcm_impl;
139*53a2e263SMartin Matuska #endif
140*53a2e263SMartin Matuska 
141eda14cbcSMatt Macy /*
142eda14cbcSMatt Macy  * gcm_tag_len:		Length of authentication tag.
143eda14cbcSMatt Macy  *
144eda14cbcSMatt Macy  * gcm_ghash:		Stores output from the GHASH function.
145eda14cbcSMatt Macy  *
146eda14cbcSMatt Macy  * gcm_processed_data_len:
147eda14cbcSMatt Macy  *			Length of processed plaintext (encrypt) or
148eda14cbcSMatt Macy  *			length of processed ciphertext (decrypt).
149eda14cbcSMatt Macy  *
150eda14cbcSMatt Macy  * gcm_pt_buf:		Stores the decrypted plaintext returned by
151eda14cbcSMatt Macy  *			decrypt_final when the computed authentication
152eda14cbcSMatt Macy  *			tag matches the	user supplied tag.
153eda14cbcSMatt Macy  *
154eda14cbcSMatt Macy  * gcm_pt_buf_len:	Length of the plaintext buffer.
155eda14cbcSMatt Macy  *
156eda14cbcSMatt Macy  * gcm_H:		Subkey.
157eda14cbcSMatt Macy  *
158eda14cbcSMatt Macy  * gcm_Htable:		Pre-computed and pre-shifted H, H^2, ... H^6 for the
159eda14cbcSMatt Macy  *			Karatsuba Algorithm in host byte order.
160eda14cbcSMatt Macy  *
161eda14cbcSMatt Macy  * gcm_J0:		Pre-counter block generated from the IV.
162eda14cbcSMatt Macy  *
163eda14cbcSMatt Macy  * gcm_len_a_len_c:	64-bit representations of the bit lengths of
164eda14cbcSMatt Macy  *			AAD and ciphertext.
165eda14cbcSMatt Macy  */
166eda14cbcSMatt Macy typedef struct gcm_ctx {
167eda14cbcSMatt Macy 	struct common_ctx gcm_common;
168eda14cbcSMatt Macy 	size_t gcm_tag_len;
169eda14cbcSMatt Macy 	size_t gcm_processed_data_len;
170eda14cbcSMatt Macy 	size_t gcm_pt_buf_len;
171eda14cbcSMatt Macy 	uint32_t gcm_tmp[4];
172eda14cbcSMatt Macy 	/*
1737877fdebSMatt Macy 	 * The offset of gcm_Htable relative to gcm_ghash, (32), is hard coded
1747877fdebSMatt Macy 	 * in aesni-gcm-x86_64.S, so please don't change (or adjust there).
175eda14cbcSMatt Macy 	 */
176eda14cbcSMatt Macy 	uint64_t gcm_ghash[2];
177eda14cbcSMatt Macy 	uint64_t gcm_H[2];
178eda14cbcSMatt Macy #ifdef CAN_USE_GCM_ASM
1797877fdebSMatt Macy 	uint64_t *gcm_Htable;
1807877fdebSMatt Macy 	size_t gcm_htab_len;
181eda14cbcSMatt Macy #endif
182eda14cbcSMatt Macy 	uint64_t gcm_J0[2];
183eda14cbcSMatt Macy 	uint64_t gcm_len_a_len_c[2];
184eda14cbcSMatt Macy 	uint8_t *gcm_pt_buf;
185eda14cbcSMatt Macy #ifdef CAN_USE_GCM_ASM
186*53a2e263SMartin Matuska 	enum gcm_impl impl;
187eda14cbcSMatt Macy #endif
188eda14cbcSMatt Macy } gcm_ctx_t;
189eda14cbcSMatt Macy 
190eda14cbcSMatt Macy #define	gcm_keysched		gcm_common.cc_keysched
191eda14cbcSMatt Macy #define	gcm_keysched_len	gcm_common.cc_keysched_len
192eda14cbcSMatt Macy #define	gcm_cb			gcm_common.cc_iv
193eda14cbcSMatt Macy #define	gcm_remainder		gcm_common.cc_remainder
194eda14cbcSMatt Macy #define	gcm_remainder_len	gcm_common.cc_remainder_len
195eda14cbcSMatt Macy #define	gcm_lastp		gcm_common.cc_lastp
196eda14cbcSMatt Macy #define	gcm_copy_to		gcm_common.cc_copy_to
197eda14cbcSMatt Macy #define	gcm_flags		gcm_common.cc_flags
198eda14cbcSMatt Macy 
1992a58b312SMartin Matuska void gcm_clear_ctx(gcm_ctx_t *ctx);
2002a58b312SMartin Matuska 
201eda14cbcSMatt Macy typedef struct aes_ctx {
202eda14cbcSMatt Macy 	union {
203eda14cbcSMatt Macy 		ccm_ctx_t acu_ccm;
204eda14cbcSMatt Macy 		gcm_ctx_t acu_gcm;
205eda14cbcSMatt Macy 	} acu;
206eda14cbcSMatt Macy } aes_ctx_t;
207eda14cbcSMatt Macy 
20875e1fea6SMartin Matuska #define	ac_flags		acu.acu_ccm.ccm_common.cc_flags
20975e1fea6SMartin Matuska #define	ac_remainder_len	acu.acu_ccm.ccm_common.cc_remainder_len
21075e1fea6SMartin Matuska #define	ac_keysched		acu.acu_ccm.ccm_common.cc_keysched
21175e1fea6SMartin Matuska #define	ac_keysched_len		acu.acu_ccm.ccm_common.cc_keysched_len
21275e1fea6SMartin Matuska #define	ac_iv			acu.acu_ccm.ccm_common.cc_iv
21375e1fea6SMartin Matuska #define	ac_lastp		acu.acu_ccm.ccm_common.cc_lastp
214eda14cbcSMatt Macy #define	ac_pt_buf		acu.acu_ccm.ccm_pt_buf
215eda14cbcSMatt Macy #define	ac_mac_len		acu.acu_ccm.ccm_mac_len
216eda14cbcSMatt Macy #define	ac_data_len		acu.acu_ccm.ccm_data_len
217eda14cbcSMatt Macy #define	ac_processed_mac_len	acu.acu_ccm.ccm_processed_mac_len
218eda14cbcSMatt Macy #define	ac_processed_data_len	acu.acu_ccm.ccm_processed_data_len
219eda14cbcSMatt Macy #define	ac_tag_len		acu.acu_gcm.gcm_tag_len
220eda14cbcSMatt Macy 
221eda14cbcSMatt Macy extern int ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t,
222eda14cbcSMatt Macy     crypto_data_t *, size_t,
223eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
224eda14cbcSMatt Macy     void (*copy_block)(uint8_t *, uint8_t *),
225eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
226eda14cbcSMatt Macy 
227eda14cbcSMatt Macy extern int ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t,
228eda14cbcSMatt Macy     crypto_data_t *, size_t,
229eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
230eda14cbcSMatt Macy     void (*copy_block)(uint8_t *, uint8_t *),
231eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
232eda14cbcSMatt Macy 
233eda14cbcSMatt Macy extern int gcm_mode_encrypt_contiguous_blocks(gcm_ctx_t *, char *, size_t,
234eda14cbcSMatt Macy     crypto_data_t *, size_t,
235eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
236eda14cbcSMatt Macy     void (*copy_block)(uint8_t *, uint8_t *),
237eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
238eda14cbcSMatt Macy 
239eda14cbcSMatt Macy extern int gcm_mode_decrypt_contiguous_blocks(gcm_ctx_t *, char *, size_t,
240eda14cbcSMatt Macy     crypto_data_t *, size_t,
241eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
242eda14cbcSMatt Macy     void (*copy_block)(uint8_t *, uint8_t *),
243eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
244eda14cbcSMatt Macy 
245eda14cbcSMatt Macy int ccm_encrypt_final(ccm_ctx_t *, crypto_data_t *, size_t,
246eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
247eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
248eda14cbcSMatt Macy 
249eda14cbcSMatt Macy int gcm_encrypt_final(gcm_ctx_t *, crypto_data_t *, size_t,
250eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
251eda14cbcSMatt Macy     void (*copy_block)(uint8_t *, uint8_t *),
252eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
253eda14cbcSMatt Macy 
254eda14cbcSMatt Macy extern int ccm_decrypt_final(ccm_ctx_t *, crypto_data_t *, size_t,
255eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
256eda14cbcSMatt Macy     void (*copy_block)(uint8_t *, uint8_t *),
257eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
258eda14cbcSMatt Macy 
259eda14cbcSMatt Macy extern int gcm_decrypt_final(gcm_ctx_t *, crypto_data_t *, size_t,
260eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
261eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
262eda14cbcSMatt Macy 
263eda14cbcSMatt Macy extern int ccm_init_ctx(ccm_ctx_t *, char *, int, boolean_t, size_t,
264eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
265eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
266eda14cbcSMatt Macy 
267eda14cbcSMatt Macy extern int gcm_init_ctx(gcm_ctx_t *, char *, size_t,
268eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
269eda14cbcSMatt Macy     void (*copy_block)(uint8_t *, uint8_t *),
270eda14cbcSMatt Macy     void (*xor_block)(uint8_t *, uint8_t *));
271eda14cbcSMatt Macy 
272eda14cbcSMatt Macy extern void calculate_ccm_mac(ccm_ctx_t *, uint8_t *,
273eda14cbcSMatt Macy     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *));
274eda14cbcSMatt Macy 
275eda14cbcSMatt Macy extern void gcm_mul(uint64_t *, uint64_t *, uint64_t *);
276eda14cbcSMatt Macy 
277eda14cbcSMatt Macy extern void crypto_init_ptrs(crypto_data_t *, void **, offset_t *);
278eda14cbcSMatt Macy extern void crypto_get_ptrs(crypto_data_t *, void **, offset_t *,
279eda14cbcSMatt Macy     uint8_t **, size_t *, uint8_t **, size_t);
280eda14cbcSMatt Macy 
281eda14cbcSMatt Macy extern void *ccm_alloc_ctx(int);
282eda14cbcSMatt Macy extern void *gcm_alloc_ctx(int);
283eda14cbcSMatt Macy extern void crypto_free_mode_ctx(void *);
284eda14cbcSMatt Macy 
285eda14cbcSMatt Macy #ifdef	__cplusplus
286eda14cbcSMatt Macy }
287eda14cbcSMatt Macy #endif
288eda14cbcSMatt Macy 
289eda14cbcSMatt Macy #endif	/* _COMMON_CRYPTO_MODES_H */
290