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 : 8 : void libspdm_fips_selftest_aes_gcm(void *fips_selftest_context)
14 : : {
15 : : #if LIBSPDM_AEAD_GCM_SUPPORT
16 : 8 : bool result = true;
17 : :
18 : 8 : libspdm_fips_selftest_context_t *context = fips_selftest_context;
19 : 8 : LIBSPDM_ASSERT(fips_selftest_context != NULL);
20 : :
21 : : /* any test fail cause the FIPS fail*/
22 [ + + ]: 8 : if (context->tested_algo != context->self_test_result) {
23 : 4 : return;
24 : : }
25 : :
26 : : /* check if run before.*/
27 [ + + ]: 6 : if ((context->tested_algo & LIBSPDM_FIPS_SELF_TEST_AES_GCM) != 0) {
28 : 2 : return;
29 : : }
30 : :
31 : : uint8_t output_ciphertext[1024];
32 : : uint8_t output_plaintext[1024];
33 : : uint8_t output_tag[1024];
34 : : size_t output_ciphertext_size;
35 : : size_t output_plaintext_size;
36 : :
37 : 4 : output_ciphertext_size = sizeof(output_ciphertext);
38 : 4 : output_plaintext_size = sizeof(output_plaintext);
39 : :
40 : : /*Key to use crypto operation*/
41 : : /* Test vector (key, iv, pt, aad, ct and tag) from the NIST CAVP:
42 : : * gcmtestvectors.zip, gcmEncryptExtIV128.rsp, [Keylen = 128, IVlen = 96,
43 : : * PTlen = 128, AADlen = 128, Taglen = 128], first record.
44 : : * https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/cavp-testing-block-cipher-modes
45 : : */
46 : 4 : const uint8_t key[] = {
47 : : 0xc9, 0x39, 0xcc, 0x13, 0x39, 0x7c, 0x1d, 0x37,
48 : : 0xde, 0x6a, 0xe0, 0xe1, 0xcb, 0x7c, 0x42, 0x3c
49 : : };
50 : :
51 : : /*IV to perform the crypto operation upon*/
52 : 4 : const uint8_t iv[] = {
53 : : 0xb3, 0xd8, 0xcc, 0x01, 0x7c, 0xbb, 0x89, 0xb3,
54 : : 0x9e, 0x0f, 0x67, 0xe2
55 : : };
56 : :
57 : : /*Data to perform the crypto operation upon*/
58 : 4 : const uint8_t input[] = {
59 : : 0xc3, 0xb3, 0xc4, 0x1f, 0x11, 0x3a, 0x31, 0xb7,
60 : : 0x3d, 0x9a, 0x5c, 0xd4, 0x32, 0x10, 0x30, 0x69
61 : : };
62 : :
63 : : /*Additional auth data*/
64 : 4 : const uint8_t aad[] = {
65 : : 0x24, 0x82, 0x56, 0x02, 0xbd, 0x12, 0xa9, 0x84,
66 : : 0xe0, 0x09, 0x2d, 0x3e, 0x44, 0x8e, 0xda, 0x5f
67 : : };
68 : :
69 : : /*Expected ciphertext*/
70 : 4 : const uint8_t expected_ciphertext[] = {
71 : : 0x93, 0xfe, 0x7d, 0x9e, 0x9b, 0xfd, 0x10, 0x34,
72 : : 0x8a, 0x56, 0x06, 0xe5, 0xca, 0xfa, 0x73, 0x54
73 : : };
74 : :
75 : : /*Expected Auth Tag*/
76 : 4 : const uint8_t expected_tag[] = {
77 : : 0x00, 0x32, 0xa1, 0xdc, 0x85, 0xf1, 0xc9, 0x78,
78 : : 0x69, 0x25, 0xa2, 0xe7, 0x1d, 0x82, 0x72, 0xdd
79 : : };
80 : :
81 : : /*KAT test*/
82 : 4 : libspdm_zero_mem(output_ciphertext, sizeof(output_ciphertext));
83 : 4 : libspdm_zero_mem(output_tag, sizeof(output_tag));
84 : 4 : result = libspdm_aead_aes_gcm_encrypt(key, sizeof(key), iv, sizeof(iv), aad, sizeof(aad),
85 : : input, sizeof(input), output_tag, sizeof(expected_tag),
86 : : output_ciphertext, &output_ciphertext_size);
87 [ - + ]: 4 : if (!result) {
88 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aes_gcm encrypt failed \n"));
89 : 0 : goto update;
90 : : }
91 : :
92 [ - + ]: 4 : if (output_ciphertext_size != sizeof(expected_ciphertext)) {
93 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aes_gcm KAT failed \n"));
94 : 0 : result = false;
95 : 0 : goto update;
96 : : }
97 : :
98 [ - + ]: 4 : if (!libspdm_consttime_is_mem_equal(output_ciphertext, expected_ciphertext,
99 : : sizeof(expected_ciphertext))) {
100 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aes_gcm KAT failed \n"));
101 : 0 : result = false;
102 : 0 : goto update;
103 : : }
104 : :
105 [ - + ]: 4 : if (!libspdm_consttime_is_mem_equal(output_tag, expected_tag, sizeof(expected_tag))) {
106 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aes_gcm KAT failed \n"));
107 : 0 : result = false;
108 : 0 : goto update;
109 : : }
110 : :
111 : 4 : libspdm_zero_mem(output_plaintext, sizeof(output_plaintext));
112 : 4 : result = libspdm_aead_aes_gcm_decrypt(key, sizeof(key), iv, sizeof(iv), aad, sizeof(aad),
113 : : expected_ciphertext, sizeof(expected_ciphertext),
114 : : expected_tag, sizeof(expected_tag),
115 : : output_plaintext, &output_plaintext_size);
116 [ - + ]: 4 : if (!result) {
117 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aes_gcm decrypt failed \n"));
118 : 0 : result = false;
119 : 0 : goto update;
120 : : }
121 : :
122 [ - + ]: 4 : if (output_plaintext_size != sizeof(input)) {
123 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aes_gcm selftest failed \n"));
124 : 0 : result = false;
125 : 0 : goto update;
126 : : }
127 : :
128 [ + - ]: 4 : if (!libspdm_consttime_is_mem_equal(output_plaintext, input, sizeof(input))) {
129 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aes_gcm selftest failed \n"));
130 : 0 : result = false;
131 : 0 : goto update;
132 : : }
133 : :
134 : 4 : update:
135 : : /* mark it as tested*/
136 : 4 : context->tested_algo |= LIBSPDM_FIPS_SELF_TEST_AES_GCM;
137 : :
138 : : /* record test result*/
139 [ + - ]: 4 : if (result) {
140 : 4 : context->self_test_result |= LIBSPDM_FIPS_SELF_TEST_AES_GCM;
141 : : } else {
142 : 0 : context->self_test_result &= ~LIBSPDM_FIPS_SELF_TEST_AES_GCM;
143 : : }
144 : :
145 : : #endif/*LIBSPDM_AEAD_GCM_SUPPORT*/
146 : : }
147 : :
148 : : #endif
|