LCOV - code coverage report
Current view: top level - os_stub/spdm_device_secret_lib_sample - csr.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 67.9 % 190 129
Test Date: 2025-09-14 08:11:04 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2024 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : #include <stdarg.h>
       8              : #include <stddef.h>
       9              : #include <setjmp.h>
      10              : #include <stdint.h>
      11              : #include <stdlib.h>
      12              : #include <stdio.h>
      13              : #include <assert.h>
      14              : #include <string.h>
      15              : 
      16              : #include <base.h>
      17              : #include "library/memlib.h"
      18              : #include "spdm_device_secret_lib_internal.h"
      19              : #include "internal/libspdm_common_lib.h"
      20              : 
      21              : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
      22           19 : bool libspdm_read_cached_last_csr_request(uint8_t **last_csr_request,
      23              :                                           size_t *last_csr_request_len,
      24              :                                           uint8_t req_csr_tracking_tag,
      25              :                                           uint8_t *available_rsp_csr_tracking_tag)
      26              : {
      27              :     bool res;
      28              :     uint8_t index;
      29              :     size_t file_size;
      30              :     uint8_t *file_data;
      31              : 
      32           19 :     file_data = NULL;
      33           19 :     *available_rsp_csr_tracking_tag = 0;
      34           19 :     char file[] = "cached_last_csr_x_request";
      35              :     /*change the file name, for example: cached_last_csr_1_request*/
      36           19 :     file[16] = (char)(req_csr_tracking_tag + '0');
      37           19 :     res = libspdm_read_input_file(file, (void **)last_csr_request, last_csr_request_len);
      38              : 
      39          152 :     for (index = 1; index <= SPDM_MAX_CSR_TRACKING_TAG; index++) {
      40          133 :         file[16] = (char)(index + '0');
      41          133 :         libspdm_read_input_file(file, (void **)(&file_data), &file_size);
      42          133 :         if (file_size == 0) {
      43           85 :             *available_rsp_csr_tracking_tag |=  (1 << index);
      44              :         } else {
      45           48 :             if (file_data != NULL) {
      46           35 :                 free(file_data);
      47              :             }
      48              :         }
      49              :     }
      50              : 
      51           19 :     return res;
      52              : }
      53              : 
      54           13 : bool libspdm_cache_last_csr_request(const uint8_t *last_csr_request,
      55              :                                     size_t last_csr_request_len,
      56              :                                     uint8_t req_csr_tracking_tag)
      57              : {
      58              :     bool res;
      59              : 
      60           13 :     char file[] = "cached_last_csr_x_request";
      61              :     /*change the file name, for example: cached_last_csr_1_request*/
      62           13 :     file[16] = (char)(req_csr_tracking_tag + '0');
      63           13 :     res = libspdm_write_output_file(file, last_csr_request, last_csr_request_len);
      64              : 
      65           13 :     return res;
      66              : }
      67              : 
      68              : /*clean the cached last SPDM csr request*/
      69            1 : bool libspdm_discard_all_cached_last_request()
      70              : {
      71              :     uint8_t index;
      72              : 
      73            1 :     char file[] = "cached_last_csr_x_request";
      74              : 
      75            8 :     for (index = 1; index <= SPDM_MAX_CSR_TRACKING_TAG; index++) {
      76            7 :         file[16] = (char)(index + '0');
      77            7 :         if (!libspdm_write_output_file(file, NULL, 0)) {
      78            0 :             return false;
      79              :         }
      80              :     }
      81              : 
      82            1 :     return true;
      83              : }
      84              : 
      85              : /*
      86              :  * return true represent that: the device complete the csr by reset successfully
      87              :  * return false represent that: the device complete the csr need reset
      88              :  **/
      89            4 : bool libspdm_read_cached_csr(uint8_t **csr_pointer, size_t *csr_len)
      90              : {
      91              :     bool res;
      92              :     char *file;
      93              : 
      94            4 :     file = "test_csr/cached.csr";
      95              : 
      96            4 :     res = libspdm_read_input_file(file, (void **)csr_pointer, csr_len);
      97            4 :     return res;
      98              : }
      99              : 
     100            6 : bool libspdm_gen_csr_without_reset(uint32_t base_hash_algo, uint32_t base_asym_algo,
     101              :                                    uint32_t pqc_asym_algo,
     102              :                                    uint8_t *requester_info, size_t requester_info_length,
     103              :                                    uint8_t *opaque_data, uint16_t opaque_data_length,
     104              :                                    size_t *csr_len, uint8_t *csr_pointer,
     105              :                                    bool is_device_cert_model)
     106              : {
     107              :     bool result;
     108              :     size_t hash_nid;
     109              :     size_t asym_nid;
     110              :     size_t pqc_asym_nid;
     111              :     void *context;
     112              :     size_t csr_buffer_size;
     113              : 
     114            6 :     csr_buffer_size = *csr_len;
     115              : 
     116              : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
     117            6 :     if (g_private_key_mode) {
     118              :         void *x509_ca_cert;
     119              :         void *prikey, *cert;
     120              :         size_t prikey_size, cert_size;
     121              : 
     122            6 :         if (pqc_asym_algo != 0) {
     123            0 :             result = libspdm_read_responder_pqc_private_key(
     124              :                 pqc_asym_algo, &prikey, &prikey_size);
     125              :         } else {
     126            6 :             result = libspdm_read_responder_private_key(
     127              :                 base_asym_algo, &prikey, &prikey_size);
     128              :         }
     129            6 :         if (!result) {
     130            0 :             return false;
     131              :         }
     132              : 
     133            6 :         if (pqc_asym_algo != 0) {
     134            0 :             result = libspdm_read_responder_pqc_certificate(
     135              :                 pqc_asym_algo, &cert, &cert_size);
     136              :         } else {
     137            6 :             result = libspdm_read_responder_certificate(
     138              :                 base_asym_algo, &cert, &cert_size);
     139              :         }
     140            6 :         if (!result) {
     141            0 :             return false;
     142              :         }
     143              : 
     144            6 :         result = libspdm_x509_construct_certificate(cert, cert_size,
     145              :                                                     (uint8_t **)&x509_ca_cert);
     146            6 :         if ((x509_ca_cert == NULL) || (!result)) {
     147            0 :             return false;
     148              :         }
     149              : 
     150            6 :         if (pqc_asym_algo != 0) {
     151            0 :             result = libspdm_pqc_asym_get_private_key_from_pem(
     152              :                 pqc_asym_algo, prikey, prikey_size, NULL, &context);
     153              :         } else {
     154            6 :             result = libspdm_asym_get_private_key_from_pem(
     155              :                 base_asym_algo, prikey, prikey_size, NULL, &context);
     156              :         }
     157            6 :         if (!result) {
     158            0 :             libspdm_zero_mem(prikey, prikey_size);
     159            0 :             free(prikey);
     160            0 :             return false;
     161              :         }
     162            6 :         hash_nid = libspdm_get_hash_nid(base_hash_algo);
     163            6 :         asym_nid = libspdm_get_aysm_nid(base_asym_algo);
     164            6 :         pqc_asym_nid = libspdm_get_pqc_aysm_nid(pqc_asym_algo);
     165              : 
     166            6 :         char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
     167              : 
     168            6 :         if (pqc_asym_algo != 0) {
     169            0 :             result = libspdm_gen_x509_csr_with_pqc(hash_nid, 0, pqc_asym_nid,
     170              :                                                    requester_info, requester_info_length,
     171            0 :                                                    !is_device_cert_model,
     172              :                                                    context, subject_name,
     173              :                                                    csr_len, csr_pointer,
     174            0 :                                                    x509_ca_cert);
     175            0 :             libspdm_pqc_asym_free(pqc_asym_algo, context);
     176              :         } else {
     177            6 :             result = libspdm_gen_x509_csr(hash_nid, asym_nid,
     178              :                                           requester_info, requester_info_length,
     179            6 :                                           !is_device_cert_model,
     180              :                                           context, subject_name,
     181              :                                           csr_len, csr_pointer,
     182            6 :                                           x509_ca_cert);
     183            6 :             libspdm_asym_free(base_asym_algo, context);
     184              :         }
     185            6 :         libspdm_zero_mem(prikey, prikey_size);
     186            6 :         free(prikey);
     187            6 :         free(cert);
     188              :     } else {
     189              : #endif
     190              :     void *x509_ca_cert;
     191              :     void *cert;
     192              :     size_t cert_size;
     193              : 
     194            0 :     if (pqc_asym_algo != 0) {
     195            0 :         result = libspdm_get_responder_pqc_private_key_from_raw_data(pqc_asym_algo, &context);
     196              :     } else {
     197            0 :         result = libspdm_get_responder_private_key_from_raw_data(base_asym_algo, &context);
     198              :     }
     199            0 :     if (!result) {
     200            0 :         return false;
     201              :     }
     202              : 
     203            0 :     if (pqc_asym_algo != 0) {
     204            0 :         result = libspdm_read_responder_pqc_certificate(
     205              :             pqc_asym_algo, &cert, &cert_size);
     206              :     } else {
     207            0 :         result = libspdm_read_responder_certificate(
     208              :             base_asym_algo, &cert, &cert_size);
     209              :     }
     210            0 :     if (!result) {
     211            0 :         return false;
     212              :     }
     213              : 
     214            0 :     result = libspdm_x509_construct_certificate(cert, cert_size,
     215              :                                                 (uint8_t **)&x509_ca_cert);
     216            0 :     if ((x509_ca_cert == NULL) || (!result)) {
     217            0 :         return false;
     218              :     }
     219              : 
     220            0 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
     221            0 :     asym_nid = libspdm_get_aysm_nid(base_asym_algo);
     222            0 :     pqc_asym_nid = libspdm_get_pqc_aysm_nid(pqc_asym_algo);
     223              : 
     224            0 :     char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
     225              : 
     226            0 :     if (pqc_asym_algo != 0) {
     227            0 :         result = libspdm_gen_x509_csr_with_pqc(hash_nid, 0, pqc_asym_nid,
     228              :                                                requester_info, requester_info_length,
     229            0 :                                                !is_device_cert_model,
     230              :                                                context, subject_name,
     231              :                                                csr_len, csr_pointer,
     232            0 :                                                x509_ca_cert);
     233            0 :         libspdm_pqc_asym_free(pqc_asym_algo, context);
     234              :     } else {
     235            0 :         result = libspdm_gen_x509_csr(hash_nid, asym_nid,
     236              :                                       requester_info, requester_info_length,
     237            0 :                                       !is_device_cert_model,
     238              :                                       context, subject_name,
     239              :                                       csr_len, csr_pointer,
     240            0 :                                       x509_ca_cert);
     241            0 :         libspdm_asym_free(base_asym_algo, context);
     242              :     }
     243            0 :     free(cert);
     244              : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
     245              : }
     246              : #endif
     247              : 
     248            6 :     if (csr_buffer_size < *csr_len) {
     249            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,"csr buffer is too small to store generated csr! \n"));
     250            0 :         result = false;
     251              :     }
     252            6 :     return result;
     253              : }
     254              : 
     255           10 : bool libspdm_gen_csr(
     256              :     void *spdm_context,
     257              :     uint32_t base_hash_algo, uint32_t base_asym_algo, bool *need_reset,
     258              :     const void *request, size_t request_size,
     259              :     uint8_t *requester_info, size_t requester_info_length,
     260              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     261              :     size_t *csr_len, uint8_t *csr_pointer,
     262              :     bool is_device_cert_model,
     263              :     bool *is_busy, bool *unexpected_request)
     264              : {
     265              :     bool result;
     266              :     uint8_t *cached_last_csr_request;
     267              :     size_t cached_last_request_len;
     268              :     uint8_t *cached_csr;
     269              :     size_t csr_buffer_size;
     270              :     uint8_t rsp_csr_tracking_tag;
     271              : 
     272           10 :     csr_buffer_size = *csr_len;
     273              : 
     274              :     /*device gen csr need reset*/
     275           10 :     if (*need_reset) {
     276            4 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     277              :                                                       &cached_last_request_len,
     278              :                                                       1, &rsp_csr_tracking_tag);
     279              : 
     280              :         /*get the cached last csr request and csr*/
     281            4 :         if ((result) &&
     282            5 :             (cached_last_request_len == request_size) &&
     283            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     284            2 :                                             request_size)) &&
     285            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     286            1 :             (*csr_len != 0)) {
     287              : 
     288              :             /*get and save cached csr*/
     289            1 :             if (csr_buffer_size < *csr_len) {
     290            0 :                 free(cached_csr);
     291            0 :                 free(cached_last_csr_request);
     292            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     293              :                                "csr buffer is too small to store cached csr! \n"));
     294            0 :                 return false;
     295              :             } else {
     296            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     297              :             }
     298              : 
     299              :             /*device don't need reset this time*/
     300            1 :             *need_reset = false;
     301              : 
     302            1 :             free(cached_csr);
     303            1 :             free(cached_last_csr_request);
     304            1 :             return true;
     305              :         } else {
     306            3 :             if (cached_last_csr_request != NULL) {
     307            2 :                 free(cached_last_csr_request);
     308              :             }
     309              : 
     310              :             /*device need reset this time: cache the last_csr_request */
     311            3 :             result = libspdm_cache_last_csr_request(request, request_size, 1);
     312            3 :             if (!result) {
     313            0 :                 return result;
     314              :             }
     315              : 
     316              :             /*device need reset this time*/
     317            3 :             *need_reset = true;
     318            3 :             return true;
     319              :         }
     320              :     } else {
     321            6 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo, 0,
     322              :                                                requester_info, requester_info_length,
     323              :                                                opaque_data, opaque_data_length,
     324              :                                                csr_len, csr_pointer, is_device_cert_model);
     325            6 :         return result;
     326              :     }
     327              : 
     328              : }
     329              : 
     330              : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
     331           15 : bool libspdm_gen_csr_ex(
     332              :     void *spdm_context,
     333              :     uint32_t base_hash_algo, uint32_t base_asym_algo, uint32_t pqc_asym_algo,
     334              :     bool *need_reset,
     335              :     const void *request, size_t request_size,
     336              :     uint8_t *requester_info, size_t requester_info_length,
     337              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     338              :     size_t *csr_len, uint8_t *csr_pointer,
     339              :     uint8_t req_cert_model,
     340              :     uint8_t *req_csr_tracking_tag,
     341              :     uint8_t req_key_pair_id,
     342              :     bool overwrite,
     343              :     bool *is_busy, bool *unexpected_request)
     344              : {
     345              :     bool result;
     346              :     uint8_t *cached_last_csr_request;
     347              :     size_t cached_last_request_len;
     348              :     uint8_t *cached_csr;
     349              :     size_t csr_buffer_size;
     350              :     uint8_t rsp_csr_tracking_tag;
     351              :     uint8_t available_csr_tracking_tag;
     352              :     uint8_t *request_change;
     353              :     uint8_t index;
     354              :     bool flag;
     355              :     bool is_device_cert_model;
     356              : 
     357           15 :     available_csr_tracking_tag = 0;
     358           15 :     csr_buffer_size = *csr_len;
     359              : 
     360              :     /*device gen csr need reset*/
     361           15 :     if (*need_reset) {
     362           15 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     363              :                                                       &cached_last_request_len,
     364           15 :                                                       *req_csr_tracking_tag,
     365              :                                                       &rsp_csr_tracking_tag);
     366              : 
     367           48 :         for (index = 1; index <= SPDM_MAX_CSR_TRACKING_TAG; index++) {
     368           47 :             if (((rsp_csr_tracking_tag >> index) & 0x01) == 0x01) {
     369           14 :                 available_csr_tracking_tag = index;
     370           14 :                 break;
     371              :             }
     372              :         }
     373              : 
     374           15 :         if (*req_csr_tracking_tag == 0) {
     375           11 :             if (available_csr_tracking_tag == 0) {
     376              :                 /*no available tracking tag*/
     377            1 :                 *is_busy = true;
     378            1 :                 return false;
     379              :             } else {
     380           10 :                 flag = false;
     381              :             }
     382              :         } else {
     383              :             /*matched csr_tracking_tag*/
     384            4 :             if (((rsp_csr_tracking_tag >> *req_csr_tracking_tag) & 0x01) == 0) {
     385            2 :                 flag = true;
     386              :             } else {
     387              :                 /*unexpected*/
     388            2 :                 return false;
     389              :             }
     390              :         }
     391              : 
     392              :         /*get the cached last csr request and csr*/
     393           12 :         if ((result) &&
     394            4 :             (cached_last_request_len == request_size) &&
     395            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     396            2 :                                             request_size)) &&
     397            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     398            1 :             (*csr_len != 0) &&
     399              :             (flag)) {
     400              : 
     401              :             /*get and save cached csr*/
     402            1 :             if (csr_buffer_size < *csr_len) {
     403            0 :                 free(cached_csr);
     404            0 :                 free(cached_last_csr_request);
     405            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     406              :                                "csr buffer is too small to store cached csr! \n"));
     407            0 :                 return false;
     408              :             } else {
     409            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     410              :             }
     411              : 
     412              :             /*device don't need reset this time*/
     413            1 :             *need_reset = false;
     414              : 
     415            1 :             free(cached_csr);
     416            1 :             free(cached_last_csr_request);
     417            1 :             return true;
     418              :         } else {
     419           11 :             if (cached_last_csr_request != NULL) {
     420            1 :                 free(cached_last_csr_request);
     421              :             }
     422              : 
     423           11 :             if ((*req_csr_tracking_tag == 0) && (available_csr_tracking_tag != 0)) {
     424           10 :                 request_change = malloc(request_size);
     425           10 :                 libspdm_copy_mem(request_change, request_size, request,request_size);
     426              : 
     427           10 :                 if (overwrite) {
     428            1 :                     available_csr_tracking_tag = 1;
     429              :                     /*discard all previously generated CSRTrackingTags. */
     430            1 :                     result = libspdm_discard_all_cached_last_request();
     431            1 :                     if (!result) {
     432            0 :                         free(request_change);
     433            0 :                         return result;
     434              :                     }
     435              :                 }
     436              : 
     437           10 :                 request_change[3] |=
     438              :                     (available_csr_tracking_tag <<
     439              :                         SPDM_GET_CSR_REQUEST_ATTRIBUTES_CSR_TRACKING_TAG_OFFSET);
     440              : 
     441              :                 /*device need reset this time: cache the last_csr_request */
     442           10 :                 result = libspdm_cache_last_csr_request(request_change,
     443              :                                                         request_size, available_csr_tracking_tag);
     444           10 :                 if (!result) {
     445            0 :                     free(request_change);
     446            0 :                     return result;
     447              :                 }
     448              : 
     449              :                 /*device need reset this time*/
     450           10 :                 *need_reset = true;
     451           10 :                 *req_csr_tracking_tag = available_csr_tracking_tag;
     452           10 :                 free(request_change);
     453           10 :                 return true;
     454              :             } else {
     455              :                 /*the device is busy*/
     456            1 :                 *is_busy = true;
     457            1 :                 return false;
     458              :             }
     459              :         }
     460              :     } else {
     461            0 :         if (req_cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT) {
     462            0 :             is_device_cert_model = true;
     463              :         } else {
     464            0 :             is_device_cert_model = false;
     465              :         }
     466            0 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo, pqc_asym_algo,
     467              :                                                requester_info, requester_info_length,
     468              :                                                opaque_data, opaque_data_length,
     469              :                                                csr_len, csr_pointer, is_device_cert_model);
     470            0 :         return result;
     471              :     }
     472              : }
     473              : #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
     474              : 
     475              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP */
        

Generated by: LCOV version 2.0-1