Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2024 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 : /** @file
8 : * RSA Asymmetric Cipher Wrapper Implementation.
9 : *
10 : * This file implements following APIs which provide basic capabilities for RSA:
11 : * 1) libspdm_rsa_new
12 : * 2) libspdm_rsa_free
13 : * 3) libspdm_rsa_set_key
14 : * 4) rsa_pkcs1_verify
15 : *
16 : * RFC 8017 - PKCS #1: RSA Cryptography Specifications version 2.2
17 : **/
18 :
19 : #include "internal_crypt_lib.h"
20 :
21 : #include <mbedtls/rsa.h>
22 :
23 : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
24 : /**
25 : * Allocates and initializes one RSA context for subsequent use.
26 : *
27 : * @return Pointer to the RSA context that has been initialized.
28 : * If the allocations fails, libspdm_rsa_new() returns NULL.
29 : *
30 : **/
31 140 : void *libspdm_rsa_new(void)
32 : {
33 : void *rsa_context;
34 :
35 140 : rsa_context = allocate_zero_pool(sizeof(mbedtls_rsa_context));
36 140 : if (rsa_context == NULL) {
37 0 : return rsa_context;
38 : }
39 :
40 140 : mbedtls_rsa_init(rsa_context);
41 :
42 140 : return rsa_context;
43 : }
44 :
45 : /**
46 : * Release the specified RSA context.
47 : *
48 : * @param[in] rsa_context Pointer to the RSA context to be released.
49 : *
50 : **/
51 104 : void libspdm_rsa_free(void *rsa_context)
52 : {
53 104 : mbedtls_rsa_free(rsa_context);
54 104 : free_pool(rsa_context);
55 104 : }
56 :
57 : /**
58 : * Sets the tag-designated key component into the established RSA context.
59 : *
60 : * This function sets the tag-designated RSA key component into the established
61 : * RSA context from the user-specified non-negative integer (octet string format
62 : * represented in RSA PKCS#1).
63 : * If big_number is NULL, then the specified key component in RSA context is cleared.
64 : *
65 : * If rsa_context is NULL, then return false.
66 : *
67 : * @param[in, out] rsa_context Pointer to RSA context being set.
68 : * @param[in] key_tag tag of RSA key component being set.
69 : * @param[in] big_number Pointer to octet integer buffer.
70 : * If NULL, then the specified key component in RSA
71 : * context is cleared.
72 : * @param[in] bn_size size of big number buffer in bytes.
73 : * If big_number is NULL, then it is ignored.
74 : *
75 : * @retval true RSA key component was set successfully.
76 : * @retval false Invalid RSA key component tag.
77 : *
78 : **/
79 6 : bool libspdm_rsa_set_key(void *rsa_context, const libspdm_rsa_key_tag_t key_tag,
80 : const uint8_t *big_number, size_t bn_size)
81 : {
82 : mbedtls_rsa_context *rsa_key;
83 : int ret;
84 : mbedtls_mpi value;
85 :
86 :
87 : /* Check input parameters.*/
88 :
89 6 : if (rsa_context == NULL || bn_size > INT_MAX) {
90 0 : return false;
91 : }
92 :
93 6 : mbedtls_mpi_init(&value);
94 :
95 6 : rsa_key = (mbedtls_rsa_context *)rsa_context;
96 :
97 : /* if big_number is Null clear*/
98 6 : if (big_number) {
99 6 : ret = mbedtls_mpi_read_binary(&value, big_number, bn_size);
100 6 : if (ret != 0) {
101 0 : mbedtls_mpi_free(&value);
102 0 : return false;
103 : }
104 : }
105 :
106 6 : switch (key_tag) {
107 2 : case LIBSPDM_RSA_KEY_N:
108 2 : ret = mbedtls_rsa_import(rsa_key, &value, NULL, NULL, NULL,
109 : NULL);
110 2 : break;
111 2 : case LIBSPDM_RSA_KEY_E:
112 2 : ret = mbedtls_rsa_import(rsa_key, NULL, NULL, NULL, NULL,
113 : &value);
114 2 : break;
115 2 : case LIBSPDM_RSA_KEY_D:
116 2 : ret = mbedtls_rsa_import(rsa_key, NULL, NULL, NULL, &value,
117 : NULL);
118 2 : break;
119 0 : case LIBSPDM_RSA_KEY_Q:
120 0 : ret = mbedtls_rsa_import(rsa_key, NULL, NULL, &value, NULL,
121 : NULL);
122 0 : break;
123 0 : case LIBSPDM_RSA_KEY_P:
124 0 : ret = mbedtls_rsa_import(rsa_key, NULL, &value, NULL, NULL,
125 : NULL);
126 0 : break;
127 0 : case LIBSPDM_RSA_KEY_DP:
128 : case LIBSPDM_RSA_KEY_DQ:
129 : case LIBSPDM_RSA_KEY_Q_INV:
130 : default:
131 0 : ret = -1;
132 0 : break;
133 : }
134 :
135 6 : mbedtls_mpi_free(&value);
136 6 : return ret == 0;
137 : }
138 : #endif /* (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT) */
139 :
140 : #if LIBSPDM_RSA_SSA_SUPPORT
141 : /**
142 : * Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in
143 : * RSA PKCS#1.
144 : *
145 : * If rsa_context is NULL, then return false.
146 : * If message_hash is NULL, then return false.
147 : * If signature is NULL, then return false.
148 : * If hash_size need match the hash_nid. hash_nid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384, SHA3_512.
149 : *
150 : * @param[in] rsa_context Pointer to RSA context for signature verification.
151 : * @param[in] hash_nid hash NID
152 : * @param[in] message_hash Pointer to octet message hash to be checked.
153 : * @param[in] hash_size size of the message hash in bytes.
154 : * @param[in] signature Pointer to RSA PKCS1-v1_5 signature to be verified.
155 : * @param[in] sig_size size of signature in bytes.
156 : *
157 : * @retval true Valid signature encoded in PKCS1-v1_5.
158 : * @retval false Invalid signature or invalid RSA context.
159 : *
160 : **/
161 31 : bool libspdm_rsa_pkcs1_verify_with_nid(void *rsa_context, size_t hash_nid,
162 : const uint8_t *message_hash,
163 : size_t hash_size, const uint8_t *signature,
164 : size_t sig_size)
165 : {
166 : int ret;
167 : mbedtls_md_type_t md_alg;
168 : mbedtls_rsa_context *rsa_key;
169 :
170 31 : if (rsa_context == NULL || message_hash == NULL || signature == NULL) {
171 0 : return false;
172 : }
173 :
174 31 : if (sig_size > INT_MAX || sig_size == 0) {
175 0 : return false;
176 : }
177 :
178 31 : rsa_key = (mbedtls_rsa_context *)rsa_context;
179 31 : if (mbedtls_rsa_complete(rsa_key) != 0) {
180 0 : return false;
181 : }
182 :
183 31 : switch (hash_nid) {
184 31 : case LIBSPDM_CRYPTO_NID_SHA256:
185 31 : md_alg = MBEDTLS_MD_SHA256;
186 31 : if (hash_size != LIBSPDM_SHA256_DIGEST_SIZE) {
187 0 : return false;
188 : }
189 31 : break;
190 :
191 0 : case LIBSPDM_CRYPTO_NID_SHA384:
192 0 : md_alg = MBEDTLS_MD_SHA384;
193 0 : if (hash_size != LIBSPDM_SHA384_DIGEST_SIZE) {
194 0 : return false;
195 : }
196 0 : break;
197 :
198 0 : case LIBSPDM_CRYPTO_NID_SHA512:
199 0 : md_alg = MBEDTLS_MD_SHA512;
200 0 : if (hash_size != LIBSPDM_SHA512_DIGEST_SIZE) {
201 0 : return false;
202 : }
203 0 : break;
204 :
205 0 : case LIBSPDM_CRYPTO_NID_SHA3_256:
206 0 : md_alg = MBEDTLS_MD_SHA3_256;
207 0 : if (hash_size != LIBSPDM_SHA3_256_DIGEST_SIZE) {
208 0 : return false;
209 : }
210 0 : break;
211 :
212 0 : case LIBSPDM_CRYPTO_NID_SHA3_384:
213 0 : md_alg = MBEDTLS_MD_SHA3_384;
214 0 : if (hash_size != LIBSPDM_SHA3_384_DIGEST_SIZE) {
215 0 : return false;
216 : }
217 0 : break;
218 :
219 0 : case LIBSPDM_CRYPTO_NID_SHA3_512:
220 0 : md_alg = MBEDTLS_MD_SHA3_512;
221 0 : if (hash_size != LIBSPDM_SHA3_512_DIGEST_SIZE) {
222 0 : return false;
223 : }
224 0 : break;
225 :
226 0 : default:
227 0 : return false;
228 : }
229 :
230 31 : if (mbedtls_rsa_get_len(rsa_context) != sig_size) {
231 0 : return false;
232 : }
233 :
234 31 : mbedtls_rsa_set_padding(rsa_context, MBEDTLS_RSA_PKCS_V15, md_alg);
235 :
236 31 : ret = mbedtls_rsa_pkcs1_verify(rsa_context, md_alg,
237 : (uint32_t)hash_size, message_hash,
238 : signature);
239 31 : if (ret != 0) {
240 8 : return false;
241 : }
242 23 : return true;
243 : }
244 : #endif /* LIBSPDM_RSA_SSA_SUPPORT */
245 :
246 : #if LIBSPDM_RSA_PSS_SUPPORT
247 : /**
248 : * Verifies the RSA-SSA signature with EMSA-PSS encoding scheme defined in
249 : * RSA PKCS#1 v2.2.
250 : *
251 : * The salt length is same as digest length.
252 : *
253 : * If rsa_context is NULL, then return false.
254 : * If message_hash is NULL, then return false.
255 : * If signature is NULL, then return false.
256 : * If hash_size need match the hash_nid. nid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384, SHA3_512.
257 : *
258 : * @param[in] rsa_context Pointer to RSA context for signature verification.
259 : * @param[in] hash_nid hash NID
260 : * @param[in] message_hash Pointer to octet message hash to be checked.
261 : * @param[in] hash_size size of the message hash in bytes.
262 : * @param[in] signature Pointer to RSA-SSA PSS signature to be verified.
263 : * @param[in] sig_size size of signature in bytes.
264 : *
265 : * @retval true Valid signature encoded in RSA-SSA PSS.
266 : * @retval false Invalid signature or invalid RSA context.
267 : *
268 : **/
269 0 : bool libspdm_rsa_pss_verify(void *rsa_context, size_t hash_nid,
270 : const uint8_t *message_hash, size_t hash_size,
271 : const uint8_t *signature, size_t sig_size)
272 : {
273 : int ret;
274 : mbedtls_md_type_t md_alg;
275 : mbedtls_rsa_context *rsa_key;
276 :
277 0 : if (rsa_context == NULL || message_hash == NULL || signature == NULL) {
278 0 : return false;
279 : }
280 :
281 0 : if (sig_size > INT_MAX || sig_size == 0) {
282 0 : return false;
283 : }
284 :
285 0 : rsa_key = (mbedtls_rsa_context *)rsa_context;
286 0 : if (mbedtls_rsa_complete(rsa_key) != 0) {
287 0 : return false;
288 : }
289 :
290 0 : switch (hash_nid) {
291 0 : case LIBSPDM_CRYPTO_NID_SHA256:
292 0 : md_alg = MBEDTLS_MD_SHA256;
293 0 : if (hash_size != LIBSPDM_SHA256_DIGEST_SIZE) {
294 0 : return false;
295 : }
296 0 : break;
297 :
298 0 : case LIBSPDM_CRYPTO_NID_SHA384:
299 0 : md_alg = MBEDTLS_MD_SHA384;
300 0 : if (hash_size != LIBSPDM_SHA384_DIGEST_SIZE) {
301 0 : return false;
302 : }
303 0 : break;
304 :
305 0 : case LIBSPDM_CRYPTO_NID_SHA512:
306 0 : md_alg = MBEDTLS_MD_SHA512;
307 0 : if (hash_size != LIBSPDM_SHA512_DIGEST_SIZE) {
308 0 : return false;
309 : }
310 0 : break;
311 :
312 0 : case LIBSPDM_CRYPTO_NID_SHA3_256:
313 0 : md_alg = MBEDTLS_MD_SHA3_256;
314 0 : if (hash_size != LIBSPDM_SHA3_256_DIGEST_SIZE) {
315 0 : return false;
316 : }
317 0 : break;
318 :
319 0 : case LIBSPDM_CRYPTO_NID_SHA3_384:
320 0 : md_alg = MBEDTLS_MD_SHA3_384;
321 0 : if (hash_size != LIBSPDM_SHA3_384_DIGEST_SIZE) {
322 0 : return false;
323 : }
324 0 : break;
325 :
326 0 : case LIBSPDM_CRYPTO_NID_SHA3_512:
327 0 : md_alg = MBEDTLS_MD_SHA3_512;
328 0 : if (hash_size != LIBSPDM_SHA3_512_DIGEST_SIZE) {
329 0 : return false;
330 : }
331 0 : break;
332 :
333 0 : default:
334 0 : return false;
335 : }
336 :
337 0 : if (mbedtls_rsa_get_len(rsa_context) != sig_size) {
338 0 : return false;
339 : }
340 :
341 0 : mbedtls_rsa_set_padding(rsa_context, MBEDTLS_RSA_PKCS_V21, md_alg);
342 :
343 0 : ret = mbedtls_rsa_rsassa_pss_verify(rsa_context, md_alg,
344 : (uint32_t)hash_size, message_hash,
345 : signature);
346 0 : if (ret != 0) {
347 0 : return false;
348 : }
349 0 : return true;
350 : }
351 :
352 : #if LIBSPDM_FIPS_MODE
353 : /**
354 : * Verifies the RSA-SSA signature with EMSA-PSS encoding scheme defined in
355 : * RSA PKCS#1 v2.2 for FIPS test.
356 : *
357 : * The salt length is zero.
358 : *
359 : * If rsa_context is NULL, then return false.
360 : * If message_hash is NULL, then return false.
361 : * If signature is NULL, then return false.
362 : * If hash_size need match the hash_nid. nid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384, SHA3_512.
363 : *
364 : * @param[in] rsa_context Pointer to RSA context for signature verification.
365 : * @param[in] hash_nid hash NID
366 : * @param[in] message_hash Pointer to octet message hash to be checked.
367 : * @param[in] hash_size size of the message hash in bytes.
368 : * @param[in] signature Pointer to RSA-SSA PSS signature to be verified.
369 : * @param[in] sig_size size of signature in bytes.
370 : *
371 : * @retval true Valid signature encoded in RSA-SSA PSS.
372 : * @retval false Invalid signature or invalid RSA context.
373 : *
374 : **/
375 1 : bool libspdm_rsa_pss_verify_fips(void *rsa_context, size_t hash_nid,
376 : const uint8_t *message_hash, size_t hash_size,
377 : const uint8_t *signature, size_t sig_size)
378 : {
379 : int ret;
380 : mbedtls_md_type_t md_alg;
381 : mbedtls_rsa_context *rsa_key;
382 : mbedtls_md_type_t mgf1_hash_id;
383 :
384 1 : if (rsa_context == NULL || message_hash == NULL || signature == NULL) {
385 0 : return false;
386 : }
387 :
388 1 : if (sig_size > INT_MAX || sig_size == 0) {
389 0 : return false;
390 : }
391 :
392 1 : rsa_key = (mbedtls_rsa_context *)rsa_context;
393 1 : if (mbedtls_rsa_complete(rsa_key) != 0) {
394 0 : return false;
395 : }
396 :
397 1 : switch (hash_nid) {
398 1 : case LIBSPDM_CRYPTO_NID_SHA256:
399 1 : md_alg = MBEDTLS_MD_SHA256;
400 1 : if (hash_size != LIBSPDM_SHA256_DIGEST_SIZE) {
401 0 : return false;
402 : }
403 1 : break;
404 :
405 0 : case LIBSPDM_CRYPTO_NID_SHA384:
406 0 : md_alg = MBEDTLS_MD_SHA384;
407 0 : if (hash_size != LIBSPDM_SHA384_DIGEST_SIZE) {
408 0 : return false;
409 : }
410 0 : break;
411 :
412 0 : case LIBSPDM_CRYPTO_NID_SHA512:
413 0 : md_alg = MBEDTLS_MD_SHA512;
414 0 : if (hash_size != LIBSPDM_SHA512_DIGEST_SIZE) {
415 0 : return false;
416 : }
417 0 : break;
418 :
419 0 : case LIBSPDM_CRYPTO_NID_SHA3_256:
420 0 : md_alg = MBEDTLS_MD_SHA3_256;
421 0 : if (hash_size != LIBSPDM_SHA3_256_DIGEST_SIZE) {
422 0 : return false;
423 : }
424 0 : break;
425 :
426 0 : case LIBSPDM_CRYPTO_NID_SHA3_384:
427 0 : md_alg = MBEDTLS_MD_SHA3_384;
428 0 : if (hash_size != LIBSPDM_SHA3_384_DIGEST_SIZE) {
429 0 : return false;
430 : }
431 0 : break;
432 :
433 0 : case LIBSPDM_CRYPTO_NID_SHA3_512:
434 0 : md_alg = MBEDTLS_MD_SHA3_512;
435 0 : if (hash_size != LIBSPDM_SHA3_512_DIGEST_SIZE) {
436 0 : return false;
437 : }
438 0 : break;
439 :
440 0 : default:
441 0 : return false;
442 : }
443 :
444 1 : if (mbedtls_rsa_get_len(rsa_context) != sig_size) {
445 0 : return false;
446 : }
447 :
448 1 : mbedtls_rsa_set_padding(rsa_context, MBEDTLS_RSA_PKCS_V21, md_alg);
449 :
450 2 : mgf1_hash_id = (rsa_key->MBEDTLS_PRIVATE(hash_id) != MBEDTLS_MD_NONE) ?
451 1 : (mbedtls_md_type_t) rsa_key->MBEDTLS_PRIVATE(hash_id) : md_alg;
452 :
453 : /*salt len is 0*/
454 1 : ret = mbedtls_rsa_rsassa_pss_verify_ext(rsa_context, md_alg,
455 : (uint32_t)hash_size, message_hash,
456 : mgf1_hash_id,
457 : 0,
458 : signature);
459 1 : if (ret != 0) {
460 0 : return false;
461 : }
462 1 : return true;
463 : }
464 : #endif /*LIBSPDM_FIPS_MODE*/
465 :
466 : #endif /* LIBSPDM_RSA_PSS_SUPPORT */
|