Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/firmware/xilinx/zynqmp-crypto.c
121833 views
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
240