Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 */
20int 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}
34EXPORT_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 */
52int 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}
59EXPORT_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 */
67void *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}
90EXPORT_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 */
104int 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}
112EXPORT_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 */
123int versal_pm_aes_key_zero(const u32 keysrc)
124{
125 return zynqmp_pm_invoke_fn(XSECURE_API_AES_KEY_ZERO, NULL, 1, keysrc);
126}
127EXPORT_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 */
137int 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}
143EXPORT_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 */
154int 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}
161EXPORT_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 */
171int 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}
179EXPORT_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 */
187int 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}
193EXPORT_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 */
203int 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}
211EXPORT_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 */
219int 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}
225EXPORT_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 */
234int versal_pm_aes_init(void)
235{
236 return zynqmp_pm_invoke_fn(XSECURE_API_AES_INIT, NULL, 0);
237}
238EXPORT_SYMBOL_GPL(versal_pm_aes_init);