| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Firmware layer for XilSecure APIs.
- *
- * Copyright (C) 2014-2022 Xilinx, Inc.
- * Copyright (C) 2022-2025 Advanced Micro Devices, Inc.
- */
- #include <linux/firmware/xlnx-zynqmp.h>
- #include <linux/module.h>
- /**
- * zynqmp_pm_aes_engine - Access AES hardware to encrypt/decrypt the data using
- * AES-GCM core.
- * @address: Address of the AesParams structure.
- * @out: Returned output value
- *
- * Return: Returns status, either success or error code.
- */
- int zynqmp_pm_aes_engine(const u64 address, u32 *out)
- {
- u32 ret_payload[PAYLOAD_ARG_CNT];
- int ret;
- if (!out)
- return -EINVAL;
- ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, ret_payload, 2, upper_32_bits(address),
- lower_32_bits(address));
- *out = ret_payload[1];
- return ret;
- }
- EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
- /**
- * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
- * @address: Address of the data/ Address of output buffer where
- * hash should be stored.
- * @size: Size of the data.
- * @flags:
- * BIT(0) - for initializing csudma driver and SHA3(Here address
- * and size inputs can be NULL).
- * BIT(1) - to call Sha3_Update API which can be called multiple
- * times when data is not contiguous.
- * BIT(2) - to get final hash of the whole updated data.
- * Hash will be overwritten at provided address with
- * 48 bytes.
- *
- * Return: Returns status, either success or error code.
- */
- int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags)
- {
- u32 lower_addr = lower_32_bits(address);
- u32 upper_addr = upper_32_bits(address);
- return zynqmp_pm_invoke_fn(PM_SECURE_SHA, NULL, 4, upper_addr, lower_addr, size, flags);
- }
- EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash);
- /**
- * xlnx_get_crypto_dev_data() - Get crypto dev data of platform
- * @feature_map: List of available feature map of all platform
- *
- * Return: Returns crypto dev data, either address crypto dev or ERR PTR
- */
- void *xlnx_get_crypto_dev_data(struct xlnx_feature *feature_map)
- {
- struct xlnx_feature *feature;
- u32 pm_family_code;
- int ret;
- /* Get the Family code and sub family code of platform */
- ret = zynqmp_pm_get_family_info(&pm_family_code);
- if (ret < 0)
- return ERR_PTR(ret);
- feature = feature_map;
- for (; feature->family; feature++) {
- if (feature->family == pm_family_code) {
- ret = zynqmp_pm_feature(feature->feature_id);
- if (ret < 0)
- return ERR_PTR(ret);
- return feature->data;
- }
- }
- return ERR_PTR(-ENODEV);
- }
- EXPORT_SYMBOL_GPL(xlnx_get_crypto_dev_data);
- /**
- * versal_pm_aes_key_write - Write AES key registers
- * @keylen: Size of the input key to be written
- * @keysrc: Key Source to be selected to which provided
- * key should be updated
- * @keyaddr: Address of a buffer which should contain the key
- * to be written
- *
- * This function provides support to write AES volatile user keys.
- *
- * Return: Returns status, either success or error+reason
- */
- int versal_pm_aes_key_write(const u32 keylen,
- const u32 keysrc, const u64 keyaddr)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_WRITE_KEY, NULL, 4,
- keylen, keysrc,
- lower_32_bits(keyaddr),
- upper_32_bits(keyaddr));
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_key_write);
- /**
- * versal_pm_aes_key_zero - Zeroise AES User key registers
- * @keysrc: Key Source to be selected to which provided
- * key should be updated
- *
- * This function provides support to zeroise AES volatile user keys.
- *
- * Return: Returns status, either success or error+reason
- */
- int versal_pm_aes_key_zero(const u32 keysrc)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_KEY_ZERO, NULL, 1, keysrc);
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_key_zero);
- /**
- * versal_pm_aes_op_init - Init AES operation
- * @hw_req: AES op init structure address
- *
- * This function provides support to init AES operation.
- *
- * Return: Returns status, either success or error+reason
- */
- int versal_pm_aes_op_init(const u64 hw_req)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_OP_INIT, NULL, 2,
- lower_32_bits(hw_req),
- upper_32_bits(hw_req));
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_op_init);
- /**
- * versal_pm_aes_update_aad - AES update aad
- * @aad_addr: AES aad address
- * @aad_len: AES aad data length
- *
- * This function provides support to update AAD data.
- *
- * Return: Returns status, either success or error+reason
- */
- int versal_pm_aes_update_aad(const u64 aad_addr, const u32 aad_len)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_UPDATE_AAD, NULL, 3,
- lower_32_bits(aad_addr),
- upper_32_bits(aad_addr),
- aad_len);
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_update_aad);
- /**
- * versal_pm_aes_enc_update - Access AES hardware to encrypt the data using
- * AES-GCM core.
- * @in_params: Address of the AesParams structure
- * @in_addr: Address of input buffer
- *
- * Return: Returns status, either success or error code.
- */
- int versal_pm_aes_enc_update(const u64 in_params, const u64 in_addr)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_UPDATE, NULL, 4,
- lower_32_bits(in_params),
- upper_32_bits(in_params),
- lower_32_bits(in_addr),
- upper_32_bits(in_addr));
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_enc_update);
- /**
- * versal_pm_aes_enc_final - Access AES hardware to store the GCM tag
- * @gcm_addr: Address of the gcm tag
- *
- * Return: Returns status, either success or error code.
- */
- int versal_pm_aes_enc_final(const u64 gcm_addr)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_FINAL, NULL, 2,
- lower_32_bits(gcm_addr),
- upper_32_bits(gcm_addr));
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_enc_final);
- /**
- * versal_pm_aes_dec_update - Access AES hardware to decrypt the data using
- * AES-GCM core.
- * @in_params: Address of the AesParams structure
- * @in_addr: Address of input buffer
- *
- * Return: Returns status, either success or error code.
- */
- int versal_pm_aes_dec_update(const u64 in_params, const u64 in_addr)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_UPDATE, NULL, 4,
- lower_32_bits(in_params),
- upper_32_bits(in_params),
- lower_32_bits(in_addr),
- upper_32_bits(in_addr));
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_dec_update);
- /**
- * versal_pm_aes_dec_final - Access AES hardware to get the GCM tag
- * @gcm_addr: Address of the gcm tag
- *
- * Return: Returns status, either success or error code.
- */
- int versal_pm_aes_dec_final(const u64 gcm_addr)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_FINAL, NULL, 2,
- lower_32_bits(gcm_addr),
- upper_32_bits(gcm_addr));
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_dec_final);
- /**
- * versal_pm_aes_init - Init AES block
- *
- * This function initialise AES block.
- *
- * Return: Returns status, either success or error+reason
- */
- int versal_pm_aes_init(void)
- {
- return zynqmp_pm_invoke_fn(XSECURE_API_AES_INIT, NULL, 0);
- }
- EXPORT_SYMBOL_GPL(versal_pm_aes_init);
|