Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2022 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_lib_config.h"
8 : #include "spdm_crypt_ext_lib/spdm_crypt_ext_lib.h"
9 : #include "hal/library/cryptlib.h"
10 : #include "spdm_crypt_ext_lib/cryptlib_ext.h"
11 : #include "industry_standard/spdm.h"
12 : #include "hal/library/debuglib.h"
13 :
14 : /**
15 : * Return asymmetric GET_PRIVATE_KEY_FROM_PEM function, based upon the asymmetric algorithm.
16 : *
17 : * @param base_asym_algo SPDM base_asym_algo
18 : *
19 : * @return asymmetric GET_PRIVATE_KEY_FROM_PEM function
20 : **/
21 : libspdm_asym_get_private_key_from_pem_func
22 181 : libspdm_get_asym_get_private_key_from_pem(uint32_t base_asym_algo)
23 : {
24 181 : switch (base_asym_algo) {
25 36 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
26 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
27 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
28 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
29 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
30 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
31 : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
32 36 : return libspdm_rsa_get_private_key_from_pem;
33 : #else
34 : LIBSPDM_ASSERT(false);
35 : break;
36 : #endif
37 145 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
38 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
39 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
40 : #if LIBSPDM_ECDSA_SUPPORT
41 145 : return libspdm_ec_get_private_key_from_pem;
42 : #else
43 : LIBSPDM_ASSERT(false);
44 : break;
45 : #endif
46 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
47 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
48 : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
49 : return libspdm_ecd_get_private_key_from_pem;
50 : #else
51 0 : LIBSPDM_ASSERT(false);
52 0 : break;
53 : #endif
54 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
55 : #if LIBSPDM_SM2_DSA_SUPPORT
56 : return libspdm_sm2_get_private_key_from_pem;
57 : #else
58 0 : LIBSPDM_ASSERT(false);
59 0 : break;
60 : #endif
61 0 : default:
62 0 : LIBSPDM_ASSERT(false);
63 0 : break;
64 : }
65 :
66 0 : return NULL;
67 : }
68 :
69 : /**
70 : * Retrieve the Private key from the password-protected PEM key data.
71 : *
72 : * @param base_asym_algo SPDM base_asym_algo
73 : * @param pem_data Pointer to the PEM-encoded key data to be retrieved.
74 : * @param pem_size size of the PEM key data in bytes.
75 : * @param password NULL-terminated passphrase used for encrypted PEM key data.
76 : * @param context Pointer to newly generated asymmetric context which contain the retrieved private key component.
77 : * Use libspdm_asym_free() function to free the resource.
78 : *
79 : * @retval true Private key was retrieved successfully.
80 : * @retval false Invalid PEM key data or incorrect password.
81 : **/
82 145 : bool libspdm_asym_get_private_key_from_pem(uint32_t base_asym_algo,
83 : const uint8_t *pem_data,
84 : size_t pem_size,
85 : const char *password,
86 : void **context)
87 : {
88 : libspdm_asym_get_private_key_from_pem_func asym_get_private_key_from_pem;
89 145 : asym_get_private_key_from_pem = libspdm_get_asym_get_private_key_from_pem(base_asym_algo);
90 145 : if (asym_get_private_key_from_pem == NULL) {
91 0 : return false;
92 : }
93 145 : return asym_get_private_key_from_pem(pem_data, pem_size, password, context);
94 : }
95 :
96 : /**
97 : * Return asymmetric GET_PRIVATE_KEY_FROM_PEM function, based upon the asymmetric algorithm.
98 : *
99 : * @param req_base_asym_alg SPDM req_base_asym_alg
100 : *
101 : * @return asymmetric GET_PRIVATE_KEY_FROM_PEM function
102 : **/
103 : static libspdm_asym_get_private_key_from_pem_func
104 36 : libspdm_get_req_asym_get_private_key_from_pem(uint16_t req_base_asym_alg)
105 : {
106 36 : return libspdm_get_asym_get_private_key_from_pem(req_base_asym_alg);
107 : }
108 :
109 : /**
110 : * Retrieve the Private key from the password-protected PEM key data.
111 : *
112 : * @param req_base_asym_alg SPDM req_base_asym_alg
113 : * @param pem_data Pointer to the PEM-encoded key data to be retrieved.
114 : * @param pem_size size of the PEM key data in bytes.
115 : * @param password NULL-terminated passphrase used for encrypted PEM key data.
116 : * @param context Pointer to newly generated asymmetric context which contain the retrieved private key component.
117 : * Use libspdm_asym_free() function to free the resource.
118 : *
119 : * @retval true Private key was retrieved successfully.
120 : * @retval false Invalid PEM key data or incorrect password.
121 : **/
122 36 : bool libspdm_req_asym_get_private_key_from_pem(uint16_t req_base_asym_alg,
123 : const uint8_t *pem_data,
124 : size_t pem_size,
125 : const char *password,
126 : void **context)
127 : {
128 : libspdm_asym_get_private_key_from_pem_func asym_get_private_key_from_pem;
129 : asym_get_private_key_from_pem =
130 36 : libspdm_get_req_asym_get_private_key_from_pem(req_base_asym_alg);
131 36 : if (asym_get_private_key_from_pem == NULL) {
132 0 : return false;
133 : }
134 36 : return asym_get_private_key_from_pem(pem_data, pem_size, password,
135 : context);
136 : }
137 :
138 : /**
139 : * Computes the hash of a input data buffer.
140 : *
141 : * This function performs the hash of a given data buffer, and return the hash value.
142 : *
143 : * @param data Pointer to the buffer containing the data to be hashed.
144 : * @param data_size Size of data buffer in bytes.
145 : * @param hash_value Pointer to a buffer that receives the hash value.
146 : *
147 : * @retval true hash computation succeeded.
148 : * @retval false hash computation failed.
149 : **/
150 : typedef bool (*libspdm_hash_all_func)(const void *data, size_t data_size, uint8_t *hash_value);
151 :
152 : /**
153 : * Return hash function, based upon the negotiated measurement hash algorithm.
154 : *
155 : * @param measurement_hash_algo SPDM measurement_hash_algo
156 : *
157 : * @return hash function
158 : **/
159 214 : static libspdm_hash_all_func libspdm_spdm_measurement_hash_func(uint32_t measurement_hash_algo)
160 : {
161 214 : switch (measurement_hash_algo) {
162 0 : case SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_256:
163 : #if LIBSPDM_SHA256_SUPPORT
164 0 : return libspdm_sha256_hash_all;
165 : #else
166 : LIBSPDM_ASSERT(false);
167 : break;
168 : #endif
169 214 : case SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_384:
170 : #if LIBSPDM_SHA384_SUPPORT
171 214 : return libspdm_sha384_hash_all;
172 : #else
173 : LIBSPDM_ASSERT(false);
174 : break;
175 : #endif
176 0 : case SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_512:
177 : #if LIBSPDM_SHA512_SUPPORT
178 0 : return libspdm_sha512_hash_all;
179 : #else
180 : LIBSPDM_ASSERT(false);
181 : break;
182 : #endif
183 0 : case SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_256:
184 : #if LIBSPDM_SHA3_256_SUPPORT
185 0 : return libspdm_sha3_256_hash_all;
186 : #else
187 : LIBSPDM_ASSERT(false);
188 : break;
189 : #endif
190 0 : case SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_384:
191 : #if LIBSPDM_SHA3_384_SUPPORT
192 0 : return libspdm_sha3_384_hash_all;
193 : #else
194 : LIBSPDM_ASSERT(false);
195 : break;
196 : #endif
197 0 : case SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_512:
198 : #if LIBSPDM_SHA3_512_SUPPORT
199 0 : return libspdm_sha3_512_hash_all;
200 : #else
201 : LIBSPDM_ASSERT(false);
202 : break;
203 : #endif
204 0 : case SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SM3_256:
205 : #if LIBSPDM_SM3_256_SUPPORT
206 : return libspdm_sm3_256_hash_all;
207 : #else
208 0 : LIBSPDM_ASSERT(false);
209 0 : break;
210 : #endif
211 0 : default:
212 0 : LIBSPDM_ASSERT(false);
213 0 : break;
214 : }
215 :
216 0 : return NULL;
217 : }
218 :
219 214 : bool libspdm_measurement_hash_all(uint32_t measurement_hash_algo,
220 : const void *data, size_t data_size,
221 : uint8_t *hash_value)
222 : {
223 : libspdm_hash_all_func hash_function;
224 214 : hash_function = libspdm_spdm_measurement_hash_func(measurement_hash_algo);
225 214 : if (hash_function == NULL) {
226 0 : return false;
227 : }
228 214 : return hash_function(data, data_size, hash_value);
229 : }
230 :
231 6 : size_t libspdm_get_aysm_nid(uint32_t base_asym_algo)
232 : {
233 6 : switch (base_asym_algo)
234 : {
235 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
236 0 : return LIBSPDM_CRYPTO_NID_RSASSA2048;
237 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
238 0 : return LIBSPDM_CRYPTO_NID_RSASSA3072;
239 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
240 0 : return LIBSPDM_CRYPTO_NID_RSASSA4096;
241 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
242 0 : return LIBSPDM_CRYPTO_NID_RSAPSS2048;
243 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
244 0 : return LIBSPDM_CRYPTO_NID_RSAPSS3072;
245 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
246 0 : return LIBSPDM_CRYPTO_NID_RSAPSS4096;
247 6 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
248 6 : return LIBSPDM_CRYPTO_NID_ECDSA_NIST_P256;
249 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
250 0 : return LIBSPDM_CRYPTO_NID_ECDSA_NIST_P384;
251 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
252 0 : return LIBSPDM_CRYPTO_NID_ECDSA_NIST_P521;
253 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
254 0 : return LIBSPDM_CRYPTO_NID_EDDSA_ED25519;
255 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
256 0 : return LIBSPDM_CRYPTO_NID_EDDSA_ED448;
257 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
258 0 : return LIBSPDM_CRYPTO_NID_SM2_DSA_P256;
259 0 : default:
260 0 : return LIBSPDM_CRYPTO_NID_NULL;
261 : }
262 : }
|