Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2024-2025 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : #include <stdarg.h>
8 : #include <stddef.h>
9 : #include <setjmp.h>
10 : #include <stdint.h>
11 : #include <stdlib.h>
12 : #include <stdio.h>
13 : #include <assert.h>
14 : #include <string.h>
15 :
16 : #include <base.h>
17 : #include "library/memlib.h"
18 : #include "spdm_device_secret_lib_internal.h"
19 : #include "internal/libspdm_common_lib.h"
20 :
21 : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) || (LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP)
22 35 : bool libspdm_requester_data_sign(
23 : void *spdm_context,
24 : spdm_version_number_t spdm_version,
25 : uint8_t key_pair_id, uint8_t op_code,
26 : uint16_t req_base_asym_alg, uint32_t req_pqc_asym_alg,
27 : uint32_t base_hash_algo, bool is_data_hash,
28 : const uint8_t *message, size_t message_size,
29 : uint8_t *signature, size_t *sig_size)
30 : {
31 : void *context;
32 : bool result;
33 :
34 35 : const uint8_t version = spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT;
35 35 : const bool multi_key_conn_rsp =
36 : ((libspdm_context_t *)spdm_context)->connection_info.multi_key_conn_req;
37 :
38 35 : if (version < SPDM_MESSAGE_VERSION_13) {
39 22 : LIBSPDM_ASSERT(key_pair_id == 0);
40 13 : } else if (version >= SPDM_MESSAGE_VERSION_13) {
41 13 : if (multi_key_conn_rsp) {
42 0 : LIBSPDM_ASSERT(key_pair_id > 0);
43 : } else {
44 13 : LIBSPDM_ASSERT(key_pair_id == 0);
45 : }
46 : }
47 :
48 : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
49 35 : if (g_private_key_mode) {
50 : void *private_pem;
51 : size_t private_pem_size;
52 :
53 35 : if (req_pqc_asym_alg != 0) {
54 0 : result = libspdm_read_requester_pqc_private_key(
55 : req_pqc_asym_alg, &private_pem, &private_pem_size);
56 : } else {
57 35 : result = libspdm_read_requester_private_key(
58 : req_base_asym_alg, &private_pem, &private_pem_size);
59 : }
60 35 : if (!result) {
61 0 : return false;
62 : }
63 :
64 35 : if (req_pqc_asym_alg != 0) {
65 0 : result = libspdm_req_pqc_asym_get_private_key_from_pem(req_pqc_asym_alg,
66 : private_pem,
67 : private_pem_size, NULL,
68 : &context);
69 : } else {
70 35 : result = libspdm_req_asym_get_private_key_from_pem(req_base_asym_alg,
71 : private_pem,
72 : private_pem_size, NULL,
73 : &context);
74 : }
75 35 : if (!result) {
76 0 : libspdm_zero_mem(private_pem, private_pem_size);
77 0 : free(private_pem);
78 0 : return false;
79 : }
80 :
81 35 : if (req_pqc_asym_alg != 0) {
82 0 : if (is_data_hash) {
83 0 : result = libspdm_req_pqc_asym_sign_hash(spdm_version, op_code, req_pqc_asym_alg,
84 : base_hash_algo, context,
85 : message, message_size, signature, sig_size);
86 : } else {
87 0 : result = libspdm_req_pqc_asym_sign(spdm_version, op_code, req_pqc_asym_alg,
88 : base_hash_algo, context,
89 : message, message_size,
90 : signature, sig_size);
91 : }
92 0 : libspdm_req_pqc_asym_free(req_pqc_asym_alg, context);
93 : } else {
94 35 : if (is_data_hash) {
95 13 : result = libspdm_req_asym_sign_hash(spdm_version, op_code, req_base_asym_alg,
96 : base_hash_algo, context,
97 : message, message_size, signature, sig_size);
98 : } else {
99 22 : result = libspdm_req_asym_sign(spdm_version, op_code, req_base_asym_alg,
100 : base_hash_algo, context,
101 : message, message_size,
102 : signature, sig_size);
103 : }
104 35 : libspdm_req_asym_free(req_base_asym_alg, context);
105 : }
106 35 : libspdm_zero_mem(private_pem, private_pem_size);
107 35 : free(private_pem);
108 : } else {
109 : #endif
110 0 : if (req_pqc_asym_alg != 0) {
111 0 : result = libspdm_get_requester_pqc_private_key_from_raw_data(req_pqc_asym_alg, &context);
112 : } else {
113 0 : result = libspdm_get_requester_private_key_from_raw_data(req_base_asym_alg, &context);
114 : }
115 0 : if (!result) {
116 0 : return false;
117 : }
118 :
119 0 : if (req_pqc_asym_alg != 0) {
120 0 : if (is_data_hash) {
121 0 : result = libspdm_req_pqc_asym_sign_hash(spdm_version, op_code, req_pqc_asym_alg,
122 : base_hash_algo, context,
123 : message, message_size, signature, sig_size);
124 : } else {
125 0 : result = libspdm_req_pqc_asym_sign(spdm_version, op_code, req_pqc_asym_alg,
126 : base_hash_algo, context,
127 : message, message_size,
128 : signature, sig_size);
129 : }
130 0 : libspdm_req_pqc_asym_free(req_pqc_asym_alg, context);
131 : } else {
132 0 : if (is_data_hash) {
133 0 : result = libspdm_req_asym_sign_hash(spdm_version, op_code, req_base_asym_alg,
134 : base_hash_algo, context,
135 : message, message_size, signature, sig_size);
136 : } else {
137 0 : result = libspdm_req_asym_sign(spdm_version, op_code, req_base_asym_alg,
138 : base_hash_algo, context,
139 : message, message_size,
140 : signature, sig_size);
141 : }
142 0 : libspdm_req_asym_free(req_base_asym_alg, context);
143 : }
144 : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
145 : }
146 : #endif
147 :
148 : #if LIBSPDM_SECRET_LIB_SIGN_LITTLE_ENDIAN
149 : if ((req_pqc_asym_alg == 0) &&
150 : ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) <= SPDM_MESSAGE_VERSION_11)) {
151 : if (result) {
152 : libspdm_copy_signature_swap_endian(
153 : req_base_asym_alg, signature, *sig_size, signature, *sig_size);
154 : }
155 : }
156 : #endif
157 :
158 35 : return result;
159 : }
160 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) || (...) */
161 :
162 139 : bool libspdm_responder_data_sign(
163 : void *spdm_context,
164 : spdm_version_number_t spdm_version,
165 : uint8_t key_pair_id, uint8_t op_code,
166 : uint32_t base_asym_algo, uint32_t pqc_asym_algo,
167 : uint32_t base_hash_algo, bool is_data_hash,
168 : const uint8_t *message, size_t message_size,
169 : uint8_t *signature, size_t *sig_size)
170 : {
171 : void *context;
172 : bool result;
173 :
174 139 : const uint8_t version = spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT;
175 139 : const bool multi_key_conn_rsp =
176 : ((libspdm_context_t *)spdm_context)->connection_info.multi_key_conn_rsp;
177 :
178 139 : if (version < SPDM_MESSAGE_VERSION_13) {
179 120 : LIBSPDM_ASSERT(key_pair_id == 0);
180 19 : } else if (version >= SPDM_MESSAGE_VERSION_13) {
181 19 : if (multi_key_conn_rsp) {
182 1 : LIBSPDM_ASSERT(key_pair_id > 0);
183 : } else {
184 18 : LIBSPDM_ASSERT(key_pair_id == 0);
185 : }
186 : }
187 :
188 : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
189 139 : if (g_private_key_mode) {
190 : void *private_pem;
191 : size_t private_pem_size;
192 :
193 139 : if (pqc_asym_algo != 0) {
194 0 : result = libspdm_read_responder_pqc_private_key(
195 : pqc_asym_algo, &private_pem, &private_pem_size);
196 : } else {
197 139 : result = libspdm_read_responder_private_key(
198 : base_asym_algo, &private_pem, &private_pem_size);
199 : }
200 139 : if (!result) {
201 0 : return false;
202 : }
203 :
204 139 : if (pqc_asym_algo != 0) {
205 0 : result = libspdm_pqc_asym_get_private_key_from_pem(
206 : pqc_asym_algo, private_pem, private_pem_size, NULL, &context);
207 : } else {
208 139 : result = libspdm_asym_get_private_key_from_pem(
209 : base_asym_algo, private_pem, private_pem_size, NULL, &context);
210 : }
211 139 : if (!result) {
212 0 : libspdm_zero_mem(private_pem, private_pem_size);
213 0 : free(private_pem);
214 0 : return false;
215 : }
216 :
217 139 : if (pqc_asym_algo != 0) {
218 0 : if (is_data_hash) {
219 0 : result = libspdm_pqc_asym_sign_hash(spdm_version, op_code, pqc_asym_algo, base_hash_algo,
220 : context,
221 : message, message_size, signature, sig_size);
222 : } else {
223 0 : result = libspdm_pqc_asym_sign(spdm_version, op_code, pqc_asym_algo,
224 : base_hash_algo, context,
225 : message, message_size,
226 : signature, sig_size);
227 : }
228 0 : libspdm_pqc_asym_free(pqc_asym_algo, context);
229 : } else {
230 139 : if (is_data_hash) {
231 40 : result = libspdm_asym_sign_hash(spdm_version, op_code, base_asym_algo, base_hash_algo,
232 : context,
233 : message, message_size, signature, sig_size);
234 : } else {
235 99 : result = libspdm_asym_sign(spdm_version, op_code, base_asym_algo,
236 : base_hash_algo, context,
237 : message, message_size,
238 : signature, sig_size);
239 : }
240 139 : libspdm_asym_free(base_asym_algo, context);
241 : }
242 139 : libspdm_zero_mem(private_pem, private_pem_size);
243 139 : free(private_pem);
244 : } else {
245 : #endif
246 0 : if (pqc_asym_algo != 0) {
247 0 : result = libspdm_get_responder_pqc_private_key_from_raw_data(pqc_asym_algo, &context);
248 : } else {
249 0 : result = libspdm_get_responder_private_key_from_raw_data(base_asym_algo, &context);
250 : }
251 0 : if (!result) {
252 0 : return false;
253 : }
254 :
255 0 : if (pqc_asym_algo != 0) {
256 0 : if (is_data_hash) {
257 0 : result = libspdm_pqc_asym_sign_hash(spdm_version, op_code, pqc_asym_algo, base_hash_algo,
258 : context,
259 : message, message_size, signature, sig_size);
260 : } else {
261 0 : result = libspdm_pqc_asym_sign(spdm_version, op_code, pqc_asym_algo,
262 : base_hash_algo, context,
263 : message, message_size,
264 : signature, sig_size);
265 : }
266 0 : libspdm_pqc_asym_free(pqc_asym_algo, context);
267 : } else {
268 0 : if (is_data_hash) {
269 0 : result = libspdm_asym_sign_hash(spdm_version, op_code, base_asym_algo, base_hash_algo,
270 : context,
271 : message, message_size, signature, sig_size);
272 : } else {
273 0 : result = libspdm_asym_sign(spdm_version, op_code, base_asym_algo,
274 : base_hash_algo, context,
275 : message, message_size,
276 : signature, sig_size);
277 : }
278 0 : libspdm_asym_free(base_asym_algo, context);
279 : }
280 : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
281 : }
282 : #endif
283 :
284 : #if LIBSPDM_SECRET_LIB_SIGN_LITTLE_ENDIAN
285 : if ((pqc_asym_algo == 0) &&
286 : ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) <= SPDM_MESSAGE_VERSION_11)) {
287 : if (result) {
288 : libspdm_copy_signature_swap_endian(
289 : base_asym_algo, signature, *sig_size, signature, *sig_size);
290 : }
291 : }
292 : #endif
293 :
294 139 : return result;
295 : }
|