Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2025-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 : 8 : void libspdm_fips_selftest_mlkem(void *fips_selftest_context)
14 : : {
15 : : #if LIBSPDM_ML_KEM_SUPPORT
16 : 4 : bool result = true;
17 : :
18 : 4 : libspdm_fips_selftest_context_t *context = fips_selftest_context;
19 : 4 : LIBSPDM_ASSERT(fips_selftest_context != NULL);
20 : :
21 : : /* any test fail cause the FIPS fail*/
22 [ + + ]: 4 : if (context->tested_algo != context->self_test_result) {
23 : 2 : return;
24 : : }
25 : :
26 : : /* check if run before.*/
27 [ + + ]: 3 : if ((context->tested_algo & LIBSPDM_FIPS_SELF_TEST_ML_KEM) != 0) {
28 : 1 : return;
29 : : }
30 : :
31 : : void *kem_context;
32 : : uint8_t shared_secret[32];
33 : : size_t shared_secret_size;
34 : : uint8_t *cipher_text;
35 : : size_t cipher_text_size;
36 : :
37 : 2 : shared_secret_size = sizeof(shared_secret);
38 : 2 : libspdm_zero_mem(shared_secret, shared_secret_size);
39 : :
40 : 2 : cipher_text_size = 1568;
41 : 2 : LIBSPDM_ASSERT(context->selftest_buffer_size >= cipher_text_size);
42 : 2 : LIBSPDM_ASSERT(context->selftest_buffer != NULL);
43 : 2 : libspdm_zero_mem(context->selftest_buffer, context->selftest_buffer_size);
44 : 2 : cipher_text = context->selftest_buffer;
45 : :
46 : : extern uint8_t peer_encap_key_mlkem_1024[1568];
47 : : extern uint8_t decap_key_mlkem_1024[3168];
48 : : extern uint8_t expected_cipher_text_mlkem_1024[1568];
49 : : extern uint8_t expected_shared_secret_mlkem_1024[32];
50 : : extern uint8_t random_value_mlkem_1024[32];
51 : :
52 : 2 : kem_context = libspdm_mlkem_new_by_name(LIBSPDM_CRYPTO_NID_ML_KEM_1024);
53 [ - + ]: 2 : if (kem_context == NULL) {
54 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM new failed \n"));
55 : 0 : result = false;
56 : 0 : goto update;
57 : : }
58 : :
59 : 2 : result = libspdm_mlkem_encapsulate_ex(kem_context, peer_encap_key_mlkem_1024,
60 : : sizeof(peer_encap_key_mlkem_1024),
61 : : cipher_text, &cipher_text_size,
62 : : shared_secret, &shared_secret_size,
63 : : random_value_mlkem_1024, sizeof(random_value_mlkem_1024));
64 [ - + ]: 2 : if (!result) {
65 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM encapsulate failed \n"));
66 : 0 : libspdm_mlkem_free(kem_context);
67 : 0 : result = false;
68 : 0 : goto update;
69 : : }
70 : :
71 : : /*KAT test*/
72 [ - + ]: 2 : if (cipher_text_size != sizeof(expected_cipher_text_mlkem_1024)) {
73 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
74 : 0 : libspdm_mlkem_free(kem_context);
75 : 0 : result = false;
76 : 0 : goto update;
77 : : }
78 : :
79 [ - + ]: 2 : if (!libspdm_consttime_is_mem_equal(cipher_text, expected_cipher_text_mlkem_1024,
80 : : sizeof(expected_cipher_text_mlkem_1024))) {
81 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
82 : 0 : libspdm_mlkem_free(kem_context);
83 : 0 : result = false;
84 : 0 : goto update;
85 : : }
86 : :
87 [ - + ]: 2 : if (shared_secret_size != sizeof(expected_shared_secret_mlkem_1024)) {
88 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
89 : 0 : libspdm_mlkem_free(kem_context);
90 : 0 : result = false;
91 : 0 : goto update;
92 : : }
93 : :
94 [ - + ]: 2 : if (!libspdm_consttime_is_mem_equal(shared_secret, expected_shared_secret_mlkem_1024,
95 : : sizeof(expected_shared_secret_mlkem_1024))) {
96 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
97 : 0 : libspdm_mlkem_free(kem_context);
98 : 0 : result = false;
99 : 0 : goto update;
100 : : }
101 : :
102 : 2 : result = libspdm_mlkem_set_privkey(kem_context, decap_key_mlkem_1024, sizeof(decap_key_mlkem_1024));
103 [ - + ]: 2 : if (!result) {
104 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM set private key failed \n"));
105 : 0 : libspdm_mlkem_free(kem_context);
106 : 0 : result = false;
107 : 0 : goto update;
108 : : }
109 : :
110 : 2 : result = libspdm_mlkem_decapsulate(kem_context, cipher_text, cipher_text_size,
111 : : shared_secret, &shared_secret_size);
112 [ - + ]: 2 : if (!result) {
113 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM decapsulate failed \n"));
114 : 0 : libspdm_mlkem_free(kem_context);
115 : 0 : result = false;
116 : 0 : goto update;
117 : : }
118 : :
119 [ - + ]: 2 : if (shared_secret_size != sizeof(expected_shared_secret_mlkem_1024)) {
120 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
121 : 0 : libspdm_mlkem_free(kem_context);
122 : 0 : result = false;
123 : 0 : goto update;
124 : : }
125 : :
126 [ - + ]: 2 : if (!libspdm_consttime_is_mem_equal(shared_secret, expected_shared_secret_mlkem_1024,
127 : : sizeof(expected_shared_secret_mlkem_1024))) {
128 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
129 : 0 : libspdm_mlkem_free(kem_context);
130 : 0 : result = false;
131 : 0 : goto update;
132 : : }
133 : :
134 : 2 : libspdm_mlkem_free(kem_context);
135 : :
136 : 2 : update:
137 : : /* mark it as tested*/
138 : 2 : context->tested_algo |= LIBSPDM_FIPS_SELF_TEST_ML_KEM;
139 : :
140 : : /* record test result*/
141 [ + - ]: 2 : if (result) {
142 : 2 : context->self_test_result |= LIBSPDM_FIPS_SELF_TEST_ML_KEM;
143 : : } else {
144 : 0 : context->self_test_result &= ~LIBSPDM_FIPS_SELF_TEST_ML_KEM;
145 : : }
146 : :
147 : : #endif/*LIBSPDM_ML_KEM_SUPPORT*/
148 : 4 : }
149 : :
150 : : #endif/*LIBSPDM_FIPS_MODE*/
|