LCOV - code coverage report
Current view: top level - os_stub/cryptlib_mbedtls/pk - rsa_basic.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 32.6 % 187 61
Test Date: 2025-06-29 08:09:00 Functions: 83.3 % 6 5

            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 */
        

Generated by: LCOV version 2.0-1