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