1c15291e2SHarsh Jain // SPDX-License-Identifier: GPL-2.0 2c15291e2SHarsh Jain /* 3c15291e2SHarsh Jain * Firmware layer for XilSecure APIs. 4c15291e2SHarsh Jain * 5c15291e2SHarsh Jain * Copyright (C) 2014-2022 Xilinx, Inc. 6c15291e2SHarsh Jain * Copyright (C) 2022-2025 Advanced Micro Devices, Inc. 7c15291e2SHarsh Jain */ 8c15291e2SHarsh Jain 9c15291e2SHarsh Jain #include <linux/firmware/xlnx-zynqmp.h> 10c15291e2SHarsh Jain #include <linux/module.h> 11c15291e2SHarsh Jain 12c15291e2SHarsh Jain /** 13c15291e2SHarsh Jain * zynqmp_pm_aes_engine - Access AES hardware to encrypt/decrypt the data using 14c15291e2SHarsh Jain * AES-GCM core. 15c15291e2SHarsh Jain * @address: Address of the AesParams structure. 16c15291e2SHarsh Jain * @out: Returned output value 17c15291e2SHarsh Jain * 18c15291e2SHarsh Jain * Return: Returns status, either success or error code. 19c15291e2SHarsh Jain */ 20c15291e2SHarsh Jain int zynqmp_pm_aes_engine(const u64 address, u32 *out) 21c15291e2SHarsh Jain { 22c15291e2SHarsh Jain u32 ret_payload[PAYLOAD_ARG_CNT]; 23c15291e2SHarsh Jain int ret; 24c15291e2SHarsh Jain 25c15291e2SHarsh Jain if (!out) 26c15291e2SHarsh Jain return -EINVAL; 27c15291e2SHarsh Jain 28c15291e2SHarsh Jain ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, ret_payload, 2, upper_32_bits(address), 29c15291e2SHarsh Jain lower_32_bits(address)); 30c15291e2SHarsh Jain *out = ret_payload[1]; 31c15291e2SHarsh Jain 32c15291e2SHarsh Jain return ret; 33c15291e2SHarsh Jain } 34c15291e2SHarsh Jain EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine); 35c15291e2SHarsh Jain 36c15291e2SHarsh Jain /** 37c15291e2SHarsh Jain * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash 38c15291e2SHarsh Jain * @address: Address of the data/ Address of output buffer where 39c15291e2SHarsh Jain * hash should be stored. 40c15291e2SHarsh Jain * @size: Size of the data. 41c15291e2SHarsh Jain * @flags: 42c15291e2SHarsh Jain * BIT(0) - for initializing csudma driver and SHA3(Here address 43c15291e2SHarsh Jain * and size inputs can be NULL). 44c15291e2SHarsh Jain * BIT(1) - to call Sha3_Update API which can be called multiple 45c15291e2SHarsh Jain * times when data is not contiguous. 46c15291e2SHarsh Jain * BIT(2) - to get final hash of the whole updated data. 47c15291e2SHarsh Jain * Hash will be overwritten at provided address with 48c15291e2SHarsh Jain * 48 bytes. 49c15291e2SHarsh Jain * 50c15291e2SHarsh Jain * Return: Returns status, either success or error code. 51c15291e2SHarsh Jain */ 52c15291e2SHarsh Jain int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags) 53c15291e2SHarsh Jain { 54c15291e2SHarsh Jain u32 lower_addr = lower_32_bits(address); 55c15291e2SHarsh Jain u32 upper_addr = upper_32_bits(address); 56c15291e2SHarsh Jain 57c15291e2SHarsh Jain return zynqmp_pm_invoke_fn(PM_SECURE_SHA, NULL, 4, upper_addr, lower_addr, size, flags); 58c15291e2SHarsh Jain } 59c15291e2SHarsh Jain EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash); 60465d7831SHarsh Jain 61465d7831SHarsh Jain /** 62465d7831SHarsh Jain * xlnx_get_crypto_dev_data() - Get crypto dev data of platform 63465d7831SHarsh Jain * @feature_map: List of available feature map of all platform 64465d7831SHarsh Jain * 65465d7831SHarsh Jain * Return: Returns crypto dev data, either address crypto dev or ERR PTR 66465d7831SHarsh Jain */ 67465d7831SHarsh Jain void *xlnx_get_crypto_dev_data(struct xlnx_feature *feature_map) 68465d7831SHarsh Jain { 69465d7831SHarsh Jain struct xlnx_feature *feature; 70465d7831SHarsh Jain u32 pm_family_code; 71465d7831SHarsh Jain int ret; 72465d7831SHarsh Jain 73465d7831SHarsh Jain /* Get the Family code and sub family code of platform */ 74465d7831SHarsh Jain ret = zynqmp_pm_get_family_info(&pm_family_code); 75465d7831SHarsh Jain if (ret < 0) 76465d7831SHarsh Jain return ERR_PTR(ret); 77465d7831SHarsh Jain 78465d7831SHarsh Jain feature = feature_map; 79465d7831SHarsh Jain for (; feature->family; feature++) { 80465d7831SHarsh Jain if (feature->family == pm_family_code) { 81465d7831SHarsh Jain ret = zynqmp_pm_feature(feature->feature_id); 82465d7831SHarsh Jain if (ret < 0) 83465d7831SHarsh Jain return ERR_PTR(ret); 84465d7831SHarsh Jain 85465d7831SHarsh Jain return feature->data; 86465d7831SHarsh Jain } 87465d7831SHarsh Jain } 88465d7831SHarsh Jain return ERR_PTR(-ENODEV); 89465d7831SHarsh Jain } 90465d7831SHarsh Jain EXPORT_SYMBOL_GPL(xlnx_get_crypto_dev_data); 91*e9f6870bSHarsh Jain 92*e9f6870bSHarsh Jain /** 93*e9f6870bSHarsh Jain * versal_pm_aes_key_write - Write AES key registers 94*e9f6870bSHarsh Jain * @keylen: Size of the input key to be written 95*e9f6870bSHarsh Jain * @keysrc: Key Source to be selected to which provided 96*e9f6870bSHarsh Jain * key should be updated 97*e9f6870bSHarsh Jain * @keyaddr: Address of a buffer which should contain the key 98*e9f6870bSHarsh Jain * to be written 99*e9f6870bSHarsh Jain * 100*e9f6870bSHarsh Jain * This function provides support to write AES volatile user keys. 101*e9f6870bSHarsh Jain * 102*e9f6870bSHarsh Jain * Return: Returns status, either success or error+reason 103*e9f6870bSHarsh Jain */ 104*e9f6870bSHarsh Jain int versal_pm_aes_key_write(const u32 keylen, 105*e9f6870bSHarsh Jain const u32 keysrc, const u64 keyaddr) 106*e9f6870bSHarsh Jain { 107*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_WRITE_KEY, NULL, 4, 108*e9f6870bSHarsh Jain keylen, keysrc, 109*e9f6870bSHarsh Jain lower_32_bits(keyaddr), 110*e9f6870bSHarsh Jain upper_32_bits(keyaddr)); 111*e9f6870bSHarsh Jain } 112*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_key_write); 113*e9f6870bSHarsh Jain 114*e9f6870bSHarsh Jain /** 115*e9f6870bSHarsh Jain * versal_pm_aes_key_zero - Zeroise AES User key registers 116*e9f6870bSHarsh Jain * @keysrc: Key Source to be selected to which provided 117*e9f6870bSHarsh Jain * key should be updated 118*e9f6870bSHarsh Jain * 119*e9f6870bSHarsh Jain * This function provides support to zeroise AES volatile user keys. 120*e9f6870bSHarsh Jain * 121*e9f6870bSHarsh Jain * Return: Returns status, either success or error+reason 122*e9f6870bSHarsh Jain */ 123*e9f6870bSHarsh Jain int versal_pm_aes_key_zero(const u32 keysrc) 124*e9f6870bSHarsh Jain { 125*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_KEY_ZERO, NULL, 1, keysrc); 126*e9f6870bSHarsh Jain } 127*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_key_zero); 128*e9f6870bSHarsh Jain 129*e9f6870bSHarsh Jain /** 130*e9f6870bSHarsh Jain * versal_pm_aes_op_init - Init AES operation 131*e9f6870bSHarsh Jain * @hw_req: AES op init structure address 132*e9f6870bSHarsh Jain * 133*e9f6870bSHarsh Jain * This function provides support to init AES operation. 134*e9f6870bSHarsh Jain * 135*e9f6870bSHarsh Jain * Return: Returns status, either success or error+reason 136*e9f6870bSHarsh Jain */ 137*e9f6870bSHarsh Jain int versal_pm_aes_op_init(const u64 hw_req) 138*e9f6870bSHarsh Jain { 139*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_OP_INIT, NULL, 2, 140*e9f6870bSHarsh Jain lower_32_bits(hw_req), 141*e9f6870bSHarsh Jain upper_32_bits(hw_req)); 142*e9f6870bSHarsh Jain } 143*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_op_init); 144*e9f6870bSHarsh Jain 145*e9f6870bSHarsh Jain /** 146*e9f6870bSHarsh Jain * versal_pm_aes_update_aad - AES update aad 147*e9f6870bSHarsh Jain * @aad_addr: AES aad address 148*e9f6870bSHarsh Jain * @aad_len: AES aad data length 149*e9f6870bSHarsh Jain * 150*e9f6870bSHarsh Jain * This function provides support to update AAD data. 151*e9f6870bSHarsh Jain * 152*e9f6870bSHarsh Jain * Return: Returns status, either success or error+reason 153*e9f6870bSHarsh Jain */ 154*e9f6870bSHarsh Jain int versal_pm_aes_update_aad(const u64 aad_addr, const u32 aad_len) 155*e9f6870bSHarsh Jain { 156*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_UPDATE_AAD, NULL, 3, 157*e9f6870bSHarsh Jain lower_32_bits(aad_addr), 158*e9f6870bSHarsh Jain upper_32_bits(aad_addr), 159*e9f6870bSHarsh Jain aad_len); 160*e9f6870bSHarsh Jain } 161*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_update_aad); 162*e9f6870bSHarsh Jain 163*e9f6870bSHarsh Jain /** 164*e9f6870bSHarsh Jain * versal_pm_aes_enc_update - Access AES hardware to encrypt the data using 165*e9f6870bSHarsh Jain * AES-GCM core. 166*e9f6870bSHarsh Jain * @in_params: Address of the AesParams structure 167*e9f6870bSHarsh Jain * @in_addr: Address of input buffer 168*e9f6870bSHarsh Jain * 169*e9f6870bSHarsh Jain * Return: Returns status, either success or error code. 170*e9f6870bSHarsh Jain */ 171*e9f6870bSHarsh Jain int versal_pm_aes_enc_update(const u64 in_params, const u64 in_addr) 172*e9f6870bSHarsh Jain { 173*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_UPDATE, NULL, 4, 174*e9f6870bSHarsh Jain lower_32_bits(in_params), 175*e9f6870bSHarsh Jain upper_32_bits(in_params), 176*e9f6870bSHarsh Jain lower_32_bits(in_addr), 177*e9f6870bSHarsh Jain upper_32_bits(in_addr)); 178*e9f6870bSHarsh Jain } 179*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_enc_update); 180*e9f6870bSHarsh Jain 181*e9f6870bSHarsh Jain /** 182*e9f6870bSHarsh Jain * versal_pm_aes_enc_final - Access AES hardware to store the GCM tag 183*e9f6870bSHarsh Jain * @gcm_addr: Address of the gcm tag 184*e9f6870bSHarsh Jain * 185*e9f6870bSHarsh Jain * Return: Returns status, either success or error code. 186*e9f6870bSHarsh Jain */ 187*e9f6870bSHarsh Jain int versal_pm_aes_enc_final(const u64 gcm_addr) 188*e9f6870bSHarsh Jain { 189*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_FINAL, NULL, 2, 190*e9f6870bSHarsh Jain lower_32_bits(gcm_addr), 191*e9f6870bSHarsh Jain upper_32_bits(gcm_addr)); 192*e9f6870bSHarsh Jain } 193*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_enc_final); 194*e9f6870bSHarsh Jain 195*e9f6870bSHarsh Jain /** 196*e9f6870bSHarsh Jain * versal_pm_aes_dec_update - Access AES hardware to decrypt the data using 197*e9f6870bSHarsh Jain * AES-GCM core. 198*e9f6870bSHarsh Jain * @in_params: Address of the AesParams structure 199*e9f6870bSHarsh Jain * @in_addr: Address of input buffer 200*e9f6870bSHarsh Jain * 201*e9f6870bSHarsh Jain * Return: Returns status, either success or error code. 202*e9f6870bSHarsh Jain */ 203*e9f6870bSHarsh Jain int versal_pm_aes_dec_update(const u64 in_params, const u64 in_addr) 204*e9f6870bSHarsh Jain { 205*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_UPDATE, NULL, 4, 206*e9f6870bSHarsh Jain lower_32_bits(in_params), 207*e9f6870bSHarsh Jain upper_32_bits(in_params), 208*e9f6870bSHarsh Jain lower_32_bits(in_addr), 209*e9f6870bSHarsh Jain upper_32_bits(in_addr)); 210*e9f6870bSHarsh Jain } 211*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_dec_update); 212*e9f6870bSHarsh Jain 213*e9f6870bSHarsh Jain /** 214*e9f6870bSHarsh Jain * versal_pm_aes_dec_final - Access AES hardware to get the GCM tag 215*e9f6870bSHarsh Jain * @gcm_addr: Address of the gcm tag 216*e9f6870bSHarsh Jain * 217*e9f6870bSHarsh Jain * Return: Returns status, either success or error code. 218*e9f6870bSHarsh Jain */ 219*e9f6870bSHarsh Jain int versal_pm_aes_dec_final(const u64 gcm_addr) 220*e9f6870bSHarsh Jain { 221*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_FINAL, NULL, 2, 222*e9f6870bSHarsh Jain lower_32_bits(gcm_addr), 223*e9f6870bSHarsh Jain upper_32_bits(gcm_addr)); 224*e9f6870bSHarsh Jain } 225*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_dec_final); 226*e9f6870bSHarsh Jain 227*e9f6870bSHarsh Jain /** 228*e9f6870bSHarsh Jain * versal_pm_aes_init - Init AES block 229*e9f6870bSHarsh Jain * 230*e9f6870bSHarsh Jain * This function initialise AES block. 231*e9f6870bSHarsh Jain * 232*e9f6870bSHarsh Jain * Return: Returns status, either success or error+reason 233*e9f6870bSHarsh Jain */ 234*e9f6870bSHarsh Jain int versal_pm_aes_init(void) 235*e9f6870bSHarsh Jain { 236*e9f6870bSHarsh Jain return zynqmp_pm_invoke_fn(XSECURE_API_AES_INIT, NULL, 0); 237*e9f6870bSHarsh Jain } 238*e9f6870bSHarsh Jain EXPORT_SYMBOL_GPL(versal_pm_aes_init); 239