LCOV - code coverage report
Current view: top level - spdm_crypt_lib - libspdm_crypt_cert.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 60.9 % 731 445
Test Date: 2026-10-01 20:56:25 Functions: 88.0 % 25 22
Branches: 54.0 % 439 237

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  *  Copyright Notice:
       3                 :             :  *  Copyright 2021-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                 :             : 
       9                 :             : #if LIBSPDM_CERT_PARSE_SUPPORT
      10                 :             : 
      11                 :             : /**pathLenConstraint is optional.
      12                 :             :  * In https://www.pkisolutions.com/basic-constraints-certificate-extension/:
      13                 :             :  * pathLenConstraint: How many CAs are allowed in the chain below current CA certificate.
      14                 :             :  * This setting has no meaning for end entity certificates.
      15                 :             :  **/
      16                 :             : 
      17                 :             : /**
      18                 :             :  * leaf cert spdm extension len
      19                 :             :  * len > 2 * (spdm id-DMTF-spdm size + 2)
      20                 :             :  **/
      21                 :             : 
      22                 :             : #ifndef LIBSPDM_MAX_EXTENSION_LEN
      23                 :             : #define LIBSPDM_MAX_EXTENSION_LEN 30
      24                 :             : #endif
      25                 :             : 
      26                 :             : #ifndef LIBSPDM_MAX_NAME_SIZE
      27                 :             : #define LIBSPDM_MAX_NAME_SIZE 100
      28                 :             : #endif
      29                 :             : 
      30                 :             : /*max public key encryption algo oid len*/
      31                 :             : #ifndef LIBSPDM_MAX_ENCRYPTION_ALGO_OID_LEN
      32                 :             : #define LIBSPDM_MAX_ENCRYPTION_ALGO_OID_LEN 10
      33                 :             : #endif
      34                 :             : 
      35                 :             : /* Maximum size of basicConstraints. This includes space for both cA and pathLen. */
      36                 :             : #ifndef LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN
      37                 :             : #define LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN 10
      38                 :             : #endif
      39                 :             : 
      40                 :             : /**
      41                 :             :  * 0x02 is integer;
      42                 :             :  * 0x82 indicates that the length is expressed in two bytes;
      43                 :             :  * 0x01 and 0x01 are rsa key len;
      44                 :             :  **/
      45                 :             : #if (LIBSPDM_RSA_SSA_2048_SUPPORT) || (LIBSPDM_RSA_PSS_2048_SUPPORT)
      46                 :             : #define KEY_ENCRY_ALGO_RSA2048_FLAG {0x02, 0x82, 0x01, 0x01}
      47                 :             : /* the other case is ASN1 code different when integer is 1 on highest position*/
      48                 :             : #define KEY_ENCRY_ALGO_RSA2048_FLAG_OTHER {0x02, 0x82, 0x01, 0x00}
      49                 :             : #endif
      50                 :             : #if (LIBSPDM_RSA_SSA_3072_SUPPORT) || (LIBSPDM_RSA_PSS_3072_SUPPORT)
      51                 :             : #define KEY_ENCRY_ALGO_RSA3072_FLAG {0x02, 0x82, 0x01, 0x81}
      52                 :             : /* the other case is ASN1 code different when integer is 1 on highest position*/
      53                 :             : #define KEY_ENCRY_ALGO_RSA3072_FLAG_OTHER {0x02, 0x82, 0x01, 0x80}
      54                 :             : #endif
      55                 :             : #if (LIBSPDM_RSA_SSA_4096_SUPPORT) || (LIBSPDM_RSA_PSS_4096_SUPPORT)
      56                 :             : #define KEY_ENCRY_ALGO_RSA4096_FLAG {0x02, 0x82, 0x02, 0x01}
      57                 :             : /* the other case is ASN1 code different when integer is 1 on highest position*/
      58                 :             : #define KEY_ENCRY_ALGO_RSA4096_FLAG_OTHER {0x02, 0x82, 0x02, 0x00}
      59                 :             : #endif
      60                 :             : 
      61                 :             : /**
      62                 :             :  * https://oidref.com/1.2.840.10045.3.1.7
      63                 :             :  * ECC256 curve OID: 1.2.840.10045.3.1.7
      64                 :             :  * https://oidref.com/1.3.132.0.34
      65                 :             :  * ECC384 curve OID: 1.3.132.0.34
      66                 :             :  * https://oidref.com/1.3.132.0.35
      67                 :             :  * ECC521 curve OID: 1.3.132.0.35
      68                 :             :  **/
      69                 :             : #if LIBSPDM_ECDSA_P256_SUPPORT
      70                 :             : #define KEY_ENCRY_ALGO_ECC256_OID {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}
      71                 :             : #endif
      72                 :             : #if LIBSPDM_ECDSA_P384_SUPPORT
      73                 :             : #define KEY_ENCRY_ALGO_ECC384_OID {0x2B, 0x81, 0x04, 0x00, 0x22}
      74                 :             : #endif
      75                 :             : #if LIBSPDM_ECDSA_P521_SUPPORT
      76                 :             : #define KEY_ENCRY_ALGO_ECC521_OID {0x2B, 0x81, 0x04, 0x00, 0x23}
      77                 :             : #endif
      78                 :             : 
      79                 :             : /**
      80                 :             :  * EDxxx OID: https://datatracker.ietf.org/doc/html/rfc8420
      81                 :             :  * ED448 OID: 1.3.101.113
      82                 :             :  * ED25519 OID: 1.3.101.112
      83                 :             :  **/
      84                 :             : #if LIBSPDM_EDDSA_ED25519_SUPPORT
      85                 :             : #define ENCRY_ALGO_ED25519_OID {0x2B, 0x65, 0x70}
      86                 :             : #endif
      87                 :             : #if LIBSPDM_EDDSA_ED448_SUPPORT
      88                 :             : #define ENCRY_ALGO_ED448_OID {0x2B, 0x65, 0x71}
      89                 :             : #endif
      90                 :             : 
      91                 :             : /**
      92                 :             :  * MLDSA OID: RFC9881
      93                 :             :  * MLDSA44 OID: 2.16.840.1.101.3.4.3.17
      94                 :             :  * MLDSA65 OID: 2.16.840.1.101.3.4.3.18
      95                 :             :  * MLDSA87 OID: 2.16.840.1.101.3.4.3.19
      96                 :             :  **/
      97                 :             : #if LIBSPDM_ML_DSA_44_SUPPORT
      98                 :             : #define ALGO_MLDSA44_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x11}
      99                 :             : #endif
     100                 :             : #if LIBSPDM_ML_DSA_65_SUPPORT
     101                 :             : #define ALGO_MLDSA65_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x12}
     102                 :             : #endif
     103                 :             : #if LIBSPDM_ML_DSA_87_SUPPORT
     104                 :             : #define ALGO_MLDSA87_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x13}
     105                 :             : #endif
     106                 :             : 
     107                 :             : /**
     108                 :             :  * SLHDSA OID: RFC9909
     109                 :             :  * SLHDSA_SHA2_128S OID: 2.16.840.1.101.3.4.3.20
     110                 :             :  * SLHDSA_SHA2_128F OID: 2.16.840.1.101.3.4.3.21
     111                 :             :  * SLHDSA_SHA2_192S OID: 2.16.840.1.101.3.4.3.22
     112                 :             :  * SLHDSA_SHA2_192F OID: 2.16.840.1.101.3.4.3.23
     113                 :             :  * SLHDSA_SHA2_256S OID: 2.16.840.1.101.3.4.3.24
     114                 :             :  * SLHDSA_SHA2_256F OID: 2.16.840.1.101.3.4.3.25
     115                 :             :  * SLHDSA_SHAKE_128S OID: 2.16.840.1.101.3.4.3.26
     116                 :             :  * SLHDSA_SHAKE_128F OID: 2.16.840.1.101.3.4.3.27
     117                 :             :  * SLHDSA_SHAKE_192S OID: 2.16.840.1.101.3.4.3.28
     118                 :             :  * SLHDSA_SHAKE_192F OID: 2.16.840.1.101.3.4.3.29
     119                 :             :  * SLHDSA_SHAKE_256S OID: 2.16.840.1.101.3.4.3.30
     120                 :             :  * SLHDSA_SHAKE_256F OID: 2.16.840.1.101.3.4.3.31
     121                 :             :  **/
     122                 :             : #if LIBSPDM_SLH_DSA_SHA2_128S_SUPPORT
     123                 :             : #define ALGO_SLHDSA_SHA2_128S_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x14}
     124                 :             : #endif
     125                 :             : #if LIBSPDM_SLH_DSA_SHA2_128F_SUPPORT
     126                 :             : #define ALGO_SLHDSA_SHA2_128F_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x15}
     127                 :             : #endif
     128                 :             : #if LIBSPDM_SLH_DSA_SHA2_192S_SUPPORT
     129                 :             : #define ALGO_SLHDSA_SHA2_192S_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x16}
     130                 :             : #endif
     131                 :             : #if LIBSPDM_SLH_DSA_SHA2_192F_SUPPORT
     132                 :             : #define ALGO_SLHDSA_SHA2_192F_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x17}
     133                 :             : #endif
     134                 :             : #if LIBSPDM_SLH_DSA_SHA2_256S_SUPPORT
     135                 :             : #define ALGO_SLHDSA_SHA2_256S_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x18}
     136                 :             : #endif
     137                 :             : #if LIBSPDM_SLH_DSA_SHA2_256F_SUPPORT
     138                 :             : #define ALGO_SLHDSA_SHA2_256F_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x19}
     139                 :             : #endif
     140                 :             : #if LIBSPDM_SLH_DSA_SHAKE_128S_SUPPORT
     141                 :             : #define ALGO_SLHDSA_SHAKE_128S_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x1A}
     142                 :             : #endif
     143                 :             : #if LIBSPDM_SLH_DSA_SHAKE_128F_SUPPORT
     144                 :             : #define ALGO_SLHDSA_SHAKE_128F_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x1B}
     145                 :             : #endif
     146                 :             : #if LIBSPDM_SLH_DSA_SHAKE_192S_SUPPORT
     147                 :             : #define ALGO_SLHDSA_SHAKE_192S_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x1C}
     148                 :             : #endif
     149                 :             : #if LIBSPDM_SLH_DSA_SHAKE_192F_SUPPORT
     150                 :             : #define ALGO_SLHDSA_SHAKE_192F_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x1D}
     151                 :             : #endif
     152                 :             : #if LIBSPDM_SLH_DSA_SHAKE_256S_SUPPORT
     153                 :             : #define ALGO_SLHDSA_SHAKE_256S_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x1E}
     154                 :             : #endif
     155                 :             : #if LIBSPDM_SLH_DSA_SHAKE_256F_SUPPORT
     156                 :             : #define ALGO_SLHDSA_SHAKE_256F_OID {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x1F}
     157                 :             : #endif
     158                 :             : 
     159                 :             : /* Leaf certificate basic constraints with cA field set to false. According to RFC5280, false is the
     160                 :             :  * default value, and according to DER encoding a sequence item with a default value must not be
     161                 :             :  * encoded. */
     162                 :             : #define BASIC_CONSTRAINTS_CA_FALSE {0x30, 0x00}
     163                 :             : 
     164                 :             : /* Leaf certificate basic constraints with cA field set to true. */
     165                 :             : #define BASIC_CONSTRAINTS_CA_TRUE {0x30, 0x03, 0x01, 0x01, 0xFF}
     166                 :             : 
     167                 :             : /**
     168                 :             :  * Retrieve the asymmetric public key from one DER-encoded X509 certificate.
     169                 :             :  *
     170                 :             :  * @param  cert       Pointer to the DER-encoded X509 certificate.
     171                 :             :  * @param  cert_size  Size of the X509 certificate in bytes.
     172                 :             :  * @param  context    Pointer to newly generated asymmetric context which contain the retrieved public
     173                 :             :  *                    key component. Use libspdm_asym_free() function to free the resource.
     174                 :             :  *
     175                 :             :  * @retval  true   public key was retrieved successfully.
     176                 :             :  * @retval  false  Fail to retrieve public key from X509 certificate.
     177                 :             :  **/
     178                 :             : typedef bool (*libspdm_asym_get_public_key_from_x509_func)(const uint8_t *cert,
     179                 :             :                                                            size_t cert_size,
     180                 :             :                                                            void **context);
     181                 :             : 
     182                 :             : /**
     183                 :             :  * Return asymmetric GET_PUBLIC_KEY_FROM_X509 function, based upon the negotiated asymmetric algorithm.
     184                 :             :  *
     185                 :             :  * @param  base_asym_algo                 SPDM base_asym_algo
     186                 :             :  *
     187                 :             :  * @return asymmetric GET_PUBLIC_KEY_FROM_X509 function
     188                 :             :  **/
     189                 :             : static libspdm_asym_get_public_key_from_x509_func
     190                 :        1206 : libspdm_get_asym_get_public_key_from_x509(uint32_t base_asym_algo)
     191                 :             : {
     192   [ +  +  -  -  :        1206 :     switch (base_asym_algo) {
                      - ]
     193                 :         119 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     194                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     195                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     196                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     197                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     198                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     199                 :             : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
     200                 :             : #if !LIBSPDM_RSA_SSA_2048_SUPPORT
     201                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048);
     202                 :             : #endif
     203                 :             : #if !LIBSPDM_RSA_SSA_3072_SUPPORT
     204                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072);
     205                 :             : #endif
     206                 :             : #if !LIBSPDM_RSA_SSA_4096_SUPPORT
     207                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096);
     208                 :             : #endif
     209                 :             : #if !LIBSPDM_RSA_PSS_2048_SUPPORT
     210                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048);
     211                 :             : #endif
     212                 :             : #if !LIBSPDM_RSA_PSS_3072_SUPPORT
     213                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072);
     214                 :             : #endif
     215                 :             : #if !LIBSPDM_RSA_PSS_4096_SUPPORT
     216                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096);
     217                 :             : #endif
     218                 :         119 :         return libspdm_rsa_get_public_key_from_x509;
     219                 :             : #else
     220                 :             :         LIBSPDM_ASSERT(false);
     221                 :             :         break;
     222                 :             : #endif
     223                 :        1087 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     224                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     225                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     226                 :             : #if LIBSPDM_ECDSA_SUPPORT
     227                 :             : #if !LIBSPDM_ECDSA_P256_SUPPORT
     228                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256);
     229                 :             : #endif
     230                 :             : #if !LIBSPDM_ECDSA_P384_SUPPORT
     231                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384);
     232                 :             : #endif
     233                 :             : #if !LIBSPDM_ECDSA_P521_SUPPORT
     234                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521);
     235                 :             : #endif
     236                 :        1087 :         return libspdm_ec_get_public_key_from_x509;
     237                 :             : #else
     238                 :             :         LIBSPDM_ASSERT(false);
     239                 :             :         break;
     240                 :             : #endif
     241                 :           0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     242                 :             :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     243                 :             : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     244                 :             : #if !LIBSPDM_EDDSA_ED25519_SUPPORT
     245                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519);
     246                 :             : #endif
     247                 :             : #if !LIBSPDM_EDDSA_ED448_SUPPORT
     248                 :             :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448);
     249                 :             : #endif
     250                 :             :         return libspdm_ecd_get_public_key_from_x509;
     251                 :             : #else
     252                 :           0 :         LIBSPDM_ASSERT(false);
     253                 :           0 :         break;
     254                 :             : #endif
     255                 :           0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     256                 :             : #if LIBSPDM_SM2_DSA_SUPPORT
     257                 :             :         return libspdm_sm2_get_public_key_from_x509;
     258                 :             : #else
     259                 :           0 :         LIBSPDM_ASSERT(false);
     260                 :           0 :         break;
     261                 :             : #endif
     262                 :           0 :     default:
     263                 :           0 :         LIBSPDM_ASSERT(false);
     264                 :           0 :         break;
     265                 :             :     }
     266                 :             : 
     267                 :           0 :     return NULL;
     268                 :             : }
     269                 :             : 
     270                 :        1206 : bool libspdm_asym_get_public_key_from_x509(uint32_t base_asym_algo,
     271                 :             :                                            const uint8_t *cert,
     272                 :             :                                            size_t cert_size,
     273                 :             :                                            void **context)
     274                 :             : {
     275                 :             :     libspdm_asym_get_public_key_from_x509_func get_public_key_from_x509_function;
     276                 :        1206 :     get_public_key_from_x509_function = libspdm_get_asym_get_public_key_from_x509(base_asym_algo);
     277         [ -  + ]:        1206 :     if (get_public_key_from_x509_function == NULL) {
     278                 :           0 :         return false;
     279                 :             :     }
     280                 :        1206 :     return get_public_key_from_x509_function(cert, cert_size, context);
     281                 :             : }
     282                 :             : 
     283                 :             : /**
     284                 :             :  * Return requester asymmetric GET_PUBLIC_KEY_FROM_X509 function, based upon the negotiated requester asymmetric algorithm.
     285                 :             :  *
     286                 :             :  * @param  req_base_asym_alg               SPDM req_base_asym_alg
     287                 :             :  *
     288                 :             :  * @return requester asymmetric GET_PUBLIC_KEY_FROM_X509 function
     289                 :             :  **/
     290                 :             : static libspdm_asym_get_public_key_from_x509_func
     291                 :           0 : libspdm_get_req_asym_get_public_key_from_x509(uint16_t req_base_asym_alg)
     292                 :             : {
     293                 :           0 :     return libspdm_get_asym_get_public_key_from_x509(req_base_asym_alg);
     294                 :             : }
     295                 :             : 
     296                 :           0 : bool libspdm_req_asym_get_public_key_from_x509(uint16_t req_base_asym_alg,
     297                 :             :                                                const uint8_t *cert,
     298                 :             :                                                size_t cert_size,
     299                 :             :                                                void **context)
     300                 :             : {
     301                 :             :     libspdm_asym_get_public_key_from_x509_func get_public_key_from_x509_function;
     302                 :             :     get_public_key_from_x509_function =
     303                 :           0 :         libspdm_get_req_asym_get_public_key_from_x509(req_base_asym_alg);
     304         [ #  # ]:           0 :     if (get_public_key_from_x509_function == NULL) {
     305                 :           0 :         return false;
     306                 :             :     }
     307                 :           0 :     return get_public_key_from_x509_function(cert, cert_size, context);
     308                 :             : }
     309                 :             : 
     310                 :             : /**
     311                 :             :  * Check the X509 DateTime is within a valid range.
     312                 :             :  *
     313                 :             :  * @param  from                         notBefore Pointer to date_time object.
     314                 :             :  * @param  from_size                     notBefore date_time object size.
     315                 :             :  * @param  to                           notAfter Pointer to date_time object.
     316                 :             :  * @param  to_size                       notAfter date_time object size.
     317                 :             :  *
     318                 :             :  * @retval  true   verification pass.
     319                 :             :  * @retval  false  verification fail.
     320                 :             :  **/
     321                 :         917 : static bool libspdm_internal_x509_date_time_check(const uint8_t *from,
     322                 :             :                                                   size_t from_size,
     323                 :             :                                                   const uint8_t *to,
     324                 :             :                                                   size_t to_size)
     325                 :             : {
     326                 :             :     int32_t ret;
     327                 :             :     bool status;
     328                 :             :     uint8_t f0[64];
     329                 :             :     uint8_t t0[64];
     330                 :             :     size_t f0_size;
     331                 :             :     size_t t0_size;
     332                 :             : 
     333                 :         917 :     f0_size = 64;
     334                 :         917 :     t0_size = 64;
     335                 :             : 
     336                 :         917 :     status = libspdm_x509_set_date_time("19700101000000Z", f0, &f0_size);
     337         [ -  + ]:         917 :     if (!status) {
     338                 :           0 :         return false;
     339                 :             :     }
     340                 :             : 
     341                 :         917 :     status = libspdm_x509_set_date_time("99991231235959Z", t0, &t0_size);
     342         [ -  + ]:         917 :     if (!status) {
     343                 :           0 :         return false;
     344                 :             :     }
     345                 :             : 
     346                 :             :     /* from >= f0*/
     347                 :         917 :     ret = libspdm_x509_compare_date_time(from, f0);
     348         [ -  + ]:         917 :     if (ret < 0) {
     349                 :           0 :         return false;
     350                 :             :     }
     351                 :             : 
     352                 :             :     /* to <= t0*/
     353                 :         917 :     ret = libspdm_x509_compare_date_time(t0, to);
     354         [ -  + ]:         917 :     if (ret < 0) {
     355                 :           0 :         return false;
     356                 :             :     }
     357                 :             : 
     358                 :         917 :     return true;
     359                 :             : }
     360                 :             : 
     361                 :             : /**
     362                 :             :  * This function returns the SPDM public key encryption algorithm OID len.
     363                 :             :  *
     364                 :             :  * @param[in]  base_asym_algo          SPDM base_asym_algo
     365                 :             :  * @param[in]  pqc_asym_algo           SPDM pqc_asym_algo
     366                 :             :  *
     367                 :             :  * @return SPDM public key encryption algorithms OID len.
     368                 :             :  **/
     369                 :        1826 : static uint32_t libspdm_get_public_key_algo_OID_len(
     370                 :             :     uint32_t base_asym_algo, uint32_t pqc_asym_algo)
     371                 :             : {
     372         [ +  - ]:        1826 :     if (base_asym_algo != 0) {
     373   [ +  -  +  -  :        1826 :         switch (base_asym_algo) {
          +  -  +  +  +  
                -  -  - ]
     374                 :         140 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     375                 :             :     #if LIBSPDM_RSA_SSA_2048_SUPPORT
     376                 :         140 :             return 4;
     377                 :             :     #else
     378                 :             :             return 0;
     379                 :             :     #endif
     380                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     381                 :             :     #if LIBSPDM_RSA_PSS_2048_SUPPORT
     382                 :           0 :             return 4;
     383                 :             :     #else
     384                 :             :             return 0;
     385                 :             :     #endif
     386                 :           6 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     387                 :             :     #if LIBSPDM_RSA_SSA_3072_SUPPORT
     388                 :           6 :             return 4;
     389                 :             :     #else
     390                 :             :             return 0;
     391                 :             :     #endif
     392                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     393                 :             :     #if LIBSPDM_RSA_PSS_3072_SUPPORT
     394                 :           0 :             return 4;
     395                 :             :     #else
     396                 :             :             return 0;
     397                 :             :     #endif
     398                 :           4 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     399                 :             :     #if LIBSPDM_RSA_SSA_4096_SUPPORT
     400                 :           4 :             return 4;
     401                 :             :     #else
     402                 :             :             return 0;
     403                 :             :     #endif
     404                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     405                 :             :     #if LIBSPDM_RSA_PSS_4096_SUPPORT
     406                 :           0 :             return 4;
     407                 :             :     #else
     408                 :             :             return 0;
     409                 :             :     #endif
     410                 :        1672 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     411                 :             :     #if LIBSPDM_ECDSA_P256_SUPPORT
     412                 :        1672 :             return 8;
     413                 :             :     #else
     414                 :             :             return 0;
     415                 :             :     #endif
     416                 :           2 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     417                 :             :     #if LIBSPDM_ECDSA_P384_SUPPORT
     418                 :           2 :             return 5;
     419                 :             :     #else
     420                 :             :             return 0;
     421                 :             :     #endif
     422                 :           2 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     423                 :             :     #if LIBSPDM_ECDSA_P521_SUPPORT
     424                 :           2 :             return 5;
     425                 :             :     #else
     426                 :             :             return 0;
     427                 :             :     #endif
     428                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     429                 :             :     #if LIBSPDM_EDDSA_ED25519_SUPPORT
     430                 :             :             return 3;
     431                 :             :     #else
     432                 :           0 :             return 0;
     433                 :             :     #endif
     434                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     435                 :             :     #if LIBSPDM_EDDSA_ED448_SUPPORT
     436                 :             :             return 3;
     437                 :             :     #else
     438                 :           0 :             return 0;
     439                 :             :     #endif
     440                 :           0 :         default:
     441                 :           0 :             LIBSPDM_ASSERT(false);
     442                 :           0 :             return 0;
     443                 :             :         }
     444                 :             :     }
     445         [ #  # ]:           0 :     if (pqc_asym_algo != 0) {
     446   [ #  #  #  #  :           0 :         switch (pqc_asym_algo) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     447                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_44:
     448                 :             :     #if LIBSPDM_ML_DSA_44_SUPPORT
     449                 :             :             return 9;
     450                 :             :     #else
     451                 :           0 :             return 0;
     452                 :             :     #endif
     453                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_65:
     454                 :             :     #if LIBSPDM_ML_DSA_65_SUPPORT
     455                 :             :             return 9;
     456                 :             :     #else
     457                 :           0 :             return 0;
     458                 :             :     #endif
     459                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_87:
     460                 :             :     #if LIBSPDM_ML_DSA_87_SUPPORT
     461                 :             :             return 9;
     462                 :             :     #else
     463                 :           0 :             return 0;
     464                 :             :     #endif
     465                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128S:
     466                 :             :     #if LIBSPDM_SLH_DSA_SHA2_128S_SUPPORT
     467                 :             :             return 9;
     468                 :             :     #else
     469                 :           0 :             return 0;
     470                 :             :     #endif
     471                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128S:
     472                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_128S_SUPPORT
     473                 :             :             return 9;
     474                 :             :     #else
     475                 :           0 :             return 0;
     476                 :             :     #endif
     477                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128F:
     478                 :             :     #if LIBSPDM_SLH_DSA_SHA2_128F_SUPPORT
     479                 :             :             return 9;
     480                 :             :     #else
     481                 :           0 :             return 0;
     482                 :             :     #endif
     483                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128F:
     484                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_128F_SUPPORT
     485                 :             :             return 9;
     486                 :             :     #else
     487                 :           0 :             return 0;
     488                 :             :     #endif
     489                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192S:
     490                 :             :     #if LIBSPDM_SLH_DSA_SHA2_192S_SUPPORT
     491                 :             :             return 9;
     492                 :             :     #else
     493                 :           0 :             return 0;
     494                 :             :     #endif
     495                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192S:
     496                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_192S_SUPPORT
     497                 :             :             return 9;
     498                 :             :     #else
     499                 :           0 :             return 0;
     500                 :             :     #endif
     501                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192F:
     502                 :             :     #if LIBSPDM_SLH_DSA_SHA2_192F_SUPPORT
     503                 :             :             return 9;
     504                 :             :     #else
     505                 :           0 :             return 0;
     506                 :             :     #endif
     507                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192F:
     508                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_192F_SUPPORT
     509                 :             :             return 9;
     510                 :             :     #else
     511                 :           0 :             return 0;
     512                 :             :     #endif
     513                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256S:
     514                 :             :     #if LIBSPDM_SLH_DSA_SHA2_256S_SUPPORT
     515                 :             :             return 9;
     516                 :             :     #else
     517                 :           0 :             return 0;
     518                 :             :     #endif
     519                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256S:
     520                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_256S_SUPPORT
     521                 :             :             return 9;
     522                 :             :     #else
     523                 :           0 :             return 0;
     524                 :             :     #endif
     525                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256F:
     526                 :             :     #if LIBSPDM_SLH_DSA_SHA2_256F_SUPPORT
     527                 :             :             return 9;
     528                 :             :     #else
     529                 :           0 :             return 0;
     530                 :             :     #endif
     531                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256F:
     532                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_256F_SUPPORT
     533                 :             :             return 9;
     534                 :             :     #else
     535                 :           0 :             return 0;
     536                 :             :     #endif
     537                 :           0 :         default:
     538                 :           0 :             LIBSPDM_ASSERT(false);
     539                 :           0 :             return 0;
     540                 :             :         }
     541                 :             :     }
     542                 :           0 :     LIBSPDM_ASSERT(false);
     543                 :           0 :     return 0;
     544                 :             : }
     545                 :             : 
     546                 :             : /**
     547                 :             :  * This function get the SPDM public key encryption algorithm OID.
     548                 :             :  *
     549                 :             :  * @param[in]      base_asym_algo                 SPDM base_asym_algo
     550                 :             :  * @param[in]      pqc_asym_algo                  SPDM pqc_asym_algo
     551                 :             :  * @param[in,out]  oid                            SPDM public key encryption algorithm OID
     552                 :             :  * @param[in,out]  oid_other                      Other SPDM public key encryption algorithm OID
     553                 :             :  *                                                because of ASN1 code for integer
     554                 :             :  *
     555                 :             :  * @retval  true   get OID successful.
     556                 :             :  * @retval  false  get OID fail.
     557                 :             :  **/
     558                 :         913 : static bool libspdm_get_public_key_algo_OID(
     559                 :             :     uint32_t base_asym_algo, uint32_t pqc_asym_algo, uint8_t *oid,
     560                 :             :     uint8_t *oid_other)
     561                 :             : {
     562                 :             :     uint32_t oid_len;
     563                 :         913 :     oid_len = libspdm_get_public_key_algo_OID_len(base_asym_algo, pqc_asym_algo);
     564         [ -  + ]:         913 :     if (oid_len == 0) {
     565                 :           0 :         return false;
     566                 :             :     }
     567                 :             : 
     568         [ +  - ]:         913 :     if (base_asym_algo != 0) {
     569   [ +  +  +  +  :         913 :         switch (base_asym_algo) {
          +  +  -  -  -  
                      - ]
     570                 :          70 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     571                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048: {
     572                 :             :     #if (LIBSPDM_RSA_SSA_2048_SUPPORT) || (LIBSPDM_RSA_PSS_2048_SUPPORT)
     573                 :          70 :             uint8_t encry_algo_oid_rsa2048[] = KEY_ENCRY_ALGO_RSA2048_FLAG;
     574                 :          70 :             uint8_t encry_algo_oid_rsa2048_other[] = KEY_ENCRY_ALGO_RSA2048_FLAG_OTHER;
     575                 :          70 :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_rsa2048, oid_len);
     576                 :          70 :             libspdm_copy_mem(oid_other, oid_len, encry_algo_oid_rsa2048_other, oid_len);
     577                 :          70 :             return true;
     578                 :             :     #else
     579                 :             :             return false;
     580                 :             :     #endif
     581                 :             :         }
     582                 :           3 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     583                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072: {
     584                 :             :     #if (LIBSPDM_RSA_SSA_3072_SUPPORT) || (LIBSPDM_RSA_PSS_3072_SUPPORT)
     585                 :           3 :             uint8_t encry_algo_oid_rsa3072[] = KEY_ENCRY_ALGO_RSA3072_FLAG;
     586                 :           3 :             uint8_t encry_algo_oid_rsa3072_other[] = KEY_ENCRY_ALGO_RSA3072_FLAG_OTHER;
     587                 :           3 :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_rsa3072, oid_len);
     588                 :           3 :             libspdm_copy_mem(oid_other, oid_len, encry_algo_oid_rsa3072_other, oid_len);
     589                 :           3 :             return true;
     590                 :             :     #else
     591                 :             :             return false;
     592                 :             :     #endif
     593                 :             :         }
     594                 :           2 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     595                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096: {
     596                 :             :     #if (LIBSPDM_RSA_SSA_4096_SUPPORT) || (LIBSPDM_RSA_PSS_4096_SUPPORT)
     597                 :           2 :             uint8_t encry_algo_oid_rsa4096[] = KEY_ENCRY_ALGO_RSA4096_FLAG;
     598                 :           2 :             uint8_t encry_algo_oid_rsa4096_other[] = KEY_ENCRY_ALGO_RSA4096_FLAG_OTHER;
     599                 :           2 :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_rsa4096, oid_len);
     600                 :           2 :             libspdm_copy_mem(oid_other, oid_len, encry_algo_oid_rsa4096_other, oid_len);
     601                 :           2 :             return true;
     602                 :             :     #else
     603                 :             :             return false;
     604                 :             :     #endif
     605                 :             :         }
     606                 :             : 
     607                 :         836 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256: {
     608                 :             :     #if LIBSPDM_ECDSA_P256_SUPPORT
     609                 :         836 :             uint8_t encry_algo_oid_ecc256[] = KEY_ENCRY_ALGO_ECC256_OID;
     610                 :         836 :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_ecc256, oid_len);
     611                 :         836 :             return true;
     612                 :             :     #else
     613                 :             :             return false;
     614                 :             :     #endif
     615                 :             :         }
     616                 :           1 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384: {
     617                 :             :     #if LIBSPDM_ECDSA_P384_SUPPORT
     618                 :           1 :             uint8_t encry_algo_oid_ecc384[] = KEY_ENCRY_ALGO_ECC384_OID;
     619                 :           1 :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_ecc384, oid_len);
     620                 :           1 :             return true;
     621                 :             :     #else
     622                 :             :             return false;
     623                 :             :     #endif
     624                 :             :         }
     625                 :           1 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521: {
     626                 :             :     #if LIBSPDM_ECDSA_P521_SUPPORT
     627                 :           1 :             uint8_t encry_algo_oid_ecc521[] = KEY_ENCRY_ALGO_ECC521_OID;
     628                 :           1 :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_ecc521, oid_len);
     629                 :           1 :             return true;
     630                 :             :     #else
     631                 :             :             return false;
     632                 :             :     #endif
     633                 :             :         }
     634                 :             : 
     635                 :             :         /*sm2 oid  TBD*/
     636                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     637                 :           0 :             return true;
     638                 :             : 
     639                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519: {
     640                 :             :     #if LIBSPDM_EDDSA_ED25519_SUPPORT
     641                 :             :             uint8_t encry_algo_oid_ed25519[] = ENCRY_ALGO_ED25519_OID;
     642                 :             :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_ed25519, oid_len);
     643                 :             :             return true;
     644                 :             :     #else
     645                 :           0 :             return false;
     646                 :             :     #endif
     647                 :             :             break;
     648                 :             :         }
     649                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448: {
     650                 :             :     #if LIBSPDM_EDDSA_ED448_SUPPORT
     651                 :             :             uint8_t encry_algo_oid_ed448[] = ENCRY_ALGO_ED448_OID;
     652                 :             :             libspdm_copy_mem(oid, oid_len, encry_algo_oid_ed448, oid_len);
     653                 :             :             return true;
     654                 :             :     #else
     655                 :           0 :             return false;
     656                 :             :     #endif
     657                 :             :             break;
     658                 :             :         }
     659                 :             : 
     660                 :           0 :         default:
     661                 :           0 :             LIBSPDM_ASSERT(false);
     662                 :           0 :             return false;
     663                 :             :         }
     664                 :             :     }
     665         [ #  # ]:           0 :     if (pqc_asym_algo != 0) {
     666   [ #  #  #  #  :           0 :         switch (pqc_asym_algo) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     667                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_44: {
     668                 :             :     #if LIBSPDM_ML_DSA_44_SUPPORT
     669                 :             :             uint8_t algo_oid_mldsa44[] = ALGO_MLDSA44_OID;
     670                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_mldsa44, oid_len);
     671                 :             :             return true;
     672                 :             :     #else
     673                 :           0 :             return false;
     674                 :             :     #endif
     675                 :             :             break;
     676                 :             :         }
     677                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_65: {
     678                 :             :     #if LIBSPDM_ML_DSA_65_SUPPORT
     679                 :             :             uint8_t algo_oid_mldsa65[] = ALGO_MLDSA65_OID;
     680                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_mldsa65, oid_len);
     681                 :             :             return true;
     682                 :             :     #else
     683                 :           0 :             return false;
     684                 :             :     #endif
     685                 :             :             break;
     686                 :             :         }
     687                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_87: {
     688                 :             :     #if LIBSPDM_ML_DSA_87_SUPPORT
     689                 :             :             uint8_t algo_oid_mldsa87[] = ALGO_MLDSA87_OID;
     690                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_mldsa87, oid_len);
     691                 :             :             return true;
     692                 :             :     #else
     693                 :           0 :             return false;
     694                 :             :     #endif
     695                 :             :             break;
     696                 :             :         }
     697                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128S: {
     698                 :             :     #if LIBSPDM_SLH_DSA_SHA2_128S_SUPPORT
     699                 :             :             uint8_t algo_oid_slhdsa_sha2_128s[] = ALGO_SLHDSA_SHA2_128S_OID;
     700                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_sha2_128s, oid_len);
     701                 :             :             return true;
     702                 :             :     #else
     703                 :           0 :             return false;
     704                 :             :     #endif
     705                 :             :             break;
     706                 :             :         }
     707                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128S: {
     708                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_128S_SUPPORT
     709                 :             :             uint8_t algo_oid_slhdsa_shake_128s[] = ALGO_SLHDSA_SHAKE_128S_OID;
     710                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_shake_128s, oid_len);
     711                 :             :             return true;
     712                 :             :     #else
     713                 :           0 :             return false;
     714                 :             :     #endif
     715                 :             :             break;
     716                 :             :         }
     717                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128F: {
     718                 :             :     #if LIBSPDM_SLH_DSA_SHA2_128F_SUPPORT
     719                 :             :             uint8_t algo_oid_slhdsa_sha2_128f[] = ALGO_SLHDSA_SHA2_128F_OID;
     720                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_sha2_128f, oid_len);
     721                 :             :             return true;
     722                 :             :     #else
     723                 :           0 :             return false;
     724                 :             :     #endif
     725                 :             :             break;
     726                 :             :         }
     727                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128F: {
     728                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_128F_SUPPORT
     729                 :             :             uint8_t algo_oid_slhdsa_shake_128f[] = ALGO_SLHDSA_SHAKE_128F_OID;
     730                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_shake_128f, oid_len);
     731                 :             :             return true;
     732                 :             :     #else
     733                 :           0 :             return false;
     734                 :             :     #endif
     735                 :             :             break;
     736                 :             :         }
     737                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192S: {
     738                 :             :     #if LIBSPDM_SLH_DSA_SHA2_192S_SUPPORT
     739                 :             :             uint8_t algo_oid_slhdsa_sha2_192s[] = ALGO_SLHDSA_SHA2_192S_OID;
     740                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_sha2_192s, oid_len);
     741                 :             :             return true;
     742                 :             :     #else
     743                 :           0 :             return false;
     744                 :             :     #endif
     745                 :             :             break;
     746                 :             :         }
     747                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192S: {
     748                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_192S_SUPPORT
     749                 :             :             uint8_t algo_oid_slhdsa_shake_192s[] = ALGO_SLHDSA_SHAKE_192S_OID;
     750                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_shake_192s, oid_len);
     751                 :             :             return true;
     752                 :             :     #else
     753                 :           0 :             return false;
     754                 :             :     #endif
     755                 :             :             break;
     756                 :             :         }
     757                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192F: {
     758                 :             :     #if LIBSPDM_SLH_DSA_SHA2_192F_SUPPORT
     759                 :             :             uint8_t algo_oid_slhdsa_sha2_192f[] = ALGO_SLHDSA_SHA2_192F_OID;
     760                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_sha2_192f, oid_len);
     761                 :             :             return true;
     762                 :             :     #else
     763                 :           0 :             return false;
     764                 :             :     #endif
     765                 :             :             break;
     766                 :             :         }
     767                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192F: {
     768                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_192F_SUPPORT
     769                 :             :             uint8_t algo_oid_slhdsa_shake_192f[] = ALGO_SLHDSA_SHAKE_192F_OID;
     770                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_shake_192f, oid_len);
     771                 :             :             return true;
     772                 :             :     #else
     773                 :           0 :             return false;
     774                 :             :     #endif
     775                 :             :             break;
     776                 :             :         }
     777                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256S: {
     778                 :             :     #if LIBSPDM_SLH_DSA_SHA2_256S_SUPPORT
     779                 :             :             uint8_t algo_oid_slhdsa_sha2_256s[] = ALGO_SLHDSA_SHA2_256S_OID;
     780                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_sha2_256s, oid_len);
     781                 :             :             return true;
     782                 :             :     #else
     783                 :           0 :             return false;
     784                 :             :     #endif
     785                 :             :             break;
     786                 :             :         }
     787                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256S: {
     788                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_256S_SUPPORT
     789                 :             :             uint8_t algo_oid_slhdsa_shake_256s[] = ALGO_SLHDSA_SHAKE_256S_OID;
     790                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_shake_256s, oid_len);
     791                 :             :             return true;
     792                 :             :     #else
     793                 :           0 :             return false;
     794                 :             :     #endif
     795                 :             :             break;
     796                 :             :         }
     797                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256F: {
     798                 :             :     #if LIBSPDM_SLH_DSA_SHA2_256F_SUPPORT
     799                 :             :             uint8_t algo_oid_slhdsa_sha2_256f[] = ALGO_SLHDSA_SHA2_256F_OID;
     800                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_sha2_256f, oid_len);
     801                 :             :             return true;
     802                 :             :     #else
     803                 :           0 :             return false;
     804                 :             :     #endif
     805                 :             :             break;
     806                 :             :         }
     807                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256F: {
     808                 :             :     #if LIBSPDM_SLH_DSA_SHAKE_256F_SUPPORT
     809                 :             :             uint8_t algo_oid_slhdsa_shake_256f[] = ALGO_SLHDSA_SHAKE_256F_OID;
     810                 :             :             libspdm_copy_mem(oid, oid_len, algo_oid_slhdsa_shake_256f, oid_len);
     811                 :             :             return true;
     812                 :             :     #else
     813                 :           0 :             return false;
     814                 :             :     #endif
     815                 :             :             break;
     816                 :             :         }
     817                 :           0 :         default:
     818                 :           0 :             LIBSPDM_ASSERT(false);
     819                 :           0 :             return false;
     820                 :             :         }
     821                 :             :     }
     822                 :           0 :     LIBSPDM_ASSERT(false);
     823                 :           0 :     return false;
     824                 :             : }
     825                 :             : 
     826                 :             : /**
     827                 :             :  * Verify cert public key encryption algorithm is matched to negotiated base_asym algo
     828                 :             :  *
     829                 :             :  * @param[in]      cert                  Pointer to the DER-encoded certificate data.
     830                 :             :  * @param[in]      cert_size             The size of certificate data in bytes.
     831                 :             :  * @param[out]     oid                   cert public key encryption algorithm OID
     832                 :             :  * @param[in]      oid_size              the buffer size for required OID
     833                 :             :  * @param[in]      base_asym_algo        SPDM base_asym_algo
     834                 :             :  * @param[in]      pqc_asym_algo         SPDM pqc_asym_algo
     835                 :             :  *
     836                 :             :  * @retval  true   get public key oid from cert successfully
     837                 :             :  * @retval  false  get public key oid from cert fail
     838                 :             :  **/
     839                 :         913 : static bool libspdm_get_public_key_oid(
     840                 :             :     const uint8_t *cert, size_t cert_size,
     841                 :             :     uint8_t *oid, size_t oid_size, uint32_t base_asym_algo, uint32_t pqc_asym_algo)
     842                 :             : {
     843                 :             :     bool ret;
     844                 :             :     uint8_t *ptr;
     845                 :             :     int32_t length;
     846                 :             :     size_t obj_len;
     847                 :             :     uint8_t *end;
     848                 :             :     uint8_t index;
     849                 :             :     uint8_t sequence_time;
     850                 :             : 
     851                 :         913 :     length = (int32_t)cert_size;
     852                 :         913 :     ptr = (uint8_t*)(size_t)cert;
     853                 :         913 :     obj_len = 0;
     854                 :         913 :     end = ptr + length;
     855                 :         913 :     ret = true;
     856                 :             : 
     857                 :             :     /* TBSCertificate have 5 sequence before subjectPublicKeyInfo*/
     858                 :         913 :     sequence_time = 5;
     859                 :             : 
     860                 :             :     /*all cert sequence*/
     861                 :         913 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     862                 :             :                                LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     863         [ -  + ]:         913 :     if (!ret) {
     864                 :           0 :         return false;
     865                 :             :     }
     866                 :             : 
     867                 :             :     /*TBSCertificate sequence*/
     868                 :         913 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     869                 :             :                                LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     870         [ -  + ]:         913 :     if (!ret) {
     871                 :           0 :         return false;
     872                 :             :     }
     873                 :             : 
     874                 :         913 :     end = ptr + obj_len;
     875                 :             :     /*version*/
     876                 :         913 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     877                 :             :                                LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC |
     878                 :             :                                LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     879         [ -  + ]:         913 :     if (!ret) {
     880                 :           0 :         return false;
     881                 :             :     }
     882                 :             : 
     883                 :         913 :     ptr += obj_len;
     884                 :             :     /*serialNumber*/
     885                 :         913 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len, LIBSPDM_CRYPTO_ASN1_INTEGER);
     886         [ -  + ]:         913 :     if (!ret) {
     887                 :           0 :         return false;
     888                 :             :     }
     889                 :             : 
     890                 :             :     /**
     891                 :             :      * signature AlgorithmIdentifier,
     892                 :             :      * issuer Name,
     893                 :             :      * validity Validity,
     894                 :             :      * subject Name,
     895                 :             :      * subjectPublicKeyInfo
     896                 :             :      **/
     897         [ +  + ]:        5478 :     for (index = 0; index < sequence_time; index++) {
     898                 :        4565 :         ptr += obj_len;
     899                 :        4565 :         ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     900                 :             :                                    LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     901         [ -  + ]:        4565 :         if (!ret) {
     902                 :           0 :             return false;
     903                 :             :         }
     904                 :             :     }
     905                 :             : 
     906         [ +  - ]:         913 :     if (base_asym_algo != 0) {
     907   [ +  +  -  - ]:         913 :         switch (base_asym_algo)
     908                 :             :         {
     909                 :          75 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     910                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     911                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     912                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     913                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     914                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     915                 :          75 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     916                 :             :                                        LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     917         [ -  + ]:          75 :             if (!ret) {
     918                 :           0 :                 return false;
     919                 :             :             }
     920                 :             : 
     921                 :          75 :             ptr += obj_len;
     922                 :          75 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len, LIBSPDM_CRYPTO_ASN1_BIT_STRING);
     923         [ -  + ]:          75 :             if (!ret) {
     924                 :           0 :                 return false;
     925                 :             :             }
     926                 :             : 
     927                 :             :             /*get rsa key len*/
     928                 :          75 :             ptr++;
     929                 :          75 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     930                 :             :                                        LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     931         [ +  + ]:          75 :             if (!ret) {
     932                 :           1 :                 return false;
     933                 :             :             }
     934                 :          74 :             libspdm_copy_mem(oid, oid_size, ptr, oid_size);
     935                 :          74 :             break;
     936                 :         838 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     937                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     938                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     939                 :         838 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     940                 :             :                                        LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     941         [ -  + ]:         838 :             if (!ret) {
     942                 :           0 :                 return false;
     943                 :             :             }
     944                 :         838 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);
     945         [ -  + ]:         838 :             if (!ret) {
     946                 :           0 :                 return false;
     947                 :             :             }
     948                 :             : 
     949                 :             :             /*get ecc second oid*/
     950                 :         838 :             ptr +=obj_len;
     951                 :         838 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);
     952         [ -  + ]:         838 :             if (!ret) {
     953                 :           0 :                 return false;
     954                 :             :             }
     955                 :             : 
     956         [ -  + ]:         838 :             if (oid_size != obj_len) {
     957                 :           0 :                 return false;
     958                 :             :             }
     959                 :             : 
     960                 :         838 :             libspdm_copy_mem(oid, oid_size, ptr, obj_len);
     961                 :         838 :             break;
     962                 :           0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     963                 :             :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     964                 :           0 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
     965                 :             :                                        LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     966         [ #  # ]:           0 :             if (!ret) {
     967                 :           0 :                 return false;
     968                 :             :             }
     969                 :             : 
     970                 :             :             /*get eddsa oid*/
     971                 :           0 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);
     972         [ #  # ]:           0 :             if (!ret) {
     973                 :           0 :                 return false;
     974                 :             :             }
     975                 :             : 
     976         [ #  # ]:           0 :             if (oid_size != obj_len) {
     977                 :           0 :                 return false;
     978                 :             :             }
     979                 :             : 
     980                 :           0 :             libspdm_copy_mem(oid, oid_size, ptr, obj_len);
     981                 :           0 :             break;
     982                 :           0 :         default:
     983                 :           0 :             LIBSPDM_ASSERT(false);
     984                 :           0 :             return false;
     985                 :             :         }
     986                 :             :     }
     987         [ -  + ]:         912 :     if (pqc_asym_algo != 0) {
     988         [ #  # ]:           0 :         switch (pqc_asym_algo)
     989                 :             :         {
     990                 :           0 :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_44:
     991                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_65:
     992                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_87:
     993                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128S:
     994                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128S:
     995                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128F:
     996                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128F:
     997                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192S:
     998                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192S:
     999                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192F:
    1000                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192F:
    1001                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256S:
    1002                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256S:
    1003                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256F:
    1004                 :             :         case SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256F:
    1005                 :             :             /* algorithm AlgorithmIdentifier SEQUENCE */
    1006                 :           0 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
    1007                 :             :                                        LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    1008         [ #  # ]:           0 :             if (!ret) {
    1009                 :           0 :                 return false;
    1010                 :             :             }
    1011                 :             : 
    1012                 :             :             /* OID */
    1013                 :           0 :             ret = libspdm_asn1_get_tag(&ptr, end, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);
    1014         [ #  # ]:           0 :             if (!ret) {
    1015                 :           0 :                 return false;
    1016                 :             :             }
    1017                 :             : 
    1018         [ #  # ]:           0 :             if (oid_size != obj_len) {
    1019                 :           0 :                 return false;
    1020                 :             :             }
    1021                 :             : 
    1022                 :           0 :             libspdm_copy_mem(oid, oid_size, ptr, obj_len);
    1023                 :           0 :             break;
    1024                 :           0 :         default:
    1025                 :           0 :             LIBSPDM_ASSERT(false);
    1026                 :           0 :             return false;
    1027                 :             :         }
    1028                 :             :     }
    1029                 :         912 :     return true;
    1030                 :             : }
    1031                 :             : 
    1032                 :             : /**
    1033                 :             :  * Verify cert public key encryption algorithm is matched to negotiated base_asym algo
    1034                 :             :  *
    1035                 :             :  * @param[in]  cert                  Pointer to the DER-encoded certificate data.
    1036                 :             :  * @param[in]  cert_size             The size of certificate data in bytes.
    1037                 :             :  * @param[in]  base_asym_algo        SPDM base_asym_algo
    1038                 :             :  * @param[in]  pqc_asym_algo         SPDM pqc_asym_algo
    1039                 :             :  *
    1040                 :             :  * @retval  true   verify pass
    1041                 :             :  * @retval  false  verify fail
    1042                 :             :  **/
    1043                 :         913 : static bool libspdm_verify_cert_subject_public_key_info(const uint8_t *cert, size_t cert_size,
    1044                 :             :                                                         uint32_t base_asym_algo, uint32_t pqc_asym_algo)
    1045                 :             : {
    1046                 :             :     size_t oid_len;
    1047                 :             :     bool status;
    1048                 :             : 
    1049                 :             :     /*public key encrypt algo OID from cert*/
    1050                 :             :     uint8_t cert_public_key_crypt_algo_oid[LIBSPDM_MAX_ENCRYPTION_ALGO_OID_LEN];
    1051                 :             :     /*public key encrypt algo OID from libspdm stored*/
    1052                 :             :     uint8_t libspdm_public_key_crypt_algo_oid[LIBSPDM_MAX_ENCRYPTION_ALGO_OID_LEN];
    1053                 :             :     uint8_t libspdm_public_key_crypt_algo_oid_other[LIBSPDM_MAX_ENCRYPTION_ALGO_OID_LEN];
    1054                 :             : 
    1055                 :         913 :     libspdm_zero_mem(libspdm_public_key_crypt_algo_oid, LIBSPDM_MAX_ENCRYPTION_ALGO_OID_LEN);
    1056                 :         913 :     libspdm_zero_mem(libspdm_public_key_crypt_algo_oid_other, LIBSPDM_MAX_ENCRYPTION_ALGO_OID_LEN);
    1057                 :             : 
    1058                 :             :     /*work around: skip the sm2*/
    1059         [ -  + ]:         913 :     if (base_asym_algo == SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256) {
    1060                 :           0 :         return true;
    1061                 :             :     }
    1062                 :             : 
    1063                 :         913 :     oid_len = libspdm_get_public_key_algo_OID_len(base_asym_algo, pqc_asym_algo);
    1064         [ -  + ]:         913 :     if (oid_len == 0) {
    1065                 :           0 :         return false;
    1066                 :             :     }
    1067                 :             :     /*get public key encrypt algo OID from libspdm stored*/
    1068                 :         913 :     status = libspdm_get_public_key_algo_OID(base_asym_algo, pqc_asym_algo,
    1069                 :             :                                              libspdm_public_key_crypt_algo_oid,
    1070                 :             :                                              libspdm_public_key_crypt_algo_oid_other);
    1071         [ -  + ]:         913 :     if (!status) {
    1072                 :           0 :         return status;
    1073                 :             :     }
    1074                 :             : 
    1075                 :             :     /*get public key encrypt algo OID from cert*/
    1076                 :         913 :     status = libspdm_get_public_key_oid(cert, cert_size, cert_public_key_crypt_algo_oid, oid_len,
    1077                 :             :                                         base_asym_algo, pqc_asym_algo);
    1078   [ +  +  +  + ]:         913 :     if (!status || (!libspdm_consttime_is_mem_equal(cert_public_key_crypt_algo_oid,
    1079                 :           2 :                                                     libspdm_public_key_crypt_algo_oid, oid_len) &&
    1080         [ +  - ]:           2 :                     !libspdm_consttime_is_mem_equal(cert_public_key_crypt_algo_oid,
    1081                 :             :                                                     libspdm_public_key_crypt_algo_oid_other,
    1082                 :             :                                                     oid_len))) {
    1083                 :           3 :         return false;
    1084                 :             :     }
    1085                 :             : 
    1086                 :         910 :     return status;
    1087                 :             : }
    1088                 :             : 
    1089                 :             : /**
    1090                 :             :  * Verify leaf cert basic_constraints CA is false
    1091                 :             :  *
    1092                 :             :  * @param[in]  cert                  Pointer to the DER-encoded certificate data.
    1093                 :             :  * @param[in]  cert_size             The size of certificate data in bytes.
    1094                 :             :  * @param[in]  need_basic_constraints  This value indicates whether basic_constraints must be present in the Cert
    1095                 :             :  *
    1096                 :             :  * @retval  true   verify pass,two case: 1.basic constraints is not present in cert, when need_basic_constraints is false;
    1097                 :             :  *                                       2. cert basic_constraints CA is false;
    1098                 :             :  * @retval  false  verify fail
    1099                 :             :  **/
    1100                 :         894 : static bool libspdm_verify_leaf_cert_basic_constraints(const uint8_t *cert, size_t cert_size,
    1101                 :             :                                                        bool need_basic_constraints)
    1102                 :             : {
    1103                 :             :     bool status;
    1104                 :             :     /*basic_constraints from cert*/
    1105                 :             :     uint8_t cert_basic_constraints[LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN];
    1106                 :             :     size_t len;
    1107                 :             : 
    1108                 :         894 :     uint8_t basic_constraints_false_case[] = BASIC_CONSTRAINTS_CA_FALSE;
    1109                 :             : 
    1110                 :         894 :     len = LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN;
    1111                 :             : 
    1112                 :         894 :     status = libspdm_x509_get_extended_basic_constraints(cert, cert_size,
    1113                 :             :                                                          cert_basic_constraints, &len);
    1114         [ -  + ]:         894 :     if (!status) {
    1115                 :           0 :         return false;
    1116         [ +  + ]:         894 :     } else if (len == 0) {
    1117                 :             :         /* basic constraints is not present in cert */
    1118         [ +  + ]:           2 :         if (need_basic_constraints) {
    1119                 :           1 :             return false;
    1120                 :             :         } else {
    1121                 :           1 :             return true;
    1122                 :             :         }
    1123                 :             :     }
    1124                 :             : 
    1125   [ +  +  +  - ]:        1783 :     if ((len == sizeof(basic_constraints_false_case)) &&
    1126                 :         891 :         (libspdm_consttime_is_mem_equal(cert_basic_constraints,
    1127                 :             :                                         basic_constraints_false_case,
    1128                 :             :                                         sizeof(basic_constraints_false_case)))) {
    1129                 :         891 :         return true;
    1130                 :             :     }
    1131                 :             : 
    1132                 :           1 :     return false;
    1133                 :             : }
    1134                 :             : 
    1135                 :             : /**
    1136                 :             :  * Verify leaf certificate basic_constraints CA is correct for set certificate.
    1137                 :             :  *
    1138                 :             :  * For SPDM 1.2
    1139                 :             :  *     - If certificate model is DeviceCert and CA is present then CA must be false.
    1140                 :             :  *     - If certificate model is AliasCert and CA is present then CA must be true.
    1141                 :             :  *
    1142                 :             :  * For SPDM 1.3 and up, CA must be present and
    1143                 :             :  *     - If certificate model is DeviceCert or GenericCert then CA must be false.
    1144                 :             :  *     - If certificate model is AliasCert then CA must be true.
    1145                 :             :  *
    1146                 :             :  * @param[in]  cert                   Pointer to the DER-encoded certificate data.
    1147                 :             :  * @param[in]  cert_size              The size of certificate data in bytes.
    1148                 :             :  * @param[in]  cert_model             The certificate model.
    1149                 :             :  * @param[in]  need_basic_constraints This value indicates whether basic_constraints must be present
    1150                 :             :  *                                    in the certificate.
    1151                 :             :  *
    1152                 :             :  * @retval  true   verify pass 1. basic_constraints is not present when allowed.
    1153                 :             :  *                             2. basic_constraints is present and correct.
    1154                 :             :  * @retval  false  verify fail
    1155                 :             :  **/
    1156                 :          16 : static bool libspdm_verify_set_cert_leaf_cert_basic_constraints(
    1157                 :             :     const uint8_t *cert, size_t cert_size, uint8_t cert_model, bool need_basic_constraints)
    1158                 :             : {
    1159                 :             :     bool status;
    1160                 :             :     /* basic_constraints from certificate. */
    1161                 :             :     uint8_t cert_basic_constraints[LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN];
    1162                 :             :     size_t len;
    1163                 :             : 
    1164                 :          16 :     const uint8_t basic_constraints_false_case[] = BASIC_CONSTRAINTS_CA_FALSE;
    1165                 :          16 :     const uint8_t basic_constraints_true_case[] = BASIC_CONSTRAINTS_CA_TRUE;
    1166                 :             : 
    1167                 :          16 :     len = LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN;
    1168                 :             : 
    1169                 :          16 :     status = libspdm_x509_get_extended_basic_constraints(cert, cert_size,
    1170                 :             :                                                          cert_basic_constraints, &len);
    1171         [ -  + ]:          16 :     if (!status) {
    1172                 :           0 :         return false;
    1173   [ +  +  -  + ]:          16 :     } else if (need_basic_constraints && (len == 0)) {
    1174                 :           0 :         return false;
    1175                 :             :     }
    1176                 :             : 
    1177   [ +  +  -  + ]:          16 :     if ((cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT) ||
    1178                 :             :         (cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
    1179   [ +  +  +  - ]:           9 :         if (need_basic_constraints || (len != 0)) {
    1180   [ +  -  +  - ]:          18 :             if ((len == sizeof(basic_constraints_false_case)) &&
    1181                 :           9 :                 (libspdm_consttime_is_mem_equal(cert_basic_constraints,
    1182                 :             :                                                 basic_constraints_false_case,
    1183                 :             :                                                 sizeof(basic_constraints_false_case)))) {
    1184                 :           9 :                 return true;
    1185                 :             :             }
    1186                 :             :         }
    1187                 :             :     } else {
    1188                 :             :         /* Alias certificate model. */
    1189   [ +  +  +  - ]:           7 :         if (need_basic_constraints || (len != 0)) {
    1190                 :             :             /* basicConstraints may include the pathLen field. Therefore do not check sequence
    1191                 :             :              * length. */
    1192         [ +  + ]:           7 :             if (len >= sizeof(basic_constraints_true_case)) {
    1193         [ -  + ]:           5 :                 if (cert_basic_constraints[0] != basic_constraints_true_case[0]) {
    1194                 :           0 :                     return false;
    1195                 :             :                 }
    1196         [ +  - ]:           5 :                 if  (libspdm_consttime_is_mem_equal(&cert_basic_constraints[2],
    1197                 :             :                                                     &basic_constraints_true_case[2],
    1198                 :             :                                                     sizeof(basic_constraints_true_case) - 2)) {
    1199                 :           5 :                     return true;
    1200                 :             :                 }
    1201                 :             :             }
    1202                 :             :         }
    1203                 :             :     }
    1204                 :           2 :     return false;
    1205                 :             : }
    1206                 :             : 
    1207                 :             : /**
    1208                 :             :  * Verify leaf cert spdm defined extended key usage
    1209                 :             :  *
    1210                 :             :  * @param[in]  cert                  Pointer to the DER-encoded certificate data.
    1211                 :             :  * @param[in]  cert_size             The size of certificate data in bytes.
    1212                 :             :  * @param[in]  is_requester_cert     Is the function verifying requester or responder cert.
    1213                 :             :  *
    1214                 :             :  * @retval  true   verify pass, two cases:
    1215                 :             :  *                 1. spdm defined eku is not present in cert;
    1216                 :             :  *                 2. spdm defined eku is compliant with requester/responder identity;
    1217                 :             :  * @retval  false  verify fail, two cases:
    1218                 :             :  *                 1. requester's cert has only responder auth oid in eku;
    1219                 :             :  *                 2. responder's cert has only requester auth oid in eku;
    1220                 :             :  **/
    1221                 :         917 : static bool libspdm_verify_leaf_cert_spdm_eku(const uint8_t *cert, size_t cert_size,
    1222                 :             :                                               bool is_requester_cert)
    1223                 :             : {
    1224                 :             :     bool status;
    1225                 :             :     uint8_t eku[256];
    1226                 :             :     size_t eku_size;
    1227                 :             :     bool req_auth_oid_find_success;
    1228                 :             :     bool rsp_auth_oid_find_success;
    1229                 :             :     uint8_t *ptr;
    1230                 :             :     size_t obj_len;
    1231                 :             : 
    1232                 :             :     /* SPDM defined OID */
    1233                 :         917 :     uint8_t eku_requester_auth_oid[] = SPDM_OID_DMTF_EKU_REQUESTER_AUTH;
    1234                 :         917 :     uint8_t eku_responder_auth_oid[] = SPDM_OID_DMTF_EKU_RESPONDER_AUTH;
    1235                 :             : 
    1236                 :         917 :     eku_size = sizeof(eku);
    1237                 :         917 :     status = libspdm_x509_get_extended_key_usage(cert, cert_size, eku, &eku_size);
    1238         [ -  + ]:         917 :     if (!status) {
    1239                 :           0 :         return false;
    1240         [ -  + ]:         917 :     } else if (eku_size == 0) {
    1241                 :             :         /* eku is not present in cert */
    1242                 :           0 :         return true;
    1243                 :             :     }
    1244                 :             : 
    1245                 :         917 :     ptr = eku;
    1246                 :         917 :     obj_len = 0;
    1247                 :         917 :     req_auth_oid_find_success = false;
    1248                 :         917 :     rsp_auth_oid_find_success = false;
    1249                 :             : 
    1250                 :         917 :     status = libspdm_asn1_get_tag(&ptr, eku + eku_size, &obj_len,
    1251                 :             :                                   LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    1252         [ -  + ]:         917 :     if (!status) {
    1253                 :           0 :         return false;
    1254                 :             :     }
    1255                 :             : 
    1256         [ +  + ]:        3671 :     while(ptr < eku + eku_size) {
    1257                 :        2754 :         status = libspdm_asn1_get_tag(&ptr, eku + eku_size, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);
    1258         [ -  + ]:        2754 :         if (!status) {
    1259                 :           0 :             return false;
    1260                 :             :         }
    1261                 :             : 
    1262   [ +  +  +  + ]:        2762 :         if ((obj_len == sizeof(eku_requester_auth_oid)) &&
    1263                 :           8 :             (libspdm_consttime_is_mem_equal(ptr, eku_requester_auth_oid,
    1264                 :             :                                             sizeof(eku_requester_auth_oid)))) {
    1265                 :           4 :             req_auth_oid_find_success = true;
    1266                 :             :         }
    1267   [ +  +  +  + ]:        2762 :         if ((obj_len == sizeof(eku_responder_auth_oid)) &&
    1268                 :           8 :             (libspdm_consttime_is_mem_equal(ptr, eku_responder_auth_oid,
    1269                 :             :                                             sizeof(eku_responder_auth_oid)))) {
    1270                 :           4 :             rsp_auth_oid_find_success = true;
    1271                 :             :         }
    1272                 :             : 
    1273                 :        2754 :         ptr += obj_len;
    1274                 :             :     }
    1275                 :             : 
    1276         [ -  + ]:         917 :     if (ptr != eku + eku_size) {
    1277                 :           0 :         return false;
    1278                 :             :     }
    1279                 :             : 
    1280         [ +  + ]:         917 :     if (is_requester_cert) {
    1281                 :             :         /* it should not only contain responder auth oid */
    1282   [ +  +  +  + ]:          22 :         if (!req_auth_oid_find_success && rsp_auth_oid_find_success) {
    1283                 :           1 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Requester certificate contains Responder OID.\n"));
    1284                 :           1 :             return false;
    1285                 :             :         }
    1286                 :             :     } else {
    1287                 :             :         /* it should not only contain requester auth oid */
    1288   [ +  +  +  + ]:         895 :         if (req_auth_oid_find_success && !rsp_auth_oid_find_success) {
    1289                 :           1 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Responder certificate contains Requester OID.\n"));
    1290                 :           1 :             return false;
    1291                 :             :         }
    1292                 :             :     }
    1293                 :             : 
    1294                 :         915 :     return true;
    1295                 :             : }
    1296                 :             : 
    1297                 :         914 : bool libspdm_contains_hardware_id_oid(const uint8_t *cert, size_t cert_size)
    1298                 :             : {
    1299                 :             :     bool status;
    1300                 :             :     bool find_successful;
    1301                 :             :     uint8_t spdm_extension[LIBSPDM_MAX_EXTENSION_LEN];
    1302                 :             :     size_t len;
    1303                 :             :     uint8_t *ptr;
    1304                 :             :     uint8_t *temptr;
    1305                 :             :     size_t obj_len;
    1306                 :             : 
    1307                 :             :     /* SPDM defined OID */
    1308                 :         914 :     uint8_t oid_spdm_extension[] = SPDM_OID_DMTF_SPDM_EXTENSION;
    1309                 :         914 :     uint8_t hardware_identity_oid[] = SPDM_OID_DMTF_HARDWARE_IDENTITY;
    1310                 :             : 
    1311                 :         914 :     len = LIBSPDM_MAX_EXTENSION_LEN;
    1312                 :             : 
    1313   [ +  -  -  + ]:         914 :     if (cert == NULL || cert_size == 0) {
    1314                 :           0 :         return false;
    1315                 :             :     }
    1316                 :             : 
    1317                 :         914 :     status = libspdm_x509_get_extension_data(cert, cert_size,
    1318                 :             :                                              (const uint8_t *)oid_spdm_extension,
    1319                 :             :                                              sizeof(oid_spdm_extension),
    1320                 :             :                                              spdm_extension,
    1321                 :             :                                              &len);
    1322         [ -  + ]:         914 :     if (!status) {
    1323                 :           0 :         return false;
    1324         [ +  + ]:         914 :     } else if (len == 0) {
    1325                 :          17 :         return false;
    1326                 :             :     }
    1327                 :             : 
    1328                 :             :     /*find the spdm hardware identity OID*/
    1329                 :         897 :     find_successful = false;
    1330                 :         897 :     ptr = spdm_extension;
    1331                 :         897 :     obj_len = 0;
    1332                 :             : 
    1333                 :             :     /*id-spdm-cert-oids ::= SEQUENCE SIZE (1..MAX) OF id-spdm-cert-oid*/
    1334                 :         897 :     status = libspdm_asn1_get_tag(
    1335                 :             :         &ptr, spdm_extension + len, &obj_len,
    1336                 :             :         LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    1337         [ -  + ]:         897 :     if (!status) {
    1338                 :           0 :         return false;
    1339                 :             :     }
    1340                 :             : 
    1341         [ +  + ]:        1794 :     while(ptr < spdm_extension + len) {
    1342                 :         897 :         status = libspdm_asn1_get_tag(
    1343                 :             :             &ptr, spdm_extension + len, &obj_len,
    1344                 :             :             LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    1345         [ -  + ]:         897 :         if (!status) {
    1346                 :           0 :             return false;
    1347                 :             :         }
    1348                 :             : 
    1349                 :         897 :         temptr = ptr + obj_len;
    1350                 :         897 :         status = libspdm_asn1_get_tag(
    1351                 :             :             &ptr, spdm_extension + len, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);
    1352         [ -  + ]:         897 :         if (!status) {
    1353                 :           0 :             return false;
    1354                 :             :         }
    1355   [ +  -  +  - ]:        1794 :         if ((obj_len == sizeof(hardware_identity_oid)) &&
    1356                 :         897 :             (libspdm_consttime_is_mem_equal(ptr, hardware_identity_oid,
    1357                 :             :                                             sizeof(hardware_identity_oid)))) {
    1358                 :         897 :             find_successful = true;
    1359                 :             :         }
    1360                 :         897 :         ptr = temptr;
    1361                 :             :     }
    1362                 :             : 
    1363         [ -  + ]:         897 :     if (ptr != spdm_extension + len) {
    1364                 :           0 :         return false;
    1365                 :             :     }
    1366                 :             : 
    1367                 :         897 :     return find_successful;
    1368                 :             : }
    1369                 :             : 
    1370                 :             : /**
    1371                 :             :  * Verify leaf cert spdm defined extension
    1372                 :             :  *
    1373                 :             :  * @param[in]  cert                  Pointer to the DER-encoded certificate data.
    1374                 :             :  * @param[in]  cert_size             The size of certificate data in bytes.
    1375                 :             :  * @param[in]  is_requester_cert     Is the function verifying requester or responder cert.
    1376                 :             :  * @param[in]  cert_model            One of the SPDM_CERTIFICATE_INFO_CERT_MODEL_* macros.
    1377                 :             :  *
    1378                 :             :  * @retval  true   verify pass
    1379                 :             :  * @retval  false  verify fail, two cases: 1. Unable to get or validate extension data.
    1380                 :             :  *                                       2. hardware_identity_oid is found in AliasCert model;
    1381                 :             :  **/
    1382                 :         908 : static bool libspdm_verify_leaf_cert_spdm_extension(const uint8_t *cert, size_t cert_size,
    1383                 :             :                                                     bool is_requester_cert,
    1384                 :             :                                                     uint8_t cert_model)
    1385                 :             : {
    1386                 :         908 :     bool find_successful = libspdm_contains_hardware_id_oid(cert, cert_size);
    1387                 :             : 
    1388                 :             :     /* Responder does not determine Requester's certificate model */
    1389         [ +  + ]:         908 :     if (!is_requester_cert) {
    1390   [ +  +  +  + ]:         889 :         if ((find_successful) && (cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT)) {
    1391                 :             :             /* Hardware_identity_OID is found in alias cert model */
    1392                 :           5 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1393                 :             :                            "Hardware identity OID present in alias leaf certificate.\n"));
    1394                 :           5 :             return false;
    1395                 :             :         }
    1396                 :             :     }
    1397                 :             : 
    1398                 :         903 :     return true;
    1399                 :             : }
    1400                 :             : 
    1401                 :             : /**
    1402                 :             :  * Certificate common Check for SPDM leaf cert when get_cert and set_cert.
    1403                 :             :  *
    1404                 :             :  * @param[in]  cert                  Pointer to the DER-encoded certificate data.
    1405                 :             :  * @param[in]  cert_size             The size of certificate data in bytes.
    1406                 :             :  * @param[in]  base_asym_algo        SPDM base_asym_algo
    1407                 :             :  * @param[in]  pqc_asym_algo         SPDM pqc_asym_algo
    1408                 :             :  * @param[in]  is_requester_cert     Is the function verifying requester or responder cert.
    1409                 :             :  * @param[in]  cert_model            One of the SPDM_CERTIFICATE_INFO_CERT_MODEL_* macros.
    1410                 :             :  * @param[in]  set_cert              Is the function verifying a set certificate operation.
    1411                 :             :  *
    1412                 :             :  * @retval  true   Success.
    1413                 :             :  * @retval  false  Certificate is not valid.
    1414                 :             :  **/
    1415                 :         920 : static bool libspdm_x509_common_certificate_check(
    1416                 :             :     const uint8_t *cert, size_t cert_size,
    1417                 :             :     uint32_t base_asym_algo, uint32_t pqc_asym_algo,
    1418                 :             :     bool is_requester_cert, uint8_t cert_model,
    1419                 :             :     bool set_cert)
    1420                 :             : {
    1421                 :             :     uint8_t end_cert_from[64];
    1422                 :             :     size_t end_cert_from_len;
    1423                 :             :     uint8_t end_cert_to[64];
    1424                 :             :     size_t end_cert_to_len;
    1425                 :             :     size_t asn1_buffer_len;
    1426                 :             :     bool status;
    1427                 :             :     size_t cert_version;
    1428                 :             :     void *context;
    1429                 :             :     size_t signature_algo_oid_size;
    1430                 :             : 
    1431   [ +  -  -  + ]:         920 :     if (cert == NULL || cert_size == 0) {
    1432                 :           0 :         return false;
    1433                 :             :     }
    1434                 :             : 
    1435                 :         920 :     status = true;
    1436                 :         920 :     context = NULL;
    1437                 :         920 :     end_cert_from_len = 64;
    1438                 :         920 :     end_cert_to_len = 64;
    1439                 :             : 
    1440                 :             :     /* 1. Version */
    1441                 :         920 :     cert_version = 0;
    1442                 :         920 :     status = libspdm_x509_get_version(cert, cert_size, &cert_version);
    1443         [ -  + ]:         920 :     if (!status) {
    1444                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Version field is not present.\n"));
    1445                 :           0 :         goto cleanup;
    1446                 :             :     }
    1447         [ -  + ]:         920 :     if (cert_version != 2) {
    1448                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1449                 :             :                        "Expected Version to be equal to 2 but it is actually %zu.\n", cert_version));
    1450                 :           0 :         status = false;
    1451                 :           0 :         goto cleanup;
    1452                 :             :     }
    1453                 :             : 
    1454                 :             :     /* 2. Serial Number */
    1455                 :         920 :     asn1_buffer_len = 0;
    1456                 :         920 :     status = libspdm_x509_get_serial_number(cert, cert_size, NULL, &asn1_buffer_len);
    1457         [ -  + ]:         920 :     if (asn1_buffer_len == 0) {
    1458                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Serial Number field is not present.\n"));
    1459                 :           0 :         status = false;
    1460                 :           0 :         goto cleanup;
    1461                 :             :     }
    1462                 :             : 
    1463                 :             :     /* 3. Signature Algorithm */
    1464                 :         920 :     signature_algo_oid_size = 0;
    1465                 :         920 :     status = libspdm_x509_get_signature_algorithm(cert, cert_size, NULL, &signature_algo_oid_size);
    1466         [ -  + ]:         920 :     if (status) {
    1467   [ #  #  #  # ]:           0 :         if ((signature_algo_oid_size == 0) &&
    1468                 :             :             (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
    1469                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1470                 :             :                            "The mandatory Signature Algorithm field is not present.\n"));
    1471                 :           0 :             status = false;
    1472                 :           0 :             goto cleanup;
    1473                 :             :         }
    1474                 :             :     } else {
    1475         [ -  + ]:         920 :         if (signature_algo_oid_size == 0) {
    1476                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1477                 :             :                            "The mandatory Signature Algorithm field is not present.\n"));
    1478                 :           0 :             status = false;
    1479                 :           0 :             goto cleanup;
    1480                 :             :         }
    1481                 :             :     }
    1482                 :             : 
    1483                 :             :     /* 4. Verify public key algorithm.
    1484                 :             :      *    If this is a SET_CERTIFICATE operation and the endpoint uses the AliasCert model then the
    1485                 :             :      *    check should be skipped as the Device Certificate CA's public key does not have to use
    1486                 :             :      *    the same algorithms as the connection's negotiated algorithms. */
    1487   [ +  +  +  + ]:         920 :     if (!set_cert || (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT)) {
    1488                 :         913 :         status = libspdm_verify_cert_subject_public_key_info(cert, cert_size, base_asym_algo,
    1489                 :             :                                                              pqc_asym_algo);
    1490         [ +  + ]:         913 :         if (!status) {
    1491                 :           3 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1492                 :             :                            "Error in verifying the Public Key Algorithm field.\n"));
    1493                 :           3 :             goto cleanup;
    1494                 :             :         }
    1495                 :             :     }
    1496                 :             : 
    1497                 :             :     /* 5. Issuer */
    1498                 :         917 :     asn1_buffer_len = 0;
    1499                 :         917 :     status = libspdm_x509_get_issuer_name(cert, cert_size, NULL, &asn1_buffer_len);
    1500         [ -  + ]:         917 :     if (status) {
    1501   [ #  #  #  # ]:           0 :         if ((asn1_buffer_len == 0) &&
    1502                 :             :             (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
    1503                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Issuer field is not present.\n"));
    1504                 :           0 :             status = false;
    1505                 :           0 :             goto cleanup;
    1506                 :             :         }
    1507                 :             :     } else {
    1508         [ -  + ]:         917 :         if (asn1_buffer_len == 0) {
    1509                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Issuer field is not present.\n"));
    1510                 :           0 :             status = false;
    1511                 :           0 :             goto cleanup;
    1512                 :             :         }
    1513                 :             :     }
    1514                 :             : 
    1515                 :             :     /* 6. subject_name*/
    1516                 :         917 :     asn1_buffer_len = 0;
    1517                 :         917 :     status = libspdm_x509_get_subject_name(cert, cert_size, NULL, &asn1_buffer_len);
    1518         [ -  + ]:         917 :     if (status) {
    1519   [ #  #  #  # ]:           0 :         if ((asn1_buffer_len == 0) &&
    1520                 :             :             (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
    1521                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Subject field is not present.\n"));
    1522                 :           0 :             status = false;
    1523                 :           0 :             goto cleanup;
    1524                 :             :         }
    1525                 :             :     } else {
    1526         [ -  + ]:         917 :         if (asn1_buffer_len == 0) {
    1527                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Subject field is not present.\n"));
    1528                 :           0 :             status = false;
    1529                 :           0 :             goto cleanup;
    1530                 :             :         }
    1531                 :             :     }
    1532                 :             : 
    1533                 :             :     /* 7. Validity */
    1534                 :         917 :     status = libspdm_x509_get_validity(cert, cert_size, end_cert_from,
    1535                 :             :                                        &end_cert_from_len, end_cert_to,
    1536                 :             :                                        &end_cert_to_len);
    1537         [ +  - ]:         917 :     if (status) {
    1538   [ -  +  -  - ]:         917 :         if ((end_cert_from_len == 0) &&
    1539                 :             :             (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
    1540                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Validity field is not present.\n"));
    1541                 :           0 :             status = false;
    1542                 :           0 :             goto cleanup;
    1543                 :             :         }
    1544                 :             :     } else {
    1545         [ #  # ]:           0 :         if (end_cert_from_len == 0) {
    1546                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Validity field is not present.\n"));
    1547                 :           0 :             status = false;
    1548                 :           0 :             goto cleanup;
    1549                 :             :         }
    1550                 :             :     }
    1551                 :             : 
    1552         [ +  - ]:         917 :     if (end_cert_from_len != 0) {
    1553                 :         917 :         status = libspdm_internal_x509_date_time_check(
    1554                 :             :             end_cert_from, end_cert_from_len, end_cert_to, end_cert_to_len);
    1555         [ -  + ]:         917 :         if (!status) {
    1556                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1557                 :             :                            "The certificate is outside its validity period.\n"));
    1558                 :           0 :             goto cleanup;
    1559                 :             :         }
    1560                 :             :     }
    1561                 :             : 
    1562                 :             :     /* 8. Subject Public Key Info */
    1563         [ +  - ]:         917 :     if (base_asym_algo != 0) {
    1564                 :         917 :         status = libspdm_asym_get_public_key_from_x509(base_asym_algo, cert, cert_size, &context);
    1565                 :             :     }
    1566         [ -  + ]:         917 :     if (pqc_asym_algo != 0) {
    1567                 :           0 :         status = libspdm_pqc_asym_get_public_key_from_x509(pqc_asym_algo, cert, cert_size, &context);
    1568                 :             :     }
    1569         [ -  + ]:         917 :     if (!status) {
    1570                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1571                 :             :                        "The mandatory Subject Public Key Info field is not present.\n"));
    1572                 :           0 :         goto cleanup;
    1573                 :             :     }
    1574                 :             : 
    1575                 :             :     /* 9. Key Usage
    1576                 :             :      *    If this is a SET_CERTIFICATE operation and the endpoint uses the AliasCert model then the
    1577                 :             :      *    check should be skipped as the SPDM specification does not specify the presence or absence
    1578                 :             :      *    of the Device Certificate CA's keyUsage field. */
    1579   [ +  +  +  + ]:         917 :     if (!set_cert || (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT)) {
    1580                 :         910 :         size_t value = 0;
    1581                 :             : 
    1582                 :         910 :         status = libspdm_x509_get_key_usage(cert, cert_size, &value);
    1583         [ -  + ]:         910 :         if (!status) {
    1584                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "The mandatory Key Usage field is not present.\n"));
    1585                 :           0 :             goto cleanup;
    1586                 :             :         } else {
    1587         [ -  + ]:         910 :             if (value == 0) {
    1588         [ #  # ]:           0 :                 if (cert_model != SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT) {
    1589                 :           0 :                     status = false;
    1590                 :           0 :                     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1591                 :             :                                    "The mandatory Key Usage field is not present.\n"));
    1592                 :           0 :                     goto cleanup;
    1593                 :             :                 }
    1594                 :             :             } else {
    1595         [ -  + ]:         910 :                 if ((LIBSPDM_CRYPTO_X509_KU_DIGITAL_SIGNATURE & value) == 0) {
    1596                 :           0 :                     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1597                 :             :                                    "The Mandatory digital signature bit in Key Usage field is not set.\n"));
    1598                 :           0 :                     status = false;
    1599                 :           0 :                     goto cleanup;
    1600                 :             :                 }
    1601                 :             :             }
    1602                 :             :         }
    1603                 :             :     }
    1604                 :             : 
    1605                 :             :     /* 10. Extended Key Usage */
    1606                 :         917 :     status = libspdm_verify_leaf_cert_spdm_eku(cert, cert_size, is_requester_cert);
    1607         [ +  + ]:         917 :     if (!status) {
    1608                 :           2 :         goto cleanup;
    1609                 :             :     }
    1610                 :             : 
    1611   [ +  +  +  + ]:         915 :     if ((!set_cert) || (cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT)) {
    1612                 :             :         /* 11. verify spdm defined extension*/
    1613                 :         908 :         status = libspdm_verify_leaf_cert_spdm_extension(cert, cert_size,
    1614                 :             :                                                          is_requester_cert, cert_model);
    1615         [ +  + ]:         908 :         if (!status) {
    1616                 :           5 :             goto cleanup;
    1617                 :             :         }
    1618                 :             :     }
    1619                 :             : 
    1620                 :         910 : cleanup:
    1621         [ +  - ]:         920 :     if (base_asym_algo != 0) {
    1622                 :         920 :         libspdm_asym_free(base_asym_algo, context);
    1623                 :             :     }
    1624         [ -  + ]:         920 :     if (pqc_asym_algo != 0) {
    1625                 :           0 :         libspdm_pqc_asym_free(pqc_asym_algo, context);
    1626                 :             :     }
    1627                 :         920 :     return status;
    1628                 :             : }
    1629                 :             : 
    1630                 :         904 : bool libspdm_x509_certificate_check(
    1631                 :             :     uint8_t spdm_version,
    1632                 :             :     const uint8_t *cert, size_t cert_size,
    1633                 :             :     uint32_t base_asym_algo, uint32_t pqc_asym_algo, uint32_t base_hash_algo,
    1634                 :             :     bool is_requester, uint8_t cert_model)
    1635                 :             : {
    1636                 :             :     bool status;
    1637                 :             :     bool need_basic_constraints;
    1638                 :             : 
    1639                 :         904 :     status = libspdm_x509_common_certificate_check(
    1640                 :             :         cert, cert_size, base_asym_algo, pqc_asym_algo, is_requester, cert_model, false);
    1641         [ +  + ]:         904 :     if (!status) {
    1642                 :          10 :         return false;
    1643                 :             :     }
    1644                 :             : 
    1645         [ +  + ]:         894 :     if (spdm_version >= SPDM_MESSAGE_VERSION_13) {
    1646                 :             :         /* verify basic constraints: the leaf cert always is ca:false in get_cert
    1647                 :             :          * basic_constraints is mandatory in SPDM 1.3*/
    1648                 :          16 :         need_basic_constraints = true;
    1649                 :             :     } else {
    1650                 :             :         /* verify basic constraints: the leaf cert always is ca:false in get_cert*/
    1651                 :         878 :         need_basic_constraints = false;
    1652                 :             :     }
    1653                 :         894 :     status = libspdm_verify_leaf_cert_basic_constraints(cert, cert_size, need_basic_constraints);
    1654                 :         894 :     return status;
    1655                 :             : }
    1656                 :             : 
    1657                 :          16 : bool libspdm_x509_set_cert_certificate_check(
    1658                 :             :     uint8_t spdm_version,
    1659                 :             :     const uint8_t *cert, size_t cert_size,
    1660                 :             :     uint32_t base_asym_algo, uint32_t pqc_asym_algo, uint32_t base_hash_algo,
    1661                 :             :     bool is_requester, uint8_t cert_model)
    1662                 :             : {
    1663                 :             :     bool status;
    1664                 :             :     bool need_basic_constraints;
    1665                 :             : 
    1666                 :          16 :     status = libspdm_x509_common_certificate_check(
    1667                 :             :         cert, cert_size, base_asym_algo, pqc_asym_algo, is_requester, cert_model, true);
    1668         [ -  + ]:          16 :     if (!status) {
    1669                 :           0 :         return false;
    1670                 :             :     }
    1671                 :             : 
    1672                 :             :     /* verify basic constraints: need to check with cert_model*/
    1673         [ +  + ]:          16 :     if (spdm_version >= SPDM_MESSAGE_VERSION_13) {
    1674                 :           6 :         need_basic_constraints = true;
    1675                 :             :     } else {
    1676                 :          10 :         need_basic_constraints = false;
    1677                 :             :     }
    1678                 :          16 :     status = libspdm_verify_set_cert_leaf_cert_basic_constraints(
    1679                 :             :         cert, cert_size, cert_model, need_basic_constraints);
    1680                 :             : 
    1681                 :          16 :     return status;
    1682                 :             : }
    1683                 :             : 
    1684                 :         938 : bool libspdm_is_root_certificate(const uint8_t *cert, size_t cert_size)
    1685                 :             : {
    1686                 :             :     uint8_t issuer_name[LIBSPDM_MAX_NAME_SIZE];
    1687                 :             :     size_t issuer_name_len;
    1688                 :             :     uint8_t subject_name[LIBSPDM_MAX_NAME_SIZE];
    1689                 :             :     size_t subject_name_len;
    1690                 :             :     bool result;
    1691                 :             :     uint8_t cert_basic_constraints[LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN];
    1692                 :             :     size_t cert_basic_constraints_len;
    1693                 :         938 :     const uint8_t basic_constraints_true_case[] = BASIC_CONSTRAINTS_CA_TRUE;
    1694                 :             : 
    1695   [ +  -  -  + ]:         938 :     if (cert == NULL || cert_size == 0) {
    1696                 :           0 :         return false;
    1697                 :             :     }
    1698                 :             : 
    1699                 :             :     /* 1. issuer_name*/
    1700                 :         938 :     issuer_name_len = sizeof(issuer_name);
    1701                 :         938 :     result = libspdm_x509_get_issuer_name(cert, cert_size, issuer_name, &issuer_name_len);
    1702         [ -  + ]:         938 :     if (!result) {
    1703                 :           0 :         return false;
    1704                 :             :     }
    1705                 :             : 
    1706                 :             :     /* 2. subject_name*/
    1707                 :         938 :     subject_name_len = sizeof(subject_name);
    1708                 :         938 :     result = libspdm_x509_get_subject_name(cert, cert_size, subject_name, &subject_name_len);
    1709         [ -  + ]:         938 :     if (!result) {
    1710                 :           0 :         return false;
    1711                 :             :     }
    1712                 :             : 
    1713         [ +  + ]:         938 :     if (issuer_name_len != subject_name_len) {
    1714                 :          11 :         return false;
    1715                 :             :     }
    1716         [ -  + ]:         927 :     if (!libspdm_consttime_is_mem_equal(issuer_name, subject_name, issuer_name_len)) {
    1717                 :           0 :         return false;
    1718                 :             :     }
    1719                 :             : 
    1720                 :             :     /* 3. cA must be present in Basic Constraints */
    1721                 :         927 :     cert_basic_constraints_len = LIBSPDM_MAX_BASIC_CONSTRAINTS_CA_LEN;
    1722                 :         927 :     result = libspdm_x509_get_extended_basic_constraints(cert, cert_size,
    1723                 :             :                                                          cert_basic_constraints,
    1724                 :             :                                                          &cert_basic_constraints_len);
    1725         [ -  + ]:         927 :     if (!result) {
    1726                 :           0 :         return false;
    1727                 :             :     }
    1728                 :             : 
    1729         [ +  - ]:         927 :     if ((cert_basic_constraints_len < sizeof(basic_constraints_true_case) ||
    1730         [ -  + ]:         927 :          (cert_basic_constraints[0] != basic_constraints_true_case[0]))) {
    1731                 :           0 :         return false;
    1732                 :             :     }
    1733         [ -  + ]:         927 :     if (!libspdm_consttime_is_mem_equal(&cert_basic_constraints[2],
    1734                 :             :                                         &basic_constraints_true_case[2],
    1735                 :             :                                         sizeof(basic_constraints_true_case) - 2)) {
    1736                 :           0 :         return false;
    1737                 :             :     }
    1738                 :             : 
    1739                 :             :     /* 4. certificate must be self-signed */
    1740                 :         927 :     result = libspdm_x509_verify_cert(cert, cert_size, cert, cert_size);
    1741         [ +  + ]:         927 :     if (!result) {
    1742                 :           1 :         return false;
    1743                 :             :     }
    1744                 :             : 
    1745                 :         926 :     return true;
    1746                 :             : }
    1747                 :             : 
    1748                 :           9 : bool libspdm_get_dmtf_subject_alt_name_from_bytes(
    1749                 :             :     uint8_t *buffer, size_t len, char *name_buffer,
    1750                 :             :     size_t *name_buffer_size, uint8_t *oid,
    1751                 :             :     size_t *oid_size)
    1752                 :             : {
    1753                 :             :     uint8_t *ptr;
    1754                 :             :     int32_t length;
    1755                 :             :     size_t obj_len;
    1756                 :             :     int32_t ret;
    1757                 :             : 
    1758                 :             :     /*copy mem variable*/
    1759                 :             :     volatile uint8_t* dst;
    1760                 :             :     const volatile uint8_t* src;
    1761                 :             :     size_t dst_len;
    1762                 :             :     size_t src_len;
    1763                 :             : 
    1764                 :           9 :     length = (int32_t)len;
    1765                 :           9 :     ptr = buffer;
    1766                 :           9 :     obj_len = 0;
    1767                 :             : 
    1768                 :             :     /* Sequence*/
    1769                 :           9 :     ret = libspdm_asn1_get_tag(&ptr, ptr + length, &obj_len,
    1770                 :             :                                LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    1771         [ -  + ]:           9 :     if (!ret) {
    1772                 :           0 :         return false;
    1773                 :             :     }
    1774                 :             : 
    1775                 :           9 :     ret = libspdm_asn1_get_tag(&ptr, ptr + obj_len, &obj_len,
    1776                 :             :                                LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC |
    1777                 :             :                                LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    1778                 :             : 
    1779                 :           9 :     ret = libspdm_asn1_get_tag(&ptr, ptr + obj_len, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);
    1780         [ -  + ]:           9 :     if (!ret) {
    1781                 :           0 :         return false;
    1782                 :             :     }
    1783                 :             :     /* CopyData to OID*/
    1784         [ -  + ]:           9 :     if (*oid_size < (size_t)obj_len) {
    1785                 :           0 :         *oid_size = (size_t)obj_len;
    1786                 :           0 :         return false;
    1787                 :             :     }
    1788         [ +  - ]:           9 :     if (oid != NULL) {
    1789                 :           9 :         libspdm_copy_mem(oid, *oid_size, ptr, obj_len);
    1790                 :           9 :         *oid_size = obj_len;
    1791                 :             :     }
    1792                 :             : 
    1793                 :             :     /* Move to next element*/
    1794                 :           9 :     ptr += obj_len;
    1795                 :             : 
    1796                 :           9 :     ret = libspdm_asn1_get_tag(&ptr, (uint8_t *)(buffer + length), &obj_len,
    1797                 :             :                                LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC |
    1798                 :             :                                LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    1799                 :           9 :     ret = libspdm_asn1_get_tag(&ptr, (uint8_t *)(buffer + length), &obj_len,
    1800                 :             :                                LIBSPDM_CRYPTO_ASN1_UTF8_STRING);
    1801         [ -  + ]:           9 :     if (!ret) {
    1802                 :           0 :         return false;
    1803                 :             :     }
    1804                 :             : 
    1805         [ -  + ]:           9 :     if (*name_buffer_size < (size_t)obj_len + 1) {
    1806                 :           0 :         *name_buffer_size = (size_t)obj_len + 1;
    1807                 :           0 :         return false;
    1808                 :             :     }
    1809                 :             : 
    1810                 :             :     /* the src and dst address are overlap,
    1811                 :             :      * When the function is called by libspdm_get_dmtf_subject_alt_name.
    1812                 :             :      * libspdm_copy_mem can not be used. */
    1813   [ +  -  +  - ]:           9 :     if ((name_buffer != NULL) && (ptr != NULL)) {
    1814                 :           9 :         dst = (volatile uint8_t*) name_buffer;
    1815                 :           9 :         src = (const volatile uint8_t*) ptr;
    1816                 :           9 :         dst_len = *name_buffer_size;
    1817                 :           9 :         src_len = obj_len;
    1818                 :             : 
    1819                 :             :         /* Check for case where "dst_len" may be invalid. Do not zero "dst" in this case. */
    1820         [ -  + ]:           9 :         if (dst_len > (SIZE_MAX >> 1)) {
    1821                 :           0 :             LIBSPDM_ASSERT(0);
    1822                 :           0 :             return false;
    1823                 :             :         }
    1824                 :             : 
    1825                 :             :         /* Guard against invalid lengths. Zero "dst" in these cases. */
    1826         [ +  - ]:           9 :         if (src_len > dst_len ||
    1827         [ -  + ]:           9 :             src_len > (SIZE_MAX >> 1)) {
    1828                 :           0 :             libspdm_zero_mem(name_buffer, dst_len);
    1829                 :           0 :             LIBSPDM_ASSERT(0);
    1830                 :           0 :             return false;
    1831                 :             :         }
    1832                 :             : 
    1833         [ +  + ]:         207 :         while (src_len-- != 0) {
    1834                 :         198 :             *(dst++) = *(src++);
    1835                 :             :         }
    1836                 :             : 
    1837                 :             :         /*encode name buffer to string*/
    1838                 :           9 :         *name_buffer_size = obj_len + 1;
    1839                 :           9 :         name_buffer[obj_len] = 0;
    1840                 :           9 :         return true;
    1841                 :             :     }
    1842                 :             : 
    1843                 :           0 :     return false;
    1844                 :             : }
    1845                 :             : 
    1846                 :           6 : bool libspdm_get_dmtf_subject_alt_name(const uint8_t *cert, size_t cert_size,
    1847                 :             :                                        char *name_buffer,
    1848                 :             :                                        size_t *name_buffer_size,
    1849                 :             :                                        uint8_t *oid, size_t *oid_size)
    1850                 :             : {
    1851                 :             :     bool status;
    1852                 :             :     size_t extension_data_size;
    1853                 :           6 :     uint8_t oid_subject_alt_name[] = { 0x55, 0x1D, 0x11 };
    1854                 :             : 
    1855                 :           6 :     extension_data_size = 0;
    1856                 :           6 :     status = libspdm_x509_get_extension_data(cert, cert_size,
    1857                 :             :                                              oid_subject_alt_name,
    1858                 :             :                                              sizeof(oid_subject_alt_name), NULL,
    1859                 :             :                                              &extension_data_size);
    1860   [ +  -  -  + ]:           6 :     if (status || (extension_data_size == 0)) {
    1861                 :           0 :         *name_buffer_size = 0;
    1862                 :           0 :         return false;
    1863                 :             :     }
    1864         [ -  + ]:           6 :     if (extension_data_size > *name_buffer_size) {
    1865                 :           0 :         *name_buffer_size = extension_data_size;
    1866                 :           0 :         return false;
    1867                 :             :     }
    1868                 :             :     status =
    1869                 :           6 :         libspdm_x509_get_extension_data(cert, cert_size,
    1870                 :             :                                         oid_subject_alt_name,
    1871                 :             :                                         sizeof(oid_subject_alt_name),
    1872                 :             :                                         (uint8_t *)name_buffer, name_buffer_size);
    1873         [ -  + ]:           6 :     if (!status) {
    1874                 :           0 :         return status;
    1875                 :             :     }
    1876                 :             : 
    1877                 :           6 :     return libspdm_get_dmtf_subject_alt_name_from_bytes(
    1878                 :             :         (uint8_t *)name_buffer, *name_buffer_size, name_buffer,
    1879                 :             :         name_buffer_size, oid, oid_size);
    1880                 :             : }
    1881                 :             : 
    1882                 :         838 : bool libspdm_verify_cert_chain_data(
    1883                 :             :     uint8_t spdm_version,
    1884                 :             :     uint8_t *cert_chain_data, size_t cert_chain_data_size,
    1885                 :             :     uint32_t base_asym_algo, uint32_t pqc_asym_algo, uint32_t base_hash_algo,
    1886                 :             :     bool is_requester_cert, uint8_t cert_model)
    1887                 :             : {
    1888                 :             :     const uint8_t *root_cert_buffer;
    1889                 :             :     size_t root_cert_buffer_size;
    1890                 :             :     const uint8_t *leaf_cert_buffer;
    1891                 :             :     size_t leaf_cert_buffer_size;
    1892                 :             : 
    1893         [ -  + ]:         838 :     if (cert_chain_data_size >
    1894                 :             :         SPDM_MAX_CERTIFICATE_CHAIN_SIZE - (sizeof(spdm_cert_chain_t) + LIBSPDM_MAX_HASH_SIZE)) {
    1895                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1896                 :             :                        "!!! VerifyCertificateChainData - FAIL (chain size too large) !!!\n"));
    1897                 :           0 :         return false;
    1898                 :             :     }
    1899                 :             : 
    1900         [ -  + ]:         838 :     if (!libspdm_x509_get_cert_from_cert_chain(
    1901                 :             :             cert_chain_data, cert_chain_data_size, 0, &root_cert_buffer,
    1902                 :             :             &root_cert_buffer_size)) {
    1903                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1904                 :             :                        "!!! VerifyCertificateChainData - FAIL (get root certificate failed)!!!\n"));
    1905                 :           0 :         return false;
    1906                 :             :     }
    1907                 :             : 
    1908         [ +  + ]:         838 :     if (!libspdm_x509_verify_cert_chain(root_cert_buffer, root_cert_buffer_size,
    1909                 :             :                                         cert_chain_data, cert_chain_data_size)) {
    1910                 :           2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1911                 :             :                        "!!! VerifyCertificateChainData - FAIL (cert chain verify failed)!!!\n"));
    1912                 :           2 :         return false;
    1913                 :             :     }
    1914                 :             : 
    1915         [ -  + ]:         836 :     if (!libspdm_x509_get_cert_from_cert_chain(
    1916                 :             :             cert_chain_data, cert_chain_data_size, -1,
    1917                 :             :             &leaf_cert_buffer, &leaf_cert_buffer_size)) {
    1918                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1919                 :             :                        "!!! VerifyCertificateChainData - FAIL (get leaf certificate failed)!!!\n"));
    1920                 :           0 :         return false;
    1921                 :             :     }
    1922                 :             : 
    1923         [ +  + ]:         836 :     if (!libspdm_x509_certificate_check(spdm_version,
    1924                 :             :                                         leaf_cert_buffer, leaf_cert_buffer_size,
    1925                 :             :                                         base_asym_algo, pqc_asym_algo, base_hash_algo,
    1926                 :             :                                         is_requester_cert, cert_model)) {
    1927                 :           1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1928                 :             :                        "!!! VerifyCertificateChainData - FAIL (leaf certificate check failed)!!!\n"));
    1929                 :           1 :         return false;
    1930                 :             :     }
    1931                 :             : 
    1932                 :         835 :     return true;
    1933                 :             : }
    1934                 :             : 
    1935                 :          46 : bool libspdm_verify_certificate_chain_buffer(
    1936                 :             :     uint8_t spdm_version,
    1937                 :             :     uint32_t base_hash_algo, uint32_t base_asym_algo, uint32_t pqc_asym_algo,
    1938                 :             :     const void *cert_chain_buffer,
    1939                 :             :     size_t cert_chain_buffer_size,
    1940                 :             :     bool is_requester_cert, uint8_t cert_model)
    1941                 :             : {
    1942                 :             :     const uint8_t *cert_chain_data;
    1943                 :             :     size_t cert_chain_data_size;
    1944                 :             :     const uint8_t *first_cert_buffer;
    1945                 :             :     size_t first_cert_buffer_size;
    1946                 :             :     size_t hash_size;
    1947                 :             :     uint8_t calc_root_cert_hash[LIBSPDM_MAX_HASH_SIZE];
    1948                 :             :     const uint8_t *leaf_cert_buffer;
    1949                 :             :     size_t leaf_cert_buffer_size;
    1950                 :             :     bool result;
    1951                 :             :     const spdm_cert_chain_t *cert_chain_header;
    1952                 :             : 
    1953                 :          46 :     hash_size = libspdm_get_hash_size(base_hash_algo);
    1954                 :             : 
    1955         [ -  + ]:          46 :     if (cert_chain_buffer_size <= sizeof(spdm_cert_chain_t) + hash_size) {
    1956                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1957                 :             :                        "!!! VerifyCertificateChainBuffer - FAIL (buffer too small) !!!\n"));
    1958                 :           0 :         return false;
    1959                 :             :     }
    1960                 :             : 
    1961                 :          46 :     cert_chain_header = cert_chain_buffer;
    1962         [ +  + ]:          46 :     if (cert_chain_header->length != cert_chain_buffer_size) {
    1963                 :           3 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1964                 :             :                        "!!! VerifyCertificateChainBuffer - FAIL (cert_chain->length mismatch) !!!\n"));
    1965                 :           3 :         return false;
    1966                 :             :     }
    1967                 :             : 
    1968                 :          43 :     cert_chain_data = (const uint8_t *)cert_chain_buffer + sizeof(spdm_cert_chain_t) + hash_size;
    1969                 :          43 :     cert_chain_data_size = cert_chain_buffer_size - sizeof(spdm_cert_chain_t) - hash_size;
    1970         [ +  + ]:          43 :     if (!libspdm_x509_get_cert_from_cert_chain(
    1971                 :             :             cert_chain_data, cert_chain_data_size, 0, &first_cert_buffer,
    1972                 :             :             &first_cert_buffer_size)) {
    1973                 :           2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1974                 :             :                        "!!! VerifyCertificateChainBuffer - FAIL (get root certificate failed)!!!\n"));
    1975                 :           2 :         return false;
    1976                 :             :     }
    1977                 :             : 
    1978         [ +  + ]:          41 :     if (libspdm_is_root_certificate(first_cert_buffer, first_cert_buffer_size)) {
    1979                 :          38 :         result = libspdm_hash_all(base_hash_algo, first_cert_buffer, first_cert_buffer_size,
    1980                 :             :                                   calc_root_cert_hash);
    1981         [ -  + ]:          38 :         if (!result) {
    1982                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1983                 :             :                            "!!! VerifyCertificateChainBuffer - FAIL (hash calculation fail) !!!\n"));
    1984                 :           0 :             return false;
    1985                 :             :         }
    1986         [ -  + ]:          38 :         if (!libspdm_consttime_is_mem_equal((const uint8_t *)cert_chain_buffer +
    1987                 :             :                                             sizeof(spdm_cert_chain_t),
    1988                 :             :                                             calc_root_cert_hash, hash_size)) {
    1989                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1990                 :             :                            "!!! VerifyCertificateChainBuffer - FAIL (cert root hash mismatch) !!!\n"));
    1991                 :           0 :             return false;
    1992                 :             :         }
    1993                 :          38 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1994                 :             :                        "!!! VerifyCertificateChainBuffer - PASS (cert root hash match) !!!\n"));
    1995                 :             :     }
    1996                 :             : 
    1997                 :             :     /*If the number of certificates in the certificate chain is more than 1,
    1998                 :             :      * other certificates need to be verified.*/
    1999         [ +  - ]:          41 :     if (cert_chain_data_size > first_cert_buffer_size) {
    2000         [ +  + ]:          41 :         if (!libspdm_x509_verify_cert_chain(first_cert_buffer, first_cert_buffer_size,
    2001                 :             :                                             cert_chain_data + first_cert_buffer_size,
    2002                 :             :                                             cert_chain_data_size - first_cert_buffer_size)) {
    2003                 :           3 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    2004                 :             :                            "!!! VerifyCertificateChainBuffer - FAIL (cert chain verify failed)!!!\n"));
    2005                 :           3 :             return false;
    2006                 :             :         }
    2007                 :             :     }
    2008                 :             : 
    2009         [ -  + ]:          38 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2010                 :             :             cert_chain_data, cert_chain_data_size, -1,
    2011                 :             :             &leaf_cert_buffer, &leaf_cert_buffer_size)) {
    2012                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    2013                 :             :                        "!!! VerifyCertificateChainBuffer - FAIL (get leaf certificate failed)!!!\n"));
    2014                 :           0 :         return false;
    2015                 :             :     }
    2016                 :             : 
    2017         [ +  + ]:          38 :     if (!libspdm_x509_certificate_check(spdm_version,
    2018                 :             :                                         leaf_cert_buffer, leaf_cert_buffer_size,
    2019                 :             :                                         base_asym_algo, pqc_asym_algo, base_hash_algo,
    2020                 :             :                                         is_requester_cert, cert_model)) {
    2021                 :           3 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    2022                 :             :                        "!!! VerifyCertificateChainBuffer - FAIL (leaf certificate check failed)!!!\n"));
    2023                 :           3 :         return false;
    2024                 :             :     }
    2025                 :             : 
    2026                 :          35 :     return true;
    2027                 :             : }
    2028                 :             : 
    2029                 :         291 : bool libspdm_get_leaf_cert_public_key_from_cert_chain(uint32_t base_hash_algo,
    2030                 :             :                                                       uint32_t base_asym_alg,
    2031                 :             :                                                       uint8_t *cert_chain_data,
    2032                 :             :                                                       size_t cert_chain_data_size,
    2033                 :             :                                                       void **public_key)
    2034                 :             : {
    2035                 :             :     size_t hash_size;
    2036                 :             :     const uint8_t *cert_buffer;
    2037                 :             :     size_t cert_buffer_size;
    2038                 :             :     bool result;
    2039                 :             : 
    2040                 :         291 :     hash_size = libspdm_get_hash_size(base_hash_algo);
    2041                 :             : 
    2042                 :         291 :     cert_chain_data = cert_chain_data + sizeof(spdm_cert_chain_t) + hash_size;
    2043                 :         291 :     cert_chain_data_size = cert_chain_data_size - (sizeof(spdm_cert_chain_t) + hash_size);
    2044                 :             : 
    2045                 :             :     /* Get leaf cert from cert chain */
    2046                 :         291 :     result = libspdm_x509_get_cert_from_cert_chain(cert_chain_data,
    2047                 :             :                                                    cert_chain_data_size, -1,
    2048                 :             :                                                    &cert_buffer, &cert_buffer_size);
    2049         [ +  + ]:         291 :     if (!result) {
    2050                 :           2 :         return false;
    2051                 :             :     }
    2052                 :             : 
    2053                 :         289 :     result = libspdm_asym_get_public_key_from_x509(
    2054                 :             :         base_asym_alg,
    2055                 :             :         cert_buffer, cert_buffer_size, public_key);
    2056         [ +  + ]:         289 :     if (!result) {
    2057                 :           4 :         return false;
    2058                 :             :     }
    2059                 :             : 
    2060                 :         285 :     return true;
    2061                 :             : }
    2062                 :             : 
    2063                 :           0 : bool libspdm_get_pqc_leaf_cert_public_key_from_cert_chain(uint32_t base_hash_algo,
    2064                 :             :                                                           uint32_t pqc_asym_alg,
    2065                 :             :                                                           uint8_t *cert_chain_data,
    2066                 :             :                                                           size_t cert_chain_data_size,
    2067                 :             :                                                           void **public_key)
    2068                 :             : {
    2069                 :             :     size_t hash_size;
    2070                 :             :     const uint8_t *cert_buffer;
    2071                 :             :     size_t cert_buffer_size;
    2072                 :             :     bool result;
    2073                 :             : 
    2074                 :           0 :     hash_size = libspdm_get_hash_size(base_hash_algo);
    2075                 :             : 
    2076                 :           0 :     cert_chain_data = cert_chain_data + sizeof(spdm_cert_chain_t) + hash_size;
    2077                 :           0 :     cert_chain_data_size = cert_chain_data_size - (sizeof(spdm_cert_chain_t) + hash_size);
    2078                 :             : 
    2079                 :             :     /* Get leaf cert from cert chain */
    2080                 :           0 :     result = libspdm_x509_get_cert_from_cert_chain(cert_chain_data,
    2081                 :             :                                                    cert_chain_data_size, -1,
    2082                 :             :                                                    &cert_buffer, &cert_buffer_size);
    2083         [ #  # ]:           0 :     if (!result) {
    2084                 :           0 :         return false;
    2085                 :             :     }
    2086                 :             : 
    2087                 :           0 :     result = libspdm_pqc_asym_get_public_key_from_x509(
    2088                 :             :         pqc_asym_alg,
    2089                 :             :         cert_buffer, cert_buffer_size, public_key);
    2090         [ #  # ]:           0 :     if (!result) {
    2091                 :           0 :         return false;
    2092                 :             :     }
    2093                 :             : 
    2094                 :           0 :     return true;
    2095                 :             : }
    2096                 :             : 
    2097                 :          29 : bool libspdm_verify_req_info(uint8_t *req_info, uint16_t req_info_len)
    2098                 :             : {
    2099                 :             :     bool ret;
    2100                 :             :     uint8_t *ptr;
    2101                 :             :     int32_t length;
    2102                 :             :     size_t obj_len;
    2103                 :             :     uint8_t *end;
    2104                 :             : 
    2105                 :          29 :     length = (int32_t)req_info_len;
    2106                 :          29 :     ptr = req_info;
    2107                 :          29 :     obj_len = 0;
    2108                 :          29 :     end = ptr + length;
    2109                 :          29 :     ret = true;
    2110                 :             : 
    2111         [ +  + ]:          29 :     if (req_info_len == 0) {
    2112                 :           4 :         return true;
    2113                 :             :     }
    2114                 :             : 
    2115                 :             :     /*req_info sequence*/
    2116                 :          25 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
    2117                 :             :                                LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    2118         [ +  + ]:          25 :     if (!ret) {
    2119                 :           2 :         return false;
    2120                 :             :     }
    2121                 :             : 
    2122                 :             :     /*integer:version*/
    2123                 :          23 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len, LIBSPDM_CRYPTO_ASN1_INTEGER);
    2124         [ -  + ]:          23 :     if (!ret) {
    2125                 :           0 :         return false;
    2126                 :             :     } else {
    2127                 :          23 :         ptr += obj_len;
    2128                 :             :     }
    2129                 :             : 
    2130                 :             :     /*sequence:subject name*/
    2131                 :          23 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
    2132                 :             :                                LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    2133         [ -  + ]:          23 :     if (!ret) {
    2134                 :           0 :         return false;
    2135                 :             :     } else {
    2136                 :          23 :         ptr += obj_len;
    2137                 :             :     }
    2138                 :             : 
    2139                 :             :     /*sequence:subject pkinfo*/
    2140                 :          23 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
    2141                 :             :                                LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    2142         [ -  + ]:          23 :     if (!ret) {
    2143                 :           0 :         return false;
    2144                 :             :     } else {
    2145                 :          23 :         ptr += obj_len;
    2146                 :             :     }
    2147                 :             : 
    2148                 :             :     /*[0]: attributes*/
    2149                 :          23 :     ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
    2150                 :             :                                LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC |
    2151                 :             :                                LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    2152                 :             :     /*req_info format error, don't have attributes tag*/
    2153         [ -  + ]:          23 :     if (!ret) {
    2154                 :           0 :         return false;
    2155                 :             :     }
    2156                 :             : 
    2157                 :             :     /*there is no attributes object*/
    2158         [ -  + ]:          23 :     if (ptr == end) {
    2159                 :           0 :         return true;
    2160                 :             :     }
    2161                 :             : 
    2162                 :             :     /*there is some attributes object: 0,1,2 ...*/
    2163         [ +  - ]:          46 :     while (ret)
    2164                 :             :     {
    2165                 :          46 :         ret = libspdm_asn1_get_tag(&ptr, end, &obj_len,
    2166                 :             :                                    LIBSPDM_CRYPTO_ASN1_SEQUENCE |
    2167                 :             :                                    LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
    2168         [ +  + ]:          46 :         if (ret) {
    2169                 :          23 :             ptr += obj_len;
    2170                 :             :         } else {
    2171                 :          23 :             break;
    2172                 :             :         }
    2173                 :             :     }
    2174                 :             : 
    2175         [ +  - ]:          23 :     if (ptr == end) {
    2176                 :          23 :         return true;
    2177                 :             :     } else {
    2178                 :           0 :         return false;
    2179                 :             :     }
    2180                 :             : }
    2181                 :             : 
    2182                 :             : #endif
        

Generated by: LCOV version 2.0-1