xref: /linux/lib/crypto/sparc/aes.h (revision 13d83ea9d81ddcb08b46377dcc9de6e5df1248d1)
1*293c7cd5SEric Biggers /* SPDX-License-Identifier: GPL-2.0-only */
2*293c7cd5SEric Biggers /*
3*293c7cd5SEric Biggers  * AES accelerated using the sparc64 aes opcodes
4*293c7cd5SEric Biggers  *
5*293c7cd5SEric Biggers  * Copyright (C) 2008, Intel Corp.
6*293c7cd5SEric Biggers  * Copyright (c) 2010, Intel Corporation.
7*293c7cd5SEric Biggers  * Copyright 2026 Google LLC
8*293c7cd5SEric Biggers  */
9*293c7cd5SEric Biggers 
10*293c7cd5SEric Biggers #include <asm/fpumacro.h>
11*293c7cd5SEric Biggers #include <asm/opcodes.h>
12*293c7cd5SEric Biggers #include <asm/pstate.h>
13*293c7cd5SEric Biggers #include <asm/elf.h>
14*293c7cd5SEric Biggers 
15*293c7cd5SEric Biggers static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_aes_opcodes);
16*293c7cd5SEric Biggers 
17*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_key_expand);
18*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_load_encrypt_keys_128);
19*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_load_encrypt_keys_192);
20*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_load_encrypt_keys_256);
21*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_load_decrypt_keys_128);
22*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_load_decrypt_keys_192);
23*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_load_decrypt_keys_256);
24*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ecb_encrypt_128);
25*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ecb_encrypt_192);
26*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ecb_encrypt_256);
27*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ecb_decrypt_128);
28*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ecb_decrypt_192);
29*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ecb_decrypt_256);
30*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_cbc_encrypt_128);
31*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_cbc_encrypt_192);
32*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_cbc_encrypt_256);
33*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_cbc_decrypt_128);
34*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_cbc_decrypt_192);
35*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_cbc_decrypt_256);
36*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ctr_crypt_128);
37*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ctr_crypt_192);
38*293c7cd5SEric Biggers EXPORT_SYMBOL_GPL(aes_sparc64_ctr_crypt_256);
39*293c7cd5SEric Biggers 
40*293c7cd5SEric Biggers void aes_sparc64_encrypt_128(const u64 *key, const u32 *input, u32 *output);
41*293c7cd5SEric Biggers void aes_sparc64_encrypt_192(const u64 *key, const u32 *input, u32 *output);
42*293c7cd5SEric Biggers void aes_sparc64_encrypt_256(const u64 *key, const u32 *input, u32 *output);
43*293c7cd5SEric Biggers void aes_sparc64_decrypt_128(const u64 *key, const u32 *input, u32 *output);
44*293c7cd5SEric Biggers void aes_sparc64_decrypt_192(const u64 *key, const u32 *input, u32 *output);
45*293c7cd5SEric Biggers void aes_sparc64_decrypt_256(const u64 *key, const u32 *input, u32 *output);
46*293c7cd5SEric Biggers 
47*293c7cd5SEric Biggers static void aes_preparekey_arch(union aes_enckey_arch *k,
48*293c7cd5SEric Biggers 				union aes_invkey_arch *inv_k,
49*293c7cd5SEric Biggers 				const u8 *in_key, int key_len, int nrounds)
50*293c7cd5SEric Biggers {
51*293c7cd5SEric Biggers 	if (static_branch_likely(&have_aes_opcodes)) {
52*293c7cd5SEric Biggers 		u32 aligned_key[AES_MAX_KEY_SIZE / 4];
53*293c7cd5SEric Biggers 
54*293c7cd5SEric Biggers 		if (IS_ALIGNED((uintptr_t)in_key, 4)) {
55*293c7cd5SEric Biggers 			aes_sparc64_key_expand((const u32 *)in_key,
56*293c7cd5SEric Biggers 					       k->sparc_rndkeys, key_len);
57*293c7cd5SEric Biggers 		} else {
58*293c7cd5SEric Biggers 			memcpy(aligned_key, in_key, key_len);
59*293c7cd5SEric Biggers 			aes_sparc64_key_expand(aligned_key,
60*293c7cd5SEric Biggers 					       k->sparc_rndkeys, key_len);
61*293c7cd5SEric Biggers 			memzero_explicit(aligned_key, key_len);
62*293c7cd5SEric Biggers 		}
63*293c7cd5SEric Biggers 		/*
64*293c7cd5SEric Biggers 		 * Note that nothing needs to be written to inv_k (if it's
65*293c7cd5SEric Biggers 		 * non-NULL) here, since the SPARC64 assembly code uses
66*293c7cd5SEric Biggers 		 * k->sparc_rndkeys for both encryption and decryption.
67*293c7cd5SEric Biggers 		 */
68*293c7cd5SEric Biggers 	} else {
69*293c7cd5SEric Biggers 		aes_expandkey_generic(k->rndkeys,
70*293c7cd5SEric Biggers 				      inv_k ? inv_k->inv_rndkeys : NULL,
71*293c7cd5SEric Biggers 				      in_key, key_len);
72*293c7cd5SEric Biggers 	}
73*293c7cd5SEric Biggers }
74*293c7cd5SEric Biggers 
75*293c7cd5SEric Biggers static void aes_sparc64_encrypt(const struct aes_enckey *key,
76*293c7cd5SEric Biggers 				const u32 *input, u32 *output)
77*293c7cd5SEric Biggers {
78*293c7cd5SEric Biggers 	if (key->len == AES_KEYSIZE_128)
79*293c7cd5SEric Biggers 		aes_sparc64_encrypt_128(key->k.sparc_rndkeys, input, output);
80*293c7cd5SEric Biggers 	else if (key->len == AES_KEYSIZE_192)
81*293c7cd5SEric Biggers 		aes_sparc64_encrypt_192(key->k.sparc_rndkeys, input, output);
82*293c7cd5SEric Biggers 	else
83*293c7cd5SEric Biggers 		aes_sparc64_encrypt_256(key->k.sparc_rndkeys, input, output);
84*293c7cd5SEric Biggers }
85*293c7cd5SEric Biggers 
86*293c7cd5SEric Biggers static void aes_encrypt_arch(const struct aes_enckey *key,
87*293c7cd5SEric Biggers 			     u8 out[AES_BLOCK_SIZE],
88*293c7cd5SEric Biggers 			     const u8 in[AES_BLOCK_SIZE])
89*293c7cd5SEric Biggers {
90*293c7cd5SEric Biggers 	u32 bounce_buf[AES_BLOCK_SIZE / 4];
91*293c7cd5SEric Biggers 
92*293c7cd5SEric Biggers 	if (static_branch_likely(&have_aes_opcodes)) {
93*293c7cd5SEric Biggers 		if (IS_ALIGNED((uintptr_t)in | (uintptr_t)out, 4)) {
94*293c7cd5SEric Biggers 			aes_sparc64_encrypt(key, (const u32 *)in, (u32 *)out);
95*293c7cd5SEric Biggers 		} else {
96*293c7cd5SEric Biggers 			memcpy(bounce_buf, in, AES_BLOCK_SIZE);
97*293c7cd5SEric Biggers 			aes_sparc64_encrypt(key, bounce_buf, bounce_buf);
98*293c7cd5SEric Biggers 			memcpy(out, bounce_buf, AES_BLOCK_SIZE);
99*293c7cd5SEric Biggers 		}
100*293c7cd5SEric Biggers 	} else {
101*293c7cd5SEric Biggers 		aes_encrypt_generic(key->k.rndkeys, key->nrounds, out, in);
102*293c7cd5SEric Biggers 	}
103*293c7cd5SEric Biggers }
104*293c7cd5SEric Biggers 
105*293c7cd5SEric Biggers static void aes_sparc64_decrypt(const struct aes_key *key,
106*293c7cd5SEric Biggers 				const u32 *input, u32 *output)
107*293c7cd5SEric Biggers {
108*293c7cd5SEric Biggers 	if (key->len == AES_KEYSIZE_128)
109*293c7cd5SEric Biggers 		aes_sparc64_decrypt_128(key->k.sparc_rndkeys, input, output);
110*293c7cd5SEric Biggers 	else if (key->len == AES_KEYSIZE_192)
111*293c7cd5SEric Biggers 		aes_sparc64_decrypt_192(key->k.sparc_rndkeys, input, output);
112*293c7cd5SEric Biggers 	else
113*293c7cd5SEric Biggers 		aes_sparc64_decrypt_256(key->k.sparc_rndkeys, input, output);
114*293c7cd5SEric Biggers }
115*293c7cd5SEric Biggers 
116*293c7cd5SEric Biggers static void aes_decrypt_arch(const struct aes_key *key,
117*293c7cd5SEric Biggers 			     u8 out[AES_BLOCK_SIZE],
118*293c7cd5SEric Biggers 			     const u8 in[AES_BLOCK_SIZE])
119*293c7cd5SEric Biggers {
120*293c7cd5SEric Biggers 	u32 bounce_buf[AES_BLOCK_SIZE / 4];
121*293c7cd5SEric Biggers 
122*293c7cd5SEric Biggers 	if (static_branch_likely(&have_aes_opcodes)) {
123*293c7cd5SEric Biggers 		if (IS_ALIGNED((uintptr_t)in | (uintptr_t)out, 4)) {
124*293c7cd5SEric Biggers 			aes_sparc64_decrypt(key, (const u32 *)in, (u32 *)out);
125*293c7cd5SEric Biggers 		} else {
126*293c7cd5SEric Biggers 			memcpy(bounce_buf, in, AES_BLOCK_SIZE);
127*293c7cd5SEric Biggers 			aes_sparc64_decrypt(key, bounce_buf, bounce_buf);
128*293c7cd5SEric Biggers 			memcpy(out, bounce_buf, AES_BLOCK_SIZE);
129*293c7cd5SEric Biggers 		}
130*293c7cd5SEric Biggers 	} else {
131*293c7cd5SEric Biggers 		aes_decrypt_generic(key->inv_k.inv_rndkeys, key->nrounds,
132*293c7cd5SEric Biggers 				    out, in);
133*293c7cd5SEric Biggers 	}
134*293c7cd5SEric Biggers }
135*293c7cd5SEric Biggers 
136*293c7cd5SEric Biggers #define aes_mod_init_arch aes_mod_init_arch
137*293c7cd5SEric Biggers static void aes_mod_init_arch(void)
138*293c7cd5SEric Biggers {
139*293c7cd5SEric Biggers 	unsigned long cfr;
140*293c7cd5SEric Biggers 
141*293c7cd5SEric Biggers 	if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
142*293c7cd5SEric Biggers 		return;
143*293c7cd5SEric Biggers 
144*293c7cd5SEric Biggers 	__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
145*293c7cd5SEric Biggers 	if (!(cfr & CFR_AES))
146*293c7cd5SEric Biggers 		return;
147*293c7cd5SEric Biggers 
148*293c7cd5SEric Biggers 	static_branch_enable(&have_aes_opcodes);
149*293c7cd5SEric Biggers }
150