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.6 % 188 127
Test Date: 2025-08-24 08:11:14 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              : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
     257              :     void *spdm_context,
     258              : #endif
     259              :     uint32_t base_hash_algo, uint32_t base_asym_algo, bool *need_reset,
     260              :     const void *request, size_t request_size,
     261              :     uint8_t *requester_info, size_t requester_info_length,
     262              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     263              :     size_t *csr_len, uint8_t *csr_pointer,
     264              :     bool is_device_cert_model
     265              : #if LIBSPDM_SET_CERT_CSR_PARAMS
     266              :     , bool *is_busy, bool *unexpected_request
     267              : #endif
     268              :     )
     269              : {
     270              :     bool result;
     271              :     uint8_t *cached_last_csr_request;
     272              :     size_t cached_last_request_len;
     273              :     uint8_t *cached_csr;
     274              :     size_t csr_buffer_size;
     275              :     uint8_t rsp_csr_tracking_tag;
     276              : 
     277           10 :     csr_buffer_size = *csr_len;
     278              : 
     279              :     /*device gen csr need reset*/
     280           10 :     if (*need_reset) {
     281            4 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     282              :                                                       &cached_last_request_len,
     283              :                                                       1, &rsp_csr_tracking_tag);
     284              : 
     285              :         /*get the cached last csr request and csr*/
     286            4 :         if ((result) &&
     287            5 :             (cached_last_request_len == request_size) &&
     288            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     289            2 :                                             request_size)) &&
     290            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     291            1 :             (*csr_len != 0)) {
     292              : 
     293              :             /*get and save cached csr*/
     294            1 :             if (csr_buffer_size < *csr_len) {
     295            0 :                 free(cached_csr);
     296            0 :                 free(cached_last_csr_request);
     297            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     298              :                                "csr buffer is too small to store cached csr! \n"));
     299            0 :                 return false;
     300              :             } else {
     301            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     302              :             }
     303              : 
     304              :             /*device don't need reset this time*/
     305            1 :             *need_reset = false;
     306              : 
     307            1 :             free(cached_csr);
     308            1 :             free(cached_last_csr_request);
     309            1 :             return true;
     310              :         } else {
     311            3 :             if (cached_last_csr_request != NULL) {
     312            2 :                 free(cached_last_csr_request);
     313              :             }
     314              : 
     315              :             /*device need reset this time: cache the last_csr_request */
     316            3 :             result = libspdm_cache_last_csr_request(request, request_size, 1);
     317            3 :             if (!result) {
     318            0 :                 return result;
     319              :             }
     320              : 
     321              :             /*device need reset this time*/
     322            3 :             *need_reset = true;
     323            3 :             return true;
     324              :         }
     325              :     } else {
     326            6 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo, 0,
     327              :                                                requester_info, requester_info_length,
     328              :                                                opaque_data, opaque_data_length,
     329              :                                                csr_len, csr_pointer, is_device_cert_model);
     330            6 :         return result;
     331              :     }
     332              : 
     333              : }
     334              : 
     335              : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
     336           15 : bool libspdm_gen_csr_ex(
     337              : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
     338              :     void *spdm_context,
     339              : #endif
     340              :     uint32_t base_hash_algo, uint32_t base_asym_algo, uint32_t pqc_asym_algo,
     341              :     bool *need_reset,
     342              :     const void *request, size_t request_size,
     343              :     uint8_t *requester_info, size_t requester_info_length,
     344              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     345              :     size_t *csr_len, uint8_t *csr_pointer,
     346              :     uint8_t req_cert_model,
     347              :     uint8_t *req_csr_tracking_tag,
     348              :     uint8_t req_key_pair_id,
     349              :     bool overwrite
     350              : #if LIBSPDM_SET_CERT_CSR_PARAMS
     351              :     , bool *is_busy, bool *unexpected_request
     352              : #endif
     353              :     )
     354              : {
     355              :     bool result;
     356              :     uint8_t *cached_last_csr_request;
     357              :     size_t cached_last_request_len;
     358              :     uint8_t *cached_csr;
     359              :     size_t csr_buffer_size;
     360              :     uint8_t rsp_csr_tracking_tag;
     361              :     uint8_t available_csr_tracking_tag;
     362              :     uint8_t *request_change;
     363              :     uint8_t index;
     364              :     bool flag;
     365              :     bool is_device_cert_model;
     366              : 
     367           15 :     available_csr_tracking_tag = 0;
     368           15 :     csr_buffer_size = *csr_len;
     369              : 
     370              :     /*device gen csr need reset*/
     371           15 :     if (*need_reset) {
     372           15 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     373              :                                                       &cached_last_request_len,
     374           15 :                                                       *req_csr_tracking_tag,
     375              :                                                       &rsp_csr_tracking_tag);
     376              : 
     377           48 :         for (index = 1; index <= SPDM_MAX_CSR_TRACKING_TAG; index++) {
     378           47 :             if (((rsp_csr_tracking_tag >> index) & 0x01) == 0x01) {
     379           14 :                 available_csr_tracking_tag = index;
     380           14 :                 break;
     381              :             }
     382              :         }
     383              : 
     384           15 :         if (*req_csr_tracking_tag == 0) {
     385           11 :             if (available_csr_tracking_tag == 0) {
     386              :                 /*no available tracking tag*/
     387              :                 #if LIBSPDM_SET_CERT_CSR_PARAMS
     388              :                 *is_busy = true;
     389              :                 #endif
     390            1 :                 return false;
     391              :             } else {
     392           10 :                 flag = false;
     393              :             }
     394              :         } else {
     395              :             /*matched csr_tracking_tag*/
     396            4 :             if (((rsp_csr_tracking_tag >> *req_csr_tracking_tag) & 0x01) == 0) {
     397            2 :                 flag = true;
     398              :             } else {
     399              :                 /*unexpected*/
     400            2 :                 return false;
     401              :             }
     402              :         }
     403              : 
     404              :         /*get the cached last csr request and csr*/
     405           12 :         if ((result) &&
     406            4 :             (cached_last_request_len == request_size) &&
     407            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     408            2 :                                             request_size)) &&
     409            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     410            1 :             (*csr_len != 0) &&
     411              :             (flag)) {
     412              : 
     413              :             /*get and save cached csr*/
     414            1 :             if (csr_buffer_size < *csr_len) {
     415            0 :                 free(cached_csr);
     416            0 :                 free(cached_last_csr_request);
     417            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     418              :                                "csr buffer is too small to store cached csr! \n"));
     419            0 :                 return false;
     420              :             } else {
     421            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     422              :             }
     423              : 
     424              :             /*device don't need reset this time*/
     425            1 :             *need_reset = false;
     426              : 
     427            1 :             free(cached_csr);
     428            1 :             free(cached_last_csr_request);
     429            1 :             return true;
     430              :         } else {
     431           11 :             if (cached_last_csr_request != NULL) {
     432            1 :                 free(cached_last_csr_request);
     433              :             }
     434              : 
     435           11 :             if ((*req_csr_tracking_tag == 0) && (available_csr_tracking_tag != 0)) {
     436           10 :                 request_change = malloc(request_size);
     437           10 :                 libspdm_copy_mem(request_change, request_size, request,request_size);
     438              : 
     439           10 :                 if (overwrite) {
     440            1 :                     available_csr_tracking_tag = 1;
     441              :                     /*discard all previously generated CSRTrackingTags. */
     442            1 :                     result = libspdm_discard_all_cached_last_request();
     443            1 :                     if (!result) {
     444            0 :                         free(request_change);
     445            0 :                         return result;
     446              :                     }
     447              :                 }
     448              : 
     449           10 :                 request_change[3] |=
     450              :                     (available_csr_tracking_tag <<
     451              :                         SPDM_GET_CSR_REQUEST_ATTRIBUTES_CSR_TRACKING_TAG_OFFSET);
     452              : 
     453              :                 /*device need reset this time: cache the last_csr_request */
     454           10 :                 result = libspdm_cache_last_csr_request(request_change,
     455              :                                                         request_size, available_csr_tracking_tag);
     456           10 :                 if (!result) {
     457            0 :                     free(request_change);
     458            0 :                     return result;
     459              :                 }
     460              : 
     461              :                 /*device need reset this time*/
     462           10 :                 *need_reset = true;
     463           10 :                 *req_csr_tracking_tag = available_csr_tracking_tag;
     464           10 :                 free(request_change);
     465           10 :                 return true;
     466              :             } else {
     467              :                 /*the device is busy*/
     468              :                 #if LIBSPDM_SET_CERT_CSR_PARAMS
     469              :                 *is_busy = true;
     470              :                 #endif
     471            1 :                 return false;
     472              :             }
     473              :         }
     474              :     } else {
     475            0 :         if (req_cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT) {
     476            0 :             is_device_cert_model = true;
     477              :         } else {
     478            0 :             is_device_cert_model = false;
     479              :         }
     480            0 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo, pqc_asym_algo,
     481              :                                                requester_info, requester_info_length,
     482              :                                                opaque_data, opaque_data_length,
     483              :                                                csr_len, csr_pointer, is_device_cert_model);
     484            0 :         return result;
     485              :     }
     486              : }
     487              : #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
     488              : 
     489              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP */
        

Generated by: LCOV version 2.0-1