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