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 1 : void libspdm_fips_selftest_ffdh(void *fips_selftest_context)
13 : {
14 : #if LIBSPDM_FFDHE_SUPPORT
15 1 : bool result = true;
16 :
17 1 : libspdm_fips_selftest_context_t *context = fips_selftest_context;
18 1 : LIBSPDM_ASSERT(fips_selftest_context != NULL);
19 :
20 : /* any test fail cause the FIPS fail*/
21 1 : if (context->tested_algo != context->self_test_result) {
22 0 : return;
23 : }
24 :
25 : /* check if run before.*/
26 1 : if ((context->tested_algo & LIBSPDM_FIPS_SELF_TEST_FFDH) != 0) {
27 0 : return;
28 : }
29 :
30 : void *dh1;
31 : void *dh2;
32 : uint8_t ff_public_key1[256];
33 : size_t ff_public_key1_length;
34 : uint8_t ff_public_key2[256];
35 : size_t ff_public_key2_length;
36 : uint8_t ff_key1[256];
37 : size_t ff_key1_length;
38 : uint8_t ff_key2[256];
39 : size_t ff_key2_length;
40 :
41 1 : ff_public_key1_length = sizeof(ff_public_key1);
42 1 : ff_public_key2_length = sizeof(ff_public_key2);
43 1 : ff_key1_length = sizeof(ff_key1);
44 1 : ff_key2_length = sizeof(ff_key2);
45 :
46 1 : dh1 = libspdm_dh_new_by_nid(LIBSPDM_CRYPTO_NID_FFDHE2048);
47 1 : if (dh1 == NULL) {
48 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "FFDH gen dh1 failed \n"));
49 0 : result = false;
50 0 : goto update;
51 : }
52 :
53 1 : dh2 = libspdm_dh_new_by_nid(LIBSPDM_CRYPTO_NID_FFDHE2048);
54 1 : if (dh2 == NULL) {
55 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "FFDH gen dh2 failed \n"));
56 0 : libspdm_dh_free(dh1);
57 0 : result = false;
58 0 : goto update;
59 : }
60 :
61 1 : result = libspdm_dh_generate_key(dh1, ff_public_key1, &ff_public_key1_length);
62 1 : if (!result || ff_public_key1_length != 256) {
63 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "FFDH generate key1 failed \n"));
64 0 : libspdm_dh_free(dh1);
65 0 : libspdm_dh_free(dh2);
66 0 : result = false;
67 0 : goto update;
68 : }
69 :
70 1 : result = libspdm_dh_generate_key(dh2, ff_public_key2, &ff_public_key2_length);
71 1 : if (!result || ff_public_key2_length != 256) {
72 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "FFDH generate key2 failed \n"));
73 0 : libspdm_dh_free(dh1);
74 0 : libspdm_dh_free(dh2);
75 0 : result = false;
76 0 : goto update;
77 : }
78 :
79 1 : result = libspdm_dh_compute_key(dh1, ff_public_key2, ff_public_key2_length,
80 : ff_key1, &ff_key1_length);
81 1 : if (!result || ff_key1_length != 256) {
82 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "FFDH compute key failed \n"));
83 0 : libspdm_dh_free(dh1);
84 0 : libspdm_dh_free(dh2);
85 0 : result = false;
86 0 : goto update;
87 : }
88 :
89 1 : result = libspdm_dh_compute_key(dh2, ff_public_key1, ff_public_key1_length,
90 : ff_key2, &ff_key2_length);
91 1 : if (!result || ff_key2_length != 256) {
92 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "FFDH compute key failed \n"));
93 0 : libspdm_dh_free(dh1);
94 0 : libspdm_dh_free(dh2);
95 0 : result = false;
96 0 : goto update;
97 : }
98 :
99 1 : if (!libspdm_consttime_is_mem_equal(ff_key1, ff_key2, ff_key1_length)) {
100 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "FFDH self_test failed \n"));
101 0 : libspdm_dh_free(dh1);
102 0 : libspdm_dh_free(dh2);
103 0 : result = false;
104 0 : goto update;
105 : }
106 :
107 1 : libspdm_dh_free(dh1);
108 1 : libspdm_dh_free(dh2);
109 :
110 1 : update:
111 : /* mark it as tested*/
112 1 : context->tested_algo |= LIBSPDM_FIPS_SELF_TEST_FFDH;
113 :
114 : /* record test result*/
115 1 : if (result) {
116 1 : context->self_test_result |= LIBSPDM_FIPS_SELF_TEST_FFDH;
117 : } else {
118 0 : context->self_test_result &= ~LIBSPDM_FIPS_SELF_TEST_FFDH;
119 : }
120 :
121 : #endif/*LIBSPDM_FFDHE_SUPPORT*/
122 : }
123 :
124 : #endif/*LIBSPDM_FIPS_MODE*/
|