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: 69.5 % 187 130
Test Date: 2026-05-03 08:40:47 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2024-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 <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 :             libspdm_x509_free(x509_ca_cert);
     161            0 :             return false;
     162              :         }
     163            6 :         hash_nid = libspdm_get_hash_nid(base_hash_algo);
     164            6 :         asym_nid = libspdm_get_aysm_nid(base_asym_algo);
     165            6 :         pqc_asym_nid = libspdm_get_pqc_aysm_nid(pqc_asym_algo);
     166              : 
     167            6 :         char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
     168              : 
     169            6 :         result = libspdm_gen_x509_csr(hash_nid, asym_nid, pqc_asym_nid,
     170              :                                       requester_info, requester_info_length,
     171            6 :                                       !is_device_cert_model,
     172              :                                       context, subject_name,
     173              :                                       csr_len, csr_pointer,
     174            6 :                                       x509_ca_cert);
     175            6 :         if (pqc_asym_algo != 0) {
     176            0 :             libspdm_pqc_asym_free(pqc_asym_algo, context);
     177              :         } else {
     178            6 :             libspdm_asym_free(base_asym_algo, context);
     179              :         }
     180            6 :         libspdm_zero_mem(prikey, prikey_size);
     181            6 :         free(prikey);
     182            6 :         free(cert);
     183            6 :         libspdm_x509_free(x509_ca_cert);
     184              :     } else {
     185              : #endif
     186              :     void *x509_ca_cert;
     187              :     void *cert;
     188              :     size_t cert_size;
     189              : 
     190            0 :     if (pqc_asym_algo != 0) {
     191            0 :         result = libspdm_get_responder_pqc_private_key_from_raw_data(pqc_asym_algo, &context);
     192              :     } else {
     193            0 :         result = libspdm_get_responder_private_key_from_raw_data(base_asym_algo, &context);
     194              :     }
     195            0 :     if (!result) {
     196            0 :         return false;
     197              :     }
     198              : 
     199            0 :     if (pqc_asym_algo != 0) {
     200            0 :         result = libspdm_read_responder_pqc_certificate(
     201              :             pqc_asym_algo, &cert, &cert_size);
     202              :     } else {
     203            0 :         result = libspdm_read_responder_certificate(
     204              :             base_asym_algo, &cert, &cert_size);
     205              :     }
     206            0 :     if (!result) {
     207            0 :         return false;
     208              :     }
     209              : 
     210            0 :     result = libspdm_x509_construct_certificate(cert, cert_size,
     211              :                                                 (uint8_t **)&x509_ca_cert);
     212            0 :     if ((x509_ca_cert == NULL) || (!result)) {
     213            0 :         return false;
     214              :     }
     215              : 
     216            0 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
     217            0 :     asym_nid = libspdm_get_aysm_nid(base_asym_algo);
     218            0 :     pqc_asym_nid = libspdm_get_pqc_aysm_nid(pqc_asym_algo);
     219              : 
     220            0 :     char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
     221              : 
     222            0 :     result = libspdm_gen_x509_csr(hash_nid, asym_nid, pqc_asym_nid,
     223              :                                   requester_info, requester_info_length,
     224            0 :                                   !is_device_cert_model,
     225              :                                   context, subject_name,
     226              :                                   csr_len, csr_pointer,
     227            0 :                                   x509_ca_cert);
     228            0 :     if (pqc_asym_algo != 0) {
     229            0 :         libspdm_pqc_asym_free(pqc_asym_algo, context);
     230              :     } else {
     231            0 :         libspdm_asym_free(base_asym_algo, context);
     232              :     }
     233            0 :     libspdm_x509_free(x509_ca_cert);
     234            0 :     free(cert);
     235              : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
     236              : }
     237              : #endif
     238              : 
     239            6 :     if (csr_buffer_size < *csr_len) {
     240            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,"csr buffer is too small to store generated csr! \n"));
     241            0 :         result = false;
     242              :     }
     243            6 :     return result;
     244              : }
     245              : 
     246           10 : bool libspdm_gen_csr(
     247              :     void *spdm_context,
     248              :     uint32_t base_hash_algo, uint32_t base_asym_algo, bool *need_reset,
     249              :     const void *request, size_t request_size,
     250              :     uint8_t *requester_info, size_t requester_info_length,
     251              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     252              :     size_t *csr_len, uint8_t *csr_pointer,
     253              :     bool is_device_cert_model,
     254              :     bool *is_busy, bool *unexpected_request)
     255              : {
     256              :     bool result;
     257              :     uint8_t *cached_last_csr_request;
     258              :     size_t cached_last_request_len;
     259              :     uint8_t *cached_csr;
     260              :     size_t csr_buffer_size;
     261              :     uint8_t rsp_csr_tracking_tag;
     262              : 
     263           10 :     csr_buffer_size = *csr_len;
     264              : 
     265              :     /*device gen csr need reset*/
     266           10 :     if (*need_reset) {
     267            4 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     268              :                                                       &cached_last_request_len,
     269              :                                                       1, &rsp_csr_tracking_tag);
     270              : 
     271              :         /*get the cached last csr request and csr*/
     272            4 :         if ((result) &&
     273            5 :             (cached_last_request_len == request_size) &&
     274            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     275            2 :                                             request_size)) &&
     276            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     277            1 :             (*csr_len != 0)) {
     278              : 
     279              :             /*get and save cached csr*/
     280            1 :             if (csr_buffer_size < *csr_len) {
     281            0 :                 free(cached_csr);
     282            0 :                 free(cached_last_csr_request);
     283            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     284              :                                "csr buffer is too small to store cached csr! \n"));
     285            0 :                 return false;
     286              :             } else {
     287            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     288              :             }
     289              : 
     290              :             /*device don't need reset this time*/
     291            1 :             *need_reset = false;
     292              : 
     293            1 :             free(cached_csr);
     294            1 :             free(cached_last_csr_request);
     295            1 :             return true;
     296              :         } else {
     297            3 :             if (cached_last_csr_request != NULL) {
     298            2 :                 free(cached_last_csr_request);
     299              :             }
     300              : 
     301              :             /*device need reset this time: cache the last_csr_request */
     302            3 :             result = libspdm_cache_last_csr_request(request, request_size, 1);
     303            3 :             if (!result) {
     304            0 :                 return result;
     305              :             }
     306              : 
     307              :             /*device need reset this time*/
     308            3 :             *need_reset = true;
     309            3 :             return true;
     310              :         }
     311              :     } else {
     312            6 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo, 0,
     313              :                                                requester_info, requester_info_length,
     314              :                                                opaque_data, opaque_data_length,
     315              :                                                csr_len, csr_pointer, is_device_cert_model);
     316            6 :         return result;
     317              :     }
     318              : 
     319              : }
     320              : 
     321              : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
     322           15 : bool libspdm_gen_csr_ex(
     323              :     void *spdm_context,
     324              :     uint32_t base_hash_algo, uint32_t base_asym_algo, uint32_t pqc_asym_algo,
     325              :     bool *need_reset,
     326              :     const void *request, size_t request_size,
     327              :     uint8_t *requester_info, size_t requester_info_length,
     328              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     329              :     size_t *csr_len, uint8_t *csr_pointer,
     330              :     uint8_t req_cert_model,
     331              :     uint8_t *req_csr_tracking_tag,
     332              :     uint8_t req_key_pair_id,
     333              :     bool overwrite,
     334              :     bool *is_busy, bool *unexpected_request)
     335              : {
     336              :     bool result;
     337              :     uint8_t *cached_last_csr_request;
     338              :     size_t cached_last_request_len;
     339              :     uint8_t *cached_csr;
     340              :     size_t csr_buffer_size;
     341              :     uint8_t rsp_csr_tracking_tag;
     342              :     uint8_t available_csr_tracking_tag;
     343              :     uint8_t *request_change;
     344              :     uint8_t index;
     345              :     bool flag;
     346              :     bool is_device_cert_model;
     347              : 
     348           15 :     available_csr_tracking_tag = 0;
     349           15 :     csr_buffer_size = *csr_len;
     350              : 
     351              :     /*device gen csr need reset*/
     352           15 :     if (*need_reset) {
     353           15 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     354              :                                                       &cached_last_request_len,
     355           15 :                                                       *req_csr_tracking_tag,
     356              :                                                       &rsp_csr_tracking_tag);
     357              : 
     358           48 :         for (index = 1; index <= SPDM_MAX_CSR_TRACKING_TAG; index++) {
     359           47 :             if (((rsp_csr_tracking_tag >> index) & 0x01) == 0x01) {
     360           14 :                 available_csr_tracking_tag = index;
     361           14 :                 break;
     362              :             }
     363              :         }
     364              : 
     365           15 :         if (*req_csr_tracking_tag == 0) {
     366           11 :             if (available_csr_tracking_tag == 0) {
     367              :                 /*no available tracking tag*/
     368            1 :                 *is_busy = true;
     369            1 :                 return false;
     370              :             } else {
     371           10 :                 flag = false;
     372              :             }
     373              :         } else {
     374              :             /*matched csr_tracking_tag*/
     375            4 :             if (((rsp_csr_tracking_tag >> *req_csr_tracking_tag) & 0x01) == 0) {
     376            2 :                 flag = true;
     377              :             } else {
     378              :                 /*unexpected*/
     379            2 :                 return false;
     380              :             }
     381              :         }
     382              : 
     383              :         /*get the cached last csr request and csr*/
     384           12 :         if ((result) &&
     385            4 :             (cached_last_request_len == request_size) &&
     386            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     387            2 :                                             request_size)) &&
     388            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     389            1 :             (*csr_len != 0) &&
     390              :             (flag)) {
     391              : 
     392              :             /*get and save cached csr*/
     393            1 :             if (csr_buffer_size < *csr_len) {
     394            0 :                 free(cached_csr);
     395            0 :                 free(cached_last_csr_request);
     396            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     397              :                                "csr buffer is too small to store cached csr! \n"));
     398            0 :                 return false;
     399              :             } else {
     400            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     401              :             }
     402              : 
     403              :             /*device don't need reset this time*/
     404            1 :             *need_reset = false;
     405              : 
     406            1 :             free(cached_csr);
     407            1 :             free(cached_last_csr_request);
     408            1 :             return true;
     409              :         } else {
     410           11 :             if (cached_last_csr_request != NULL) {
     411            1 :                 free(cached_last_csr_request);
     412              :             }
     413              : 
     414           11 :             if ((*req_csr_tracking_tag == 0) && (available_csr_tracking_tag != 0)) {
     415           10 :                 request_change = malloc(request_size);
     416           10 :                 libspdm_copy_mem(request_change, request_size, request,request_size);
     417              : 
     418           10 :                 if (overwrite) {
     419            1 :                     available_csr_tracking_tag = 1;
     420              :                     /*discard all previously generated CSRTrackingTags. */
     421            1 :                     result = libspdm_discard_all_cached_last_request();
     422            1 :                     if (!result) {
     423            0 :                         free(request_change);
     424            0 :                         return result;
     425              :                     }
     426              :                 }
     427              : 
     428           10 :                 request_change[3] |=
     429              :                     (available_csr_tracking_tag <<
     430              :                         SPDM_GET_CSR_REQUEST_ATTRIBUTES_CSR_TRACKING_TAG_OFFSET);
     431              : 
     432              :                 /*device need reset this time: cache the last_csr_request */
     433           10 :                 result = libspdm_cache_last_csr_request(request_change,
     434              :                                                         request_size, available_csr_tracking_tag);
     435           10 :                 if (!result) {
     436            0 :                     free(request_change);
     437            0 :                     return result;
     438              :                 }
     439              : 
     440              :                 /*device need reset this time*/
     441           10 :                 *need_reset = true;
     442           10 :                 *req_csr_tracking_tag = available_csr_tracking_tag;
     443           10 :                 free(request_change);
     444           10 :                 return true;
     445              :             } else {
     446              :                 /*the device is busy*/
     447            1 :                 *is_busy = true;
     448            1 :                 return false;
     449              :             }
     450              :         }
     451              :     } else {
     452            0 :         if (req_cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT) {
     453            0 :             is_device_cert_model = true;
     454              :         } else {
     455            0 :             is_device_cert_model = false;
     456              :         }
     457            0 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo, pqc_asym_algo,
     458              :                                                requester_info, requester_info_length,
     459              :                                                opaque_data, opaque_data_length,
     460              :                                                csr_len, csr_pointer, is_device_cert_model);
     461            0 :         return result;
     462              :     }
     463              : }
     464              : #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
     465              : 
     466              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP */
        

Generated by: LCOV version 2.0-1