17188Smcpowers /*
27188Smcpowers  * CDDL HEADER START
37188Smcpowers  *
47188Smcpowers  * The contents of this file are subject to the terms of the
57188Smcpowers  * Common Development and Distribution License (the "License").
67188Smcpowers  * You may not use this file except in compliance with the License.
77188Smcpowers  *
87188Smcpowers  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97188Smcpowers  * or http://www.opensolaris.org/os/licensing.
107188Smcpowers  * See the License for the specific language governing permissions
117188Smcpowers  * and limitations under the License.
127188Smcpowers  *
137188Smcpowers  * When distributing Covered Code, include this CDDL HEADER in each
147188Smcpowers  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157188Smcpowers  * If applicable, add the following below this CDDL HEADER, with the
167188Smcpowers  * fields enclosed by brackets "[]" replaced with your own identifying
177188Smcpowers  * information: Portions Copyright [yyyy] [name of copyright owner]
187188Smcpowers  *
197188Smcpowers  * CDDL HEADER END
207188Smcpowers  */
217188Smcpowers /*
227188Smcpowers  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237188Smcpowers  * Use is subject to license terms.
247188Smcpowers  */
257188Smcpowers 
267188Smcpowers #ifndef	_COMMON_CRYPTO_MODES_H
277188Smcpowers #define	_COMMON_CRYPTO_MODES_H
287188Smcpowers 
297188Smcpowers #ifdef	__cplusplus
307188Smcpowers extern "C" {
317188Smcpowers #endif
327188Smcpowers 
337188Smcpowers #include <sys/strsun.h>
347188Smcpowers #include <sys/systm.h>
357188Smcpowers #include <sys/sysmacros.h>
367188Smcpowers #include <sys/types.h>
377188Smcpowers #include <sys/errno.h>
387188Smcpowers #include <sys/rwlock.h>
397188Smcpowers #include <sys/kmem.h>
407188Smcpowers #include <sys/crypto/common.h>
417188Smcpowers #include <sys/crypto/impl.h>
427188Smcpowers 
437188Smcpowers #define	ECB_MODE			0x00000002
447188Smcpowers #define	CBC_MODE			0x00000004
457188Smcpowers #define	CTR_MODE			0x00000008
467188Smcpowers #define	CCM_MODE			0x00000010
477188Smcpowers 
487188Smcpowers /*
497188Smcpowers  * cc_keysched:		Pointer to key schedule.
507188Smcpowers  *
517188Smcpowers  * cc_keysched_len:	Length of the key schedule.
527188Smcpowers  *
537188Smcpowers  * cc_remainder:	This is for residual data, i.e. data that can't
547188Smcpowers  *			be processed because there are too few bytes.
557188Smcpowers  *			Must wait until more data arrives.
567188Smcpowers  *
577188Smcpowers  * cc_remainder_len:	Number of bytes in cc_remainder.
587188Smcpowers  *
597188Smcpowers  * cc_iv:		Scratch buffer that sometimes contains the IV.
607188Smcpowers  *
617188Smcpowers  * cc_lastp:		Pointer to previous block of ciphertext.
627188Smcpowers  *
637188Smcpowers  * cc_copy_to:		Pointer to where encrypted residual data needs
647188Smcpowers  *			to be copied.
657188Smcpowers  *
667188Smcpowers  * cc_flags:		PROVIDER_OWNS_KEY_SCHEDULE
677188Smcpowers  *			When a context is freed, it is necessary
687188Smcpowers  *			to know whether the key schedule was allocated
697188Smcpowers  *			by the caller, or internally, e.g. an init routine.
707188Smcpowers  *			If allocated by the latter, then it needs to be freed.
717188Smcpowers  *
727188Smcpowers  *			ECB_MODE, CBC_MODE, CTR_MODE, or CCM_MODE
737188Smcpowers  */
747188Smcpowers struct common_ctx {
757188Smcpowers 	void *cc_keysched;
767188Smcpowers 	size_t cc_keysched_len;
777188Smcpowers 	uint64_t cc_iv[2];
787188Smcpowers 	uint64_t cc_remainder[2];
797188Smcpowers 	size_t cc_remainder_len;
807188Smcpowers 	uint8_t *cc_lastp;
817188Smcpowers 	uint8_t *cc_copy_to;
827188Smcpowers 	uint32_t cc_flags;
837188Smcpowers };
847188Smcpowers 
857188Smcpowers typedef struct common_ctx common_ctx_t;
867188Smcpowers 
87*7581SMark.Powers@Sun.COM typedef struct ecb_ctx {
88*7581SMark.Powers@Sun.COM 	struct common_ctx ecb_common;
89*7581SMark.Powers@Sun.COM 	uint64_t ecb_lastblock[2];
90*7581SMark.Powers@Sun.COM } ecb_ctx_t;
91*7581SMark.Powers@Sun.COM 
92*7581SMark.Powers@Sun.COM #define	ecb_keysched		ecb_common.cc_keysched
93*7581SMark.Powers@Sun.COM #define	ecb_keysched_len	ecb_common.cc_keysched_len
94*7581SMark.Powers@Sun.COM #define	ecb_iv			ecb_common.cc_iv
95*7581SMark.Powers@Sun.COM #define	ecb_remainder		ecb_common.cc_remainder
96*7581SMark.Powers@Sun.COM #define	ecb_remainder_len	ecb_common.cc_remainder_len
97*7581SMark.Powers@Sun.COM #define	ecb_lastp		ecb_common.cc_lastp
98*7581SMark.Powers@Sun.COM #define	ecb_copy_to		ecb_common.cc_copy_to
99*7581SMark.Powers@Sun.COM #define	ecb_flags		ecb_common.cc_flags
100*7581SMark.Powers@Sun.COM 
101*7581SMark.Powers@Sun.COM typedef struct cbc_ctx {
102*7581SMark.Powers@Sun.COM 	struct common_ctx cbc_common;
103*7581SMark.Powers@Sun.COM 	uint64_t cbc_lastblock[2];
104*7581SMark.Powers@Sun.COM } cbc_ctx_t;
105*7581SMark.Powers@Sun.COM 
106*7581SMark.Powers@Sun.COM #define	cbc_keysched		cbc_common.cc_keysched
107*7581SMark.Powers@Sun.COM #define	cbc_keysched_len	cbc_common.cc_keysched_len
108*7581SMark.Powers@Sun.COM #define	cbc_iv			cbc_common.cc_iv
109*7581SMark.Powers@Sun.COM #define	cbc_remainder		cbc_common.cc_remainder
110*7581SMark.Powers@Sun.COM #define	cbc_remainder_len	cbc_common.cc_remainder_len
111*7581SMark.Powers@Sun.COM #define	cbc_lastp		cbc_common.cc_lastp
112*7581SMark.Powers@Sun.COM #define	cbc_copy_to		cbc_common.cc_copy_to
113*7581SMark.Powers@Sun.COM #define	cbc_flags		cbc_common.cc_flags
114*7581SMark.Powers@Sun.COM 
115*7581SMark.Powers@Sun.COM /*
116*7581SMark.Powers@Sun.COM  * ctr_lower_mask		Bit-mask for lower 8 bytes of counter block.
117*7581SMark.Powers@Sun.COM  * ctr_upper_mask		Bit-mask for upper 8 bytes of counter block.
118*7581SMark.Powers@Sun.COM  */
1197188Smcpowers typedef struct ctr_ctx {
1207188Smcpowers 	struct common_ctx ctr_common;
121*7581SMark.Powers@Sun.COM 	uint64_t ctr_lower_mask;
122*7581SMark.Powers@Sun.COM 	uint64_t ctr_upper_mask;
1237188Smcpowers 	uint32_t ctr_tmp[4];
1247188Smcpowers } ctr_ctx_t;
1257188Smcpowers 
1267188Smcpowers /*
127*7581SMark.Powers@Sun.COM  * ctr_cb			Counter block.
1287188Smcpowers  */
1297188Smcpowers #define	ctr_keysched		ctr_common.cc_keysched
1307188Smcpowers #define	ctr_keysched_len	ctr_common.cc_keysched_len
1317188Smcpowers #define	ctr_cb			ctr_common.cc_iv
1327188Smcpowers #define	ctr_remainder		ctr_common.cc_remainder
1337188Smcpowers #define	ctr_remainder_len	ctr_common.cc_remainder_len
1347188Smcpowers #define	ctr_lastp		ctr_common.cc_lastp
1357188Smcpowers #define	ctr_copy_to		ctr_common.cc_copy_to
1367188Smcpowers #define	ctr_flags		ctr_common.cc_flags
1377188Smcpowers 
1387188Smcpowers /*
1397188Smcpowers  *
1407188Smcpowers  * ccm_mac_len:		Stores length of the MAC in CCM mode.
1417188Smcpowers  * ccm_mac_buf:		Stores the intermediate value for MAC in CCM encrypt.
1427188Smcpowers  *			In CCM decrypt, stores the input MAC value.
1437188Smcpowers  * ccm_data_len:	Length of the plaintext for CCM mode encrypt, or
1447188Smcpowers  *			length of the ciphertext for CCM mode decrypt.
1457188Smcpowers  * ccm_processed_data_len:
1467188Smcpowers  *			Length of processed plaintext in CCM mode encrypt,
1477188Smcpowers  *			or length of processed ciphertext for CCM mode decrypt.
1487188Smcpowers  * ccm_processed_mac_len:
1497188Smcpowers  *			Length of MAC data accumulated in CCM mode decrypt.
1507188Smcpowers  *
1517188Smcpowers  * ccm_pt_buf:		Only used in CCM mode decrypt.  It stores the
1527188Smcpowers  *			decrypted plaintext to be returned when
1537188Smcpowers  *			MAC verification succeeds in decrypt_final.
1547188Smcpowers  *			Memory for this should be allocated in the AES module.
1557188Smcpowers  *
1567188Smcpowers  */
1577188Smcpowers typedef struct ccm_ctx {
1587188Smcpowers 	struct common_ctx ccm_common;
1597188Smcpowers 	uint32_t ccm_tmp[4];
1607188Smcpowers 	size_t ccm_mac_len;
1617188Smcpowers 	uint64_t ccm_mac_buf[2];
1627188Smcpowers 	size_t ccm_data_len;
1637188Smcpowers 	size_t ccm_processed_data_len;
1647188Smcpowers 	size_t ccm_processed_mac_len;
1657188Smcpowers 	uint8_t *ccm_pt_buf;
1667188Smcpowers 	uint64_t ccm_mac_input_buf[2];
167*7581SMark.Powers@Sun.COM 	uint64_t ccm_counter_mask;
1687188Smcpowers } ccm_ctx_t;
1697188Smcpowers 
1707188Smcpowers #define	ccm_keysched		ccm_common.cc_keysched
1717188Smcpowers #define	ccm_keysched_len	ccm_common.cc_keysched_len
1727188Smcpowers #define	ccm_cb			ccm_common.cc_iv
1737188Smcpowers #define	ccm_remainder		ccm_common.cc_remainder
1747188Smcpowers #define	ccm_remainder_len	ccm_common.cc_remainder_len
1757188Smcpowers #define	ccm_lastp		ccm_common.cc_lastp
1767188Smcpowers #define	ccm_copy_to		ccm_common.cc_copy_to
1777188Smcpowers #define	ccm_flags		ccm_common.cc_flags
1787188Smcpowers 
1797188Smcpowers typedef struct aes_ctx {
1807188Smcpowers 	union {
1817188Smcpowers 		ecb_ctx_t acu_ecb;
1827188Smcpowers 		cbc_ctx_t acu_cbc;
1837188Smcpowers 		ctr_ctx_t acu_ctr;
1847188Smcpowers #ifdef _KERNEL
1857188Smcpowers 		ccm_ctx_t acu_ccm;
1867188Smcpowers #endif
1877188Smcpowers 	} acu;
1887188Smcpowers } aes_ctx_t;
1897188Smcpowers 
190*7581SMark.Powers@Sun.COM #define	ac_flags		acu.acu_ecb.ecb_common.cc_flags
191*7581SMark.Powers@Sun.COM #define	ac_remainder_len	acu.acu_ecb.ecb_common.cc_remainder_len
192*7581SMark.Powers@Sun.COM #define	ac_keysched		acu.acu_ecb.ecb_common.cc_keysched
193*7581SMark.Powers@Sun.COM #define	ac_keysched_len		acu.acu_ecb.ecb_common.cc_keysched_len
194*7581SMark.Powers@Sun.COM #define	ac_iv			acu.acu_ecb.ecb_common.cc_iv
195*7581SMark.Powers@Sun.COM #define	ac_lastp		acu.acu_ecb.ecb_common.cc_lastp
1967188Smcpowers #define	ac_pt_buf		acu.acu_ccm.ccm_pt_buf
1977188Smcpowers #define	ac_mac_len		acu.acu_ccm.ccm_mac_len
1987188Smcpowers #define	ac_data_len		acu.acu_ccm.ccm_data_len
1997188Smcpowers #define	ac_processed_mac_len	acu.acu_ccm.ccm_processed_mac_len
2007188Smcpowers #define	ac_processed_data_len	acu.acu_ccm.ccm_processed_data_len
2017188Smcpowers 
2027188Smcpowers typedef struct blowfish_ctx {
2037188Smcpowers 	union {
2047188Smcpowers 		ecb_ctx_t bcu_ecb;
2057188Smcpowers 		cbc_ctx_t bcu_cbc;
2067188Smcpowers 	} bcu;
2077188Smcpowers } blowfish_ctx_t;
2087188Smcpowers 
209*7581SMark.Powers@Sun.COM #define	bc_flags		bcu.bcu_ecb.ecb_common.cc_flags
210*7581SMark.Powers@Sun.COM #define	bc_remainder_len	bcu.bcu_ecb.ecb_common.cc_remainder_len
211*7581SMark.Powers@Sun.COM #define	bc_keysched		bcu.bcu_ecb.ecb_common.cc_keysched
212*7581SMark.Powers@Sun.COM #define	bc_keysched_len		bcu.bcu_ecb.ecb_common.cc_keysched_len
213*7581SMark.Powers@Sun.COM #define	bc_iv			bcu.bcu_ecb.ecb_common.cc_iv
214*7581SMark.Powers@Sun.COM #define	bc_lastp		bcu.bcu_ecb.ecb_common.cc_lastp
2157188Smcpowers 
2167188Smcpowers typedef struct des_ctx {
2177188Smcpowers 	union {
2187188Smcpowers 		ecb_ctx_t dcu_ecb;
2197188Smcpowers 		cbc_ctx_t dcu_cbc;
2207188Smcpowers 	} dcu;
2217188Smcpowers } des_ctx_t;
2227188Smcpowers 
223*7581SMark.Powers@Sun.COM #define	dc_flags		dcu.dcu_ecb.ecb_common.cc_flags
224*7581SMark.Powers@Sun.COM #define	dc_remainder_len	dcu.dcu_ecb.ecb_common.cc_remainder_len
225*7581SMark.Powers@Sun.COM #define	dc_keysched		dcu.dcu_ecb.ecb_common.cc_keysched
226*7581SMark.Powers@Sun.COM #define	dc_keysched_len		dcu.dcu_ecb.ecb_common.cc_keysched_len
227*7581SMark.Powers@Sun.COM #define	dc_iv			dcu.dcu_ecb.ecb_common.cc_iv
228*7581SMark.Powers@Sun.COM #define	dc_lastp		dcu.dcu_ecb.ecb_common.cc_lastp
2297188Smcpowers 
230*7581SMark.Powers@Sun.COM extern int ecb_cipher_contiguous_blocks(ecb_ctx_t *, char *, size_t,
2317188Smcpowers     crypto_data_t *, size_t, int (*cipher)(const void *, const uint8_t *,
2327188Smcpowers     uint8_t *));
2337188Smcpowers 
2347188Smcpowers extern int cbc_encrypt_contiguous_blocks(cbc_ctx_t *, char *, size_t,
2357188Smcpowers     crypto_data_t *, size_t,
2367188Smcpowers     int (*encrypt)(const void *, const uint8_t *, uint8_t *),
2377188Smcpowers     void (*copy_block)(uint8_t *, uint8_t *),
2387188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2397188Smcpowers 
2407188Smcpowers extern int cbc_decrypt_contiguous_blocks(cbc_ctx_t *, char *, size_t,
2417188Smcpowers     crypto_data_t *, size_t,
2427188Smcpowers     int (*decrypt)(const void *, const uint8_t *, uint8_t *),
2437188Smcpowers     void (*copy_block)(uint8_t *, uint8_t *),
2447188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2457188Smcpowers 
2467188Smcpowers extern int ctr_mode_contiguous_blocks(ctr_ctx_t *, char *, size_t,
2477188Smcpowers     crypto_data_t *, size_t,
2487188Smcpowers     int (*cipher)(const void *, const uint8_t *, uint8_t *),
2497188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2507188Smcpowers 
2517188Smcpowers extern int ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t,
2527188Smcpowers     crypto_data_t *, size_t,
2537188Smcpowers     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
2547188Smcpowers     void (*copy_block)(uint8_t *, uint8_t *),
2557188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2567188Smcpowers 
2577188Smcpowers extern int ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t,
2587188Smcpowers     crypto_data_t *, size_t,
2597188Smcpowers     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
2607188Smcpowers     void (*copy_block)(uint8_t *, uint8_t *),
2617188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2627188Smcpowers 
2637188Smcpowers int ccm_encrypt_final(ccm_ctx_t *, crypto_data_t *, size_t,
2647188Smcpowers     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
2657188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2667188Smcpowers 
2677188Smcpowers extern int ccm_decrypt_final(ccm_ctx_t *, crypto_data_t *, size_t,
2687188Smcpowers     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
2697188Smcpowers     void (*copy_block)(uint8_t *, uint8_t *),
2707188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2717188Smcpowers 
2727188Smcpowers extern int ctr_mode_final(ctr_ctx_t *, crypto_data_t *,
2737188Smcpowers     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *));
2747188Smcpowers 
2757188Smcpowers extern int cbc_init_ctx(cbc_ctx_t *, char *, size_t, size_t,
2767188Smcpowers     void (*copy_block)(uint8_t *, uint64_t *));
2777188Smcpowers 
2787188Smcpowers extern int ctr_init_ctx(ctr_ctx_t *, ulong_t, uint8_t *,
2797188Smcpowers     void (*copy_block)(uint8_t *, uint8_t *));
2807188Smcpowers 
2817188Smcpowers extern int ccm_init_ctx(ccm_ctx_t *, char *, int, boolean_t, size_t,
2827188Smcpowers     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
2837188Smcpowers     void (*xor_block)(uint8_t *, uint8_t *));
2847188Smcpowers 
2857188Smcpowers extern void calculate_ccm_mac(ccm_ctx_t *, uint8_t *,
2867188Smcpowers     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *));
2877188Smcpowers 
2887188Smcpowers extern void crypto_init_ptrs(crypto_data_t *, void **, offset_t *);
2897188Smcpowers extern void crypto_get_ptrs(crypto_data_t *, void **, offset_t *,
2907188Smcpowers     uint8_t **, size_t *, uint8_t **, size_t);
2917188Smcpowers 
2927188Smcpowers extern void *ecb_alloc_ctx(int);
2937188Smcpowers extern void *cbc_alloc_ctx(int);
2947188Smcpowers extern void *ctr_alloc_ctx(int);
2957188Smcpowers extern void *ccm_alloc_ctx(int);
2967188Smcpowers extern void crypto_free_mode_ctx(void *);
2977188Smcpowers 
2987188Smcpowers #ifdef	__cplusplus
2997188Smcpowers }
3007188Smcpowers #endif
3017188Smcpowers 
3027188Smcpowers #endif	/* _COMMON_CRYPTO_MODES_H */
303