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 : 1 : void libspdm_fips_selftest_mlkem(void *fips_selftest_context)
14 : : {
15 : : #if LIBSPDM_ML_KEM_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_ML_KEM) != 0) {
28 : : 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 : : shared_secret_size = sizeof(shared_secret);
38 : : libspdm_zero_mem(shared_secret, shared_secret_size);
39 : :
40 : : cipher_text_size = 1568;
41 : : LIBSPDM_ASSERT(context->selftest_buffer_size >= cipher_text_size);
42 : : LIBSPDM_ASSERT(context->selftest_buffer != NULL);
43 : : libspdm_zero_mem(context->selftest_buffer, context->selftest_buffer_size);
44 : : 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 : : kem_context = libspdm_mlkem_new_by_name(LIBSPDM_CRYPTO_NID_ML_KEM_1024);
53 : : if (kem_context == NULL) {
54 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM new failed \n"));
55 : : result = false;
56 : : goto update;
57 : : }
58 : :
59 : : 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 : : if (!result) {
65 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM encapsulate failed \n"));
66 : : libspdm_mlkem_free(kem_context);
67 : : result = false;
68 : : goto update;
69 : : }
70 : :
71 : : /*KAT test*/
72 : : if (cipher_text_size != sizeof(expected_cipher_text_mlkem_1024)) {
73 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
74 : : libspdm_mlkem_free(kem_context);
75 : : result = false;
76 : : goto update;
77 : : }
78 : :
79 : : if (!libspdm_consttime_is_mem_equal(cipher_text, expected_cipher_text_mlkem_1024,
80 : : sizeof(expected_cipher_text_mlkem_1024))) {
81 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
82 : : libspdm_mlkem_free(kem_context);
83 : : result = false;
84 : : goto update;
85 : : }
86 : :
87 : : if (shared_secret_size != sizeof(expected_shared_secret_mlkem_1024)) {
88 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
89 : : libspdm_mlkem_free(kem_context);
90 : : result = false;
91 : : goto update;
92 : : }
93 : :
94 : : if (!libspdm_consttime_is_mem_equal(shared_secret, expected_shared_secret_mlkem_1024,
95 : : sizeof(expected_shared_secret_mlkem_1024))) {
96 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
97 : : libspdm_mlkem_free(kem_context);
98 : : result = false;
99 : : goto update;
100 : : }
101 : :
102 : : result = libspdm_mlkem_set_privkey(kem_context, decap_key_mlkem_1024, sizeof(decap_key_mlkem_1024));
103 : : if (!result) {
104 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM set private key failed \n"));
105 : : libspdm_mlkem_free(kem_context);
106 : : result = false;
107 : : goto update;
108 : : }
109 : :
110 : : result = libspdm_mlkem_decapsulate(kem_context, cipher_text, cipher_text_size,
111 : : shared_secret, &shared_secret_size);
112 : : if (!result) {
113 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM decapsulate failed \n"));
114 : : libspdm_mlkem_free(kem_context);
115 : : result = false;
116 : : goto update;
117 : : }
118 : :
119 : : if (shared_secret_size != sizeof(expected_shared_secret_mlkem_1024)) {
120 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
121 : : libspdm_mlkem_free(kem_context);
122 : : result = false;
123 : : goto update;
124 : : }
125 : :
126 : : if (!libspdm_consttime_is_mem_equal(shared_secret, expected_shared_secret_mlkem_1024,
127 : : sizeof(expected_shared_secret_mlkem_1024))) {
128 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ML-KEM KAT failed \n"));
129 : : libspdm_mlkem_free(kem_context);
130 : : result = false;
131 : : goto update;
132 : : }
133 : :
134 : : update:
135 : : /* mark it as tested*/
136 : : context->tested_algo |= LIBSPDM_FIPS_SELF_TEST_ML_KEM;
137 : :
138 : : /* record test result*/
139 : : if (result) {
140 : : context->self_test_result |= LIBSPDM_FIPS_SELF_TEST_ML_KEM;
141 : : } else {
142 : : context->self_test_result &= ~LIBSPDM_FIPS_SELF_TEST_ML_KEM;
143 : : }
144 : :
145 : : #endif/*LIBSPDM_ML_KEM_SUPPORT*/
146 : 1 : }
147 : :
148 : : #endif/*LIBSPDM_FIPS_MODE*/
|