Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2023-2026 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 "internal/libspdm_crypt_lib.h"
8 : #include "internal/libspdm_common_lib.h"
9 : #include "internal/libspdm_fips_lib.h"
10 :
11 : #if LIBSPDM_FIPS_MODE
12 :
13 1 : bool libspdm_fips_selftest_eddsa(void *fips_selftest_context)
14 : {
15 1 : bool result = true;
16 :
17 : #if LIBSPDM_EDDSA_SUPPORT
18 : libspdm_fips_selftest_context_t *context = fips_selftest_context;
19 : LIBSPDM_ASSERT(fips_selftest_context != NULL);
20 :
21 : /* any test fail cause the FIPS fail*/
22 : if (context->tested_algo != context->self_test_result) {
23 : return false;
24 : }
25 :
26 : /* check if run before.*/
27 : if ((context->tested_algo & LIBSPDM_FIPS_SELF_TEST_EDDSA) != 0) {
28 : return true;
29 : }
30 :
31 : #if LIBSPDM_EDDSA_ED25519_SUPPORT
32 :
33 : void *ecd_25519;
34 : uint8_t signature_25519[32 * 2];
35 : size_t sig25519_size;
36 : uint8_t get_pub_key_25519[32];
37 : size_t get_pub_key_25519_size = sizeof(get_pub_key_25519);
38 :
39 : /*test vectors from https://www.rfc-editor.org/rfc/rfc8032 */
40 : uint8_t message_25519[] = {
41 : 0x72
42 : };
43 :
44 : const uint8_t public_key_25519[] = {
45 : 0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a, 0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e,
46 : 0xbc, 0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c, 0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4,
47 : 0x66, 0x0c
48 : };
49 :
50 : const uint8_t private_key_25519[] = {
51 : 0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda, 0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e,
52 : 0x0f, 0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24, 0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8,
53 : 0xa6, 0xfb
54 : };
55 :
56 : /* Expected signature*/
57 : const uint8_t expected_signature_25519[] = {
58 : 0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8, 0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25,
59 : 0x40, 0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f, 0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb,
60 : 0x69, 0xda, 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e, 0x45, 0x8f, 0x36, 0x13, 0xd0,
61 : 0xf1, 0x1d, 0x8c, 0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, 0xb0, 0x0d, 0x29, 0x16,
62 : 0x12, 0xbb, 0x0c, 0x00
63 : };
64 :
65 : ecd_25519 = libspdm_ecd_new_by_nid(LIBSPDM_CRYPTO_NID_EDDSA_ED25519);
66 : if (ecd_25519 == NULL) {
67 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 gen failed \n"));
68 : result = false;
69 : goto update;
70 : }
71 :
72 : result = libspdm_ecd_set_pub_key(ecd_25519, public_key_25519, sizeof(public_key_25519));
73 : if (!result) {
74 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 set public key failed \n"));
75 : libspdm_ecd_free(ecd_25519);
76 : result = false;
77 : goto update;
78 : }
79 :
80 : result = libspdm_ecd_get_pub_key(ecd_25519, get_pub_key_25519, &get_pub_key_25519_size);
81 : if (!result) {
82 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 get pub key failed \n"));
83 : libspdm_ecd_free(ecd_25519);
84 : result = false;
85 : goto update;
86 : }
87 :
88 : if (get_pub_key_25519_size != sizeof(public_key_25519)) {
89 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 get key size compare failed \n"));
90 : libspdm_ecd_free(ecd_25519);
91 : result = false;
92 : goto update;
93 : }
94 :
95 : if (!libspdm_consttime_is_mem_equal(get_pub_key_25519, public_key_25519,
96 : sizeof(public_key_25519))) {
97 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 get key content compare failed \n"));
98 : libspdm_ecd_free(ecd_25519);
99 : result = false;
100 : goto update;
101 : }
102 :
103 : result = libspdm_ecd_set_pri_key(ecd_25519, private_key_25519, sizeof(private_key_25519));
104 : if (!result) {
105 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 set private key failed \n"));
106 : libspdm_ecd_free(ecd_25519);
107 : result = false;
108 : goto update;
109 : }
110 :
111 : /* Verify Ed-DSA*/
112 : sig25519_size = sizeof(signature_25519);
113 : result = libspdm_eddsa_sign(ecd_25519, LIBSPDM_CRYPTO_NID_NULL, NULL, 0, message_25519,
114 : sizeof(message_25519), signature_25519, &sig25519_size);
115 : if (!result) {
116 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 sign failed \n"));
117 : libspdm_ecd_free(ecd_25519);
118 : result = false;
119 : goto update;
120 : }
121 :
122 : if (!libspdm_consttime_is_mem_equal(signature_25519, expected_signature_25519,
123 : sizeof(expected_signature_25519))) {
124 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 KAT failed \n"));
125 : libspdm_ecd_free(ecd_25519);
126 : result = false;
127 : goto update;
128 : }
129 :
130 : result = libspdm_eddsa_verify(ecd_25519, LIBSPDM_CRYPTO_NID_NULL, NULL, 0, message_25519,
131 : sizeof(message_25519), signature_25519, sig25519_size);
132 : if (!result) {
133 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 25519 verify failed \n"));
134 : libspdm_ecd_free(ecd_25519);
135 : result = false;
136 : goto update;
137 : }
138 :
139 : libspdm_ecd_free(ecd_25519);
140 :
141 : #endif/*LIBSPDM_EDDSA_ED25519_SUPPORT */
142 :
143 : #if LIBSPDM_EDDSA_ED448_SUPPORT
144 : void *ecd_448;
145 : uint8_t signature_448[57 * 2];
146 : size_t sig448_size;
147 : uint8_t get_edd48_key[57];
148 : size_t get_pub_key_448_size = sizeof(get_edd48_key);
149 :
150 : /*test vectors from https://www.rfc-editor.org/rfc/rfc8032 */
151 : uint8_t message_448[] = {
152 : 0x03
153 : };
154 :
155 : const uint8_t public_key_448[] = {
156 : 0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45, 0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd,
157 : 0x0a, 0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37, 0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98,
158 : 0xc0, 0x86, 0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02, 0xb8, 0x43, 0x8e, 0xa4, 0xcb,
159 : 0x82, 0x16, 0x9c, 0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94, 0x80
160 : };
161 :
162 : const uint8_t private_key_448[] = {
163 : 0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6, 0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92,
164 : 0x4d, 0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d, 0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c,
165 : 0x46, 0x3a, 0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c, 0x5e, 0x3b, 0xc3, 0x97, 0xa6,
166 : 0x59, 0x94, 0x9e, 0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27, 0x4e
167 : };
168 :
169 : /* Expected signature*/
170 : const uint8_t expected_signature_448[] = {
171 : 0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89, 0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3,
172 : 0x77, 0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35, 0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10,
173 : 0xf4, 0x35, 0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7, 0xe1, 0x8f, 0x62, 0xde, 0x8c,
174 : 0xcd, 0xf6, 0x33, 0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79, 0x80, 0x5e, 0x0d, 0xbc,
175 : 0xc0, 0xaa, 0xe1, 0xcb, 0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36, 0xbc, 0x04, 0xdc,
176 : 0xec, 0xbf, 0x15, 0x43, 0x36, 0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29, 0x05, 0xe7,
177 : 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f, 0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf, 0xd1,
178 : 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0, 0x3a
179 : };
180 :
181 : ecd_448 = libspdm_ecd_new_by_nid(LIBSPDM_CRYPTO_NID_EDDSA_ED448);
182 : if (ecd_448 == NULL) {
183 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 gen failed \n"));
184 : result = false;
185 : goto update;
186 : }
187 :
188 : result = libspdm_ecd_set_pub_key(ecd_448, public_key_448, sizeof(public_key_448));
189 : if (!result) {
190 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 set public key failed \n"));
191 : libspdm_ecd_free(ecd_448);
192 : result = false;
193 : goto update;
194 : }
195 :
196 : result = libspdm_ecd_get_pub_key(ecd_448, get_edd48_key, &get_pub_key_448_size);
197 : if (!result) {
198 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 get pub key failed \n"));
199 : libspdm_ecd_free(ecd_448);
200 : result = false;
201 : goto update;
202 : }
203 :
204 : if (get_pub_key_448_size != sizeof(public_key_448)) {
205 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 get key compare failed \n"));
206 : libspdm_ecd_free(ecd_448);
207 : result = false;
208 : goto update;
209 : }
210 :
211 : if (!libspdm_consttime_is_mem_equal(get_edd48_key, public_key_448,
212 : sizeof(public_key_448))) {
213 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 get key compare failed \n"));
214 : libspdm_ecd_free(ecd_448);
215 : result = false;
216 : goto update;
217 : }
218 :
219 : result = libspdm_ecd_set_pri_key(ecd_448, private_key_448, sizeof(private_key_448));
220 : if (!result) {
221 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 set private key failed \n"));
222 : libspdm_ecd_free(ecd_448);
223 : result = false;
224 : goto update;
225 : }
226 :
227 : /* Verify Ed-DSA*/
228 : sig448_size = sizeof(signature_448);
229 : result = libspdm_eddsa_sign(ecd_448, LIBSPDM_CRYPTO_NID_NULL, NULL, 0, message_448,
230 : sizeof(message_448), signature_448, &sig448_size);
231 : if (!result) {
232 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 sign failed \n"));
233 : libspdm_ecd_free(ecd_448);
234 : result = false;
235 : goto update;
236 : }
237 :
238 : if (!libspdm_consttime_is_mem_equal(signature_448, expected_signature_448,
239 : sizeof(expected_signature_448))) {
240 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 KAT failed \n"));
241 : libspdm_ecd_free(ecd_448);
242 : result = false;
243 : goto update;
244 : }
245 :
246 : result = libspdm_eddsa_verify(ecd_448, LIBSPDM_CRYPTO_NID_NULL, NULL, 0, message_448,
247 : sizeof(message_448), signature_448, sig448_size);
248 : if (!result) {
249 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "EDDSA 448 verify failed \n"));
250 : libspdm_ecd_free(ecd_448);
251 : result = false;
252 : goto update;
253 : }
254 :
255 : libspdm_ecd_free(ecd_448);
256 : #endif/*LIBSPDM_EDDSA_ED448_SUPPORT*/
257 :
258 : update:
259 : /* mark it as tested*/
260 : context->tested_algo |= LIBSPDM_FIPS_SELF_TEST_EDDSA;
261 :
262 : /* record test result*/
263 : if (result) {
264 : context->self_test_result |= LIBSPDM_FIPS_SELF_TEST_EDDSA;
265 : } else {
266 : context->self_test_result &= ~LIBSPDM_FIPS_SELF_TEST_EDDSA;
267 : }
268 :
269 : #endif /* LIBSPDM_EDDSA_SUPPORT */
270 1 : return result;
271 : }
272 :
273 : #endif/*LIBSPDM_FIPS_MODE*/
|