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: 73.5 % 166 122
Test Date: 2025-06-29 08:09:00 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              :                                    uint8_t *requester_info, size_t requester_info_length,
     102              :                                    uint8_t *opaque_data, uint16_t opaque_data_length,
     103              :                                    size_t *csr_len, uint8_t *csr_pointer,
     104              :                                    bool is_device_cert_model)
     105              : {
     106              :     bool result;
     107              :     size_t hash_nid;
     108              :     size_t asym_nid;
     109              :     void *context;
     110              :     size_t csr_buffer_size;
     111              : 
     112            6 :     csr_buffer_size = *csr_len;
     113              : 
     114              : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
     115            6 :     if (g_private_key_mode) {
     116              :         void *x509_ca_cert;
     117              :         void *prikey, *cert;
     118              :         size_t prikey_size, cert_size;
     119              : 
     120            6 :         result = libspdm_read_responder_private_key(
     121              :             base_asym_algo, &prikey, &prikey_size);
     122            6 :         if (!result) {
     123            0 :             return false;
     124              :         }
     125              : 
     126            6 :         result = libspdm_read_responder_certificate(
     127              :             base_asym_algo, &cert, &cert_size);
     128            6 :         if (!result) {
     129            0 :             return false;
     130              :         }
     131              : 
     132            6 :         result = libspdm_x509_construct_certificate(cert, cert_size,
     133              :                                                     (uint8_t **)&x509_ca_cert);
     134            6 :         if ((x509_ca_cert == NULL) || (!result)) {
     135            0 :             return false;
     136              :         }
     137              : 
     138            6 :         result = libspdm_asym_get_private_key_from_pem(
     139              :             base_asym_algo, prikey, prikey_size, NULL, &context);
     140            6 :         if (!result) {
     141            0 :             libspdm_zero_mem(prikey, prikey_size);
     142            0 :             free(prikey);
     143            0 :             return false;
     144              :         }
     145            6 :         hash_nid = libspdm_get_hash_nid(base_hash_algo);
     146            6 :         asym_nid = libspdm_get_aysm_nid(base_asym_algo);
     147              : 
     148            6 :         char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
     149              : 
     150            6 :         result = libspdm_gen_x509_csr(hash_nid, asym_nid,
     151              :                                       requester_info, requester_info_length,
     152            6 :                                       !is_device_cert_model,
     153              :                                       context, subject_name,
     154              :                                       csr_len, csr_pointer,
     155            6 :                                       x509_ca_cert);
     156            6 :         libspdm_asym_free(base_asym_algo, context);
     157            6 :         libspdm_zero_mem(prikey, prikey_size);
     158            6 :         free(prikey);
     159            6 :         free(cert);
     160              :     } else {
     161              : #endif
     162              :     void *x509_ca_cert;
     163              :     void *cert;
     164              :     size_t cert_size;
     165              : 
     166            0 :     result = libspdm_get_responder_private_key_from_raw_data(base_asym_algo, &context);
     167            0 :     if (!result) {
     168            0 :         return false;
     169              :     }
     170              : 
     171            0 :     result = libspdm_read_responder_certificate(
     172              :         base_asym_algo, &cert, &cert_size);
     173            0 :     if (!result) {
     174            0 :         return false;
     175              :     }
     176              : 
     177            0 :     result = libspdm_x509_construct_certificate(cert, cert_size,
     178              :                                                 (uint8_t **)&x509_ca_cert);
     179            0 :     if ((x509_ca_cert == NULL) || (!result)) {
     180            0 :         return false;
     181              :     }
     182              : 
     183            0 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
     184            0 :     asym_nid = libspdm_get_aysm_nid(base_asym_algo);
     185              : 
     186            0 :     char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
     187              : 
     188            0 :     result = libspdm_gen_x509_csr(hash_nid, asym_nid,
     189              :                                   requester_info, requester_info_length,
     190            0 :                                   !is_device_cert_model,
     191              :                                   context, subject_name,
     192              :                                   csr_len, csr_pointer,
     193            0 :                                   x509_ca_cert);
     194            0 :     libspdm_asym_free(base_asym_algo, context);
     195            0 :     free(cert);
     196              : #if !LIBSPDM_PRIVATE_KEY_MODE_RAW_KEY_ONLY
     197              : }
     198              : #endif
     199              : 
     200            6 :     if (csr_buffer_size < *csr_len) {
     201            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,"csr buffer is too small to store generated csr! \n"));
     202            0 :         result = false;
     203              :     }
     204            6 :     return result;
     205              : }
     206              : 
     207           10 : bool libspdm_gen_csr(
     208              : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
     209              :     void *spdm_context,
     210              : #endif
     211              :     uint32_t base_hash_algo, uint32_t base_asym_algo, bool *need_reset,
     212              :     const void *request, size_t request_size,
     213              :     uint8_t *requester_info, size_t requester_info_length,
     214              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     215              :     size_t *csr_len, uint8_t *csr_pointer,
     216              :     bool is_device_cert_model
     217              : #if LIBSPDM_SET_CERT_CSR_PARAMS
     218              :     , bool *is_busy, bool *unexpected_request
     219              : #endif
     220              :     )
     221              : {
     222              :     bool result;
     223              :     uint8_t *cached_last_csr_request;
     224              :     size_t cached_last_request_len;
     225              :     uint8_t *cached_csr;
     226              :     size_t csr_buffer_size;
     227              :     uint8_t rsp_csr_tracking_tag;
     228              : 
     229           10 :     csr_buffer_size = *csr_len;
     230              : 
     231              :     /*device gen csr need reset*/
     232           10 :     if (*need_reset) {
     233            4 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     234              :                                                       &cached_last_request_len,
     235              :                                                       1, &rsp_csr_tracking_tag);
     236              : 
     237              :         /*get the cached last csr request and csr*/
     238            4 :         if ((result) &&
     239            5 :             (cached_last_request_len == request_size) &&
     240            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     241            2 :                                             request_size)) &&
     242            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     243            1 :             (*csr_len != 0)) {
     244              : 
     245              :             /*get and save cached csr*/
     246            1 :             if (csr_buffer_size < *csr_len) {
     247            0 :                 free(cached_csr);
     248            0 :                 free(cached_last_csr_request);
     249            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     250              :                                "csr buffer is too small to store cached csr! \n"));
     251            0 :                 return false;
     252              :             } else {
     253            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     254              :             }
     255              : 
     256              :             /*device don't need reset this time*/
     257            1 :             *need_reset = false;
     258              : 
     259            1 :             free(cached_csr);
     260            1 :             free(cached_last_csr_request);
     261            1 :             return true;
     262              :         } else {
     263            3 :             if (cached_last_csr_request != NULL) {
     264            2 :                 free(cached_last_csr_request);
     265              :             }
     266              : 
     267              :             /*device need reset this time: cache the last_csr_request */
     268            3 :             result = libspdm_cache_last_csr_request(request, request_size, 1);
     269            3 :             if (!result) {
     270            0 :                 return result;
     271              :             }
     272              : 
     273              :             /*device need reset this time*/
     274            3 :             *need_reset = true;
     275            3 :             return true;
     276              :         }
     277              :     } else {
     278            6 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo,
     279              :                                                requester_info, requester_info_length,
     280              :                                                opaque_data, opaque_data_length,
     281              :                                                csr_len, csr_pointer, is_device_cert_model);
     282            6 :         return result;
     283              :     }
     284              : 
     285              : }
     286              : 
     287              : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
     288           15 : bool libspdm_gen_csr_ex(
     289              : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
     290              :     void *spdm_context,
     291              : #endif
     292              :     uint32_t base_hash_algo, uint32_t base_asym_algo, bool *need_reset,
     293              :     const void *request, size_t request_size,
     294              :     uint8_t *requester_info, size_t requester_info_length,
     295              :     uint8_t *opaque_data, uint16_t opaque_data_length,
     296              :     size_t *csr_len, uint8_t *csr_pointer,
     297              :     uint8_t req_cert_model,
     298              :     uint8_t *req_csr_tracking_tag,
     299              :     uint8_t req_key_pair_id,
     300              :     bool overwrite
     301              : #if LIBSPDM_SET_CERT_CSR_PARAMS
     302              :     , bool *is_busy, bool *unexpected_request
     303              : #endif
     304              :     )
     305              : {
     306              :     bool result;
     307              :     uint8_t *cached_last_csr_request;
     308              :     size_t cached_last_request_len;
     309              :     uint8_t *cached_csr;
     310              :     size_t csr_buffer_size;
     311              :     uint8_t rsp_csr_tracking_tag;
     312              :     uint8_t available_csr_tracking_tag;
     313              :     uint8_t *request_change;
     314              :     uint8_t index;
     315              :     bool flag;
     316              :     bool is_device_cert_model;
     317              : 
     318           15 :     available_csr_tracking_tag = 0;
     319           15 :     csr_buffer_size = *csr_len;
     320              : 
     321              :     /*device gen csr need reset*/
     322           15 :     if (*need_reset) {
     323           15 :         result = libspdm_read_cached_last_csr_request(&cached_last_csr_request,
     324              :                                                       &cached_last_request_len,
     325           15 :                                                       *req_csr_tracking_tag,
     326              :                                                       &rsp_csr_tracking_tag);
     327              : 
     328           48 :         for (index = 1; index <= SPDM_MAX_CSR_TRACKING_TAG; index++) {
     329           47 :             if (((rsp_csr_tracking_tag >> index) & 0x01) == 0x01) {
     330           14 :                 available_csr_tracking_tag = index;
     331           14 :                 break;
     332              :             }
     333              :         }
     334              : 
     335           15 :         if (*req_csr_tracking_tag == 0) {
     336           11 :             if (available_csr_tracking_tag == 0) {
     337              :                 /*no available tracking tag*/
     338              :                 #if LIBSPDM_SET_CERT_CSR_PARAMS
     339              :                 *is_busy = true;
     340              :                 #endif
     341            1 :                 return false;
     342              :             } else {
     343           10 :                 flag = false;
     344              :             }
     345              :         } else {
     346              :             /*matched csr_tracking_tag*/
     347            4 :             if (((rsp_csr_tracking_tag >> *req_csr_tracking_tag) & 0x01) == 0) {
     348            2 :                 flag = true;
     349              :             } else {
     350              :                 /*unexpected*/
     351            2 :                 return false;
     352              :             }
     353              :         }
     354              : 
     355              :         /*get the cached last csr request and csr*/
     356           12 :         if ((result) &&
     357            4 :             (cached_last_request_len == request_size) &&
     358            2 :             (libspdm_consttime_is_mem_equal(cached_last_csr_request, request,
     359            2 :                                             request_size)) &&
     360            2 :             (libspdm_read_cached_csr(&cached_csr, csr_len)) &&
     361            1 :             (*csr_len != 0) &&
     362              :             (flag)) {
     363              : 
     364              :             /*get and save cached csr*/
     365            1 :             if (csr_buffer_size < *csr_len) {
     366            0 :                 free(cached_csr);
     367            0 :                 free(cached_last_csr_request);
     368            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     369              :                                "csr buffer is too small to store cached csr! \n"));
     370            0 :                 return false;
     371              :             } else {
     372            1 :                 libspdm_copy_mem(csr_pointer, csr_buffer_size, cached_csr, *csr_len);
     373              :             }
     374              : 
     375              :             /*device don't need reset this time*/
     376            1 :             *need_reset = false;
     377              : 
     378            1 :             free(cached_csr);
     379            1 :             free(cached_last_csr_request);
     380            1 :             return true;
     381              :         } else {
     382           11 :             if (cached_last_csr_request != NULL) {
     383            1 :                 free(cached_last_csr_request);
     384              :             }
     385              : 
     386           11 :             if ((*req_csr_tracking_tag == 0) && (available_csr_tracking_tag != 0)) {
     387           10 :                 request_change = malloc(request_size);
     388           10 :                 libspdm_copy_mem(request_change, request_size, request,request_size);
     389              : 
     390           10 :                 if (overwrite) {
     391            1 :                     available_csr_tracking_tag = 1;
     392              :                     /*discard all previously generated CSRTrackingTags. */
     393            1 :                     result = libspdm_discard_all_cached_last_request();
     394            1 :                     if (!result) {
     395            0 :                         free(request_change);
     396            0 :                         return result;
     397              :                     }
     398              :                 }
     399              : 
     400           10 :                 request_change[3] |=
     401              :                     (available_csr_tracking_tag <<
     402              :                         SPDM_GET_CSR_REQUEST_ATTRIBUTES_CSR_TRACKING_TAG_OFFSET);
     403              : 
     404              :                 /*device need reset this time: cache the last_csr_request */
     405           10 :                 result = libspdm_cache_last_csr_request(request_change,
     406              :                                                         request_size, available_csr_tracking_tag);
     407           10 :                 if (!result) {
     408            0 :                     free(request_change);
     409            0 :                     return result;
     410              :                 }
     411              : 
     412              :                 /*device need reset this time*/
     413           10 :                 *need_reset = true;
     414           10 :                 *req_csr_tracking_tag = available_csr_tracking_tag;
     415           10 :                 free(request_change);
     416           10 :                 return true;
     417              :             } else {
     418              :                 /*the device is busy*/
     419              :                 #if LIBSPDM_SET_CERT_CSR_PARAMS
     420              :                 *is_busy = true;
     421              :                 #endif
     422            1 :                 return false;
     423              :             }
     424              :         }
     425              :     } else {
     426            0 :         if (req_cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT) {
     427            0 :             is_device_cert_model = true;
     428              :         } else {
     429            0 :             is_device_cert_model = false;
     430              :         }
     431            0 :         result = libspdm_gen_csr_without_reset(base_hash_algo, base_asym_algo,
     432              :                                                requester_info, requester_info_length,
     433              :                                                opaque_data, opaque_data_length,
     434              :                                                csr_len, csr_pointer, is_device_cert_model);
     435            0 :         return result;
     436              :     }
     437              : }
     438              : #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
     439              : 
     440              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP */
        

Generated by: LCOV version 2.0-1