Branch data 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 : void libspdm_fips_selftest_eddsa(void *fips_selftest_context)
14 : : {
15 : : #if LIBSPDM_EDDSA_SUPPORT
16 : : bool result = true;
17 : :
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;
24 : : }
25 : :
26 : : /* check if run before.*/
27 : : if ((context->tested_algo & LIBSPDM_FIPS_SELF_TEST_EDDSA) != 0) {
28 : : return;
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 : }
271 : :
272 : : #endif/*LIBSPDM_FIPS_MODE*/
|