xref: /freebsd-src/sys/contrib/openzfs/module/icp/algs/aes/aes_impl_aesni.c (revision 15f0b8c309dea1dcb14d3e374686576ff68ac43f)
1eda14cbcSMatt Macy /*
2eda14cbcSMatt Macy  * CDDL HEADER START
3eda14cbcSMatt Macy  *
4eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7eda14cbcSMatt Macy  *
8eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9271171e0SMartin Matuska  * or https://opensource.org/licenses/CDDL-1.0.
10eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11eda14cbcSMatt Macy  * and limitations under the License.
12eda14cbcSMatt Macy  *
13eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18eda14cbcSMatt Macy  *
19eda14cbcSMatt Macy  * CDDL HEADER END
20eda14cbcSMatt Macy  */
21eda14cbcSMatt Macy /*
22eda14cbcSMatt Macy  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23eda14cbcSMatt Macy  */
24eda14cbcSMatt Macy 
25eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_AES)
26eda14cbcSMatt Macy 
27eda14cbcSMatt Macy #include <sys/simd.h>
28eda14cbcSMatt Macy #include <sys/types.h>
29*15f0b8c3SMartin Matuska #include <sys/asm_linkage.h>
30eda14cbcSMatt Macy 
31eda14cbcSMatt Macy /* These functions are used to execute AES-NI instructions: */
32*15f0b8c3SMartin Matuska extern ASMABI int rijndael_key_setup_enc_intel(uint32_t rk[],
33eda14cbcSMatt Macy 	const uint32_t cipherKey[], uint64_t keyBits);
34*15f0b8c3SMartin Matuska extern ASMABI int rijndael_key_setup_dec_intel(uint32_t rk[],
35eda14cbcSMatt Macy 	const uint32_t cipherKey[], uint64_t keyBits);
36*15f0b8c3SMartin Matuska extern ASMABI void aes_encrypt_intel(const uint32_t rk[], int Nr,
37eda14cbcSMatt Macy 	const uint32_t pt[4], uint32_t ct[4]);
38*15f0b8c3SMartin Matuska extern ASMABI void aes_decrypt_intel(const uint32_t rk[], int Nr,
39eda14cbcSMatt Macy 	const uint32_t ct[4], uint32_t pt[4]);
40eda14cbcSMatt Macy 
41eda14cbcSMatt Macy 
42eda14cbcSMatt Macy #include <aes/aes_impl.h>
43eda14cbcSMatt Macy 
44eda14cbcSMatt Macy /*
45eda14cbcSMatt Macy  * Expand the 32-bit AES cipher key array into the encryption and decryption
46eda14cbcSMatt Macy  * key schedules.
47eda14cbcSMatt Macy  *
48eda14cbcSMatt Macy  * Parameters:
49eda14cbcSMatt Macy  * key		AES key schedule to be initialized
50eda14cbcSMatt Macy  * keyarr32	User key
51eda14cbcSMatt Macy  * keyBits	AES key size (128, 192, or 256 bits)
52eda14cbcSMatt Macy  */
53eda14cbcSMatt Macy static void
aes_aesni_generate(aes_key_t * key,const uint32_t * keyarr32,int keybits)54eda14cbcSMatt Macy aes_aesni_generate(aes_key_t *key, const uint32_t *keyarr32, int keybits)
55eda14cbcSMatt Macy {
56eda14cbcSMatt Macy 	kfpu_begin();
57eda14cbcSMatt Macy 	key->nr = rijndael_key_setup_enc_intel(&(key->encr_ks.ks32[0]),
58eda14cbcSMatt Macy 	    keyarr32, keybits);
59eda14cbcSMatt Macy 	key->nr = rijndael_key_setup_dec_intel(&(key->decr_ks.ks32[0]),
60eda14cbcSMatt Macy 	    keyarr32, keybits);
61eda14cbcSMatt Macy 	kfpu_end();
62eda14cbcSMatt Macy }
63eda14cbcSMatt Macy 
64eda14cbcSMatt Macy /*
65eda14cbcSMatt Macy  * Encrypt one block of data. The block is assumed to be an array
66eda14cbcSMatt Macy  * of four uint32_t values, so copy for alignment (and byte-order
67eda14cbcSMatt Macy  * reversal for little endian systems might be necessary on the
68eda14cbcSMatt Macy  * input and output byte streams.
69eda14cbcSMatt Macy  * The size of the key schedule depends on the number of rounds
70eda14cbcSMatt Macy  * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
71eda14cbcSMatt Macy  *
72eda14cbcSMatt Macy  * Parameters:
73eda14cbcSMatt Macy  * rk		Key schedule, of aes_ks_t (60 32-bit integers)
74eda14cbcSMatt Macy  * Nr		Number of rounds
75eda14cbcSMatt Macy  * pt		Input block (plain text)
76eda14cbcSMatt Macy  * ct		Output block (crypto text).  Can overlap with pt
77eda14cbcSMatt Macy  */
78eda14cbcSMatt Macy static void
aes_aesni_encrypt(const uint32_t rk[],int Nr,const uint32_t pt[4],uint32_t ct[4])79eda14cbcSMatt Macy aes_aesni_encrypt(const uint32_t rk[], int Nr, const uint32_t pt[4],
80eda14cbcSMatt Macy     uint32_t ct[4])
81eda14cbcSMatt Macy {
82eda14cbcSMatt Macy 	kfpu_begin();
83eda14cbcSMatt Macy 	aes_encrypt_intel(rk, Nr, pt, ct);
84eda14cbcSMatt Macy 	kfpu_end();
85eda14cbcSMatt Macy }
86eda14cbcSMatt Macy 
87eda14cbcSMatt Macy /*
88eda14cbcSMatt Macy  * Decrypt one block of data. The block is assumed to be an array
89eda14cbcSMatt Macy  * of four uint32_t values, so copy for alignment (and byte-order
90eda14cbcSMatt Macy  * reversal for little endian systems might be necessary on the
91eda14cbcSMatt Macy  * input and output byte streams.
92eda14cbcSMatt Macy  * The size of the key schedule depends on the number of rounds
93eda14cbcSMatt Macy  * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
94eda14cbcSMatt Macy  *
95eda14cbcSMatt Macy  * Parameters:
96eda14cbcSMatt Macy  * rk		Key schedule, of aes_ks_t (60 32-bit integers)
97eda14cbcSMatt Macy  * Nr		Number of rounds
98eda14cbcSMatt Macy  * ct		Input block (crypto text)
99eda14cbcSMatt Macy  * pt		Output block (plain text). Can overlap with pt
100eda14cbcSMatt Macy  */
101eda14cbcSMatt Macy static void
aes_aesni_decrypt(const uint32_t rk[],int Nr,const uint32_t ct[4],uint32_t pt[4])102eda14cbcSMatt Macy aes_aesni_decrypt(const uint32_t rk[], int Nr, const uint32_t ct[4],
103eda14cbcSMatt Macy     uint32_t pt[4])
104eda14cbcSMatt Macy {
105eda14cbcSMatt Macy 	kfpu_begin();
106eda14cbcSMatt Macy 	aes_decrypt_intel(rk, Nr, ct, pt);
107eda14cbcSMatt Macy 	kfpu_end();
108eda14cbcSMatt Macy }
109eda14cbcSMatt Macy 
110eda14cbcSMatt Macy static boolean_t
aes_aesni_will_work(void)111eda14cbcSMatt Macy aes_aesni_will_work(void)
112eda14cbcSMatt Macy {
113eda14cbcSMatt Macy 	return (kfpu_allowed() && zfs_aes_available());
114eda14cbcSMatt Macy }
115eda14cbcSMatt Macy 
116eda14cbcSMatt Macy const aes_impl_ops_t aes_aesni_impl = {
117eda14cbcSMatt Macy 	.generate = &aes_aesni_generate,
118eda14cbcSMatt Macy 	.encrypt = &aes_aesni_encrypt,
119eda14cbcSMatt Macy 	.decrypt = &aes_aesni_decrypt,
120eda14cbcSMatt Macy 	.is_supported = &aes_aesni_will_work,
121eda14cbcSMatt Macy 	.needs_byteswap = B_FALSE,
122eda14cbcSMatt Macy 	.name = "aesni"
123eda14cbcSMatt Macy };
124eda14cbcSMatt Macy 
125eda14cbcSMatt Macy #endif /* defined(__x86_64) && defined(HAVE_AES) */
126