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