From 6eb564ca745895c6cbf09a59d0dadcd0122279b0 Mon Sep 17 00:00:00 2001 From: Shrikant Temburwar Date: Mon, 13 Nov 2023 11:58:54 +0530 Subject: [PATCH 1/2] Add run time argument to take input for manufacturer address (#257) * Add run time argument to take input for manufacturer address Add "-ip" runtime argument to take input for manufacturer address. If -ip is not specified, the manufacturer_addr.bin file is used. * Add a note about linux-client binary usage Signed-off-by: Shrikant Temburwar --- app/main.c | 46 +++++++++++++++++++++++++++++++++------------ docs/cse.md | 4 ++++ docs/linux.md | 6 ++++++ docs/tpm.md | 4 ++++ include/fdo.h | 3 +++ lib/fdo.c | 52 ++++++++++++++++++++++++++++++++++----------------- 6 files changed, 86 insertions(+), 29 deletions(-) diff --git a/app/main.c b/app/main.c index 38e58fe2..695fe1ad 100644 --- a/app/main.c +++ b/app/main.c @@ -229,10 +229,42 @@ int app_main(bool is_resale) { fdo_sdk_service_info_module *module_info = NULL; int ret = -1; - + bool resale = false; bool do_resale = false; + int strcmp_res = 0; + LOG(LOG_DEBUG, "Starting FIDO Device Onboard\n"); + for (int index = 1; index < argc; index++) { + if (index + 1 < argc && + (!strcmp_s((char *)argv[index], DATA_CONTENT_SIZE, "-ip", + &strcmp_res) && + !strcmp_res)) { + index++; + mfg_addr = argv[index]; + use_mfg_addr_bin = false; + } else if (!strcmp_s((char *)argv[index], DATA_CONTENT_SIZE, + "-ss", &strcmp_res) && + !strcmp_res) { +#if defined SELF_SIGNED_CERTS_SUPPORTED + useSelfSignedCerts = true; +#endif + } else if (!strcmp_s((char *)argv[index], DATA_CONTENT_SIZE, + "-r", &strcmp_res) && + !strcmp_res) { + resale = true; + } else { + printf("Usage: linux-client -ip ://:\n" + "\tif -ip not specified, manufacturer_addr.bin " + "will be used\n" + "\t-ss: specify if backend servers are using " + "self-signed certificates\n" + "\t-r: enable resale\n"); + exit(1); + } + } + #ifdef SECURE_ELEMENT if (-1 == se_provisioning()) { LOG(LOG_ERROR, "Provisioning Secure element failed!\n"); @@ -278,7 +310,7 @@ int app_main(bool is_resale) #endif #if defined TARGET_OS_LINUX - if (argc > 1 && *argv[1] == '1') { + if (resale == true) { do_resale = true; } #else @@ -286,17 +318,7 @@ int app_main(bool is_resale) do_resale = true; } #endif -#if defined SELF_SIGNED_CERTS_SUPPORTED - int strcmp_ss = 1; - int res = -1; - - res = (int)strcmp_s((char *)argv[1], DATA_CONTENT_SIZE, "-ss", - &strcmp_ss); - if (argc > 1 && (!res && !strcmp_ss)) { - useSelfSignedCerts = true; - } -#endif if (is_ownership_transfer(do_resale)) { ret = 0; goto end; diff --git a/docs/cse.md b/docs/cse.md index c5617076..d60929bc 100644 --- a/docs/cse.md +++ b/docs/cse.md @@ -254,6 +254,10 @@ After a successful compilation, the Intel® CSE enabled FDO Client ```shell sudo ./build/linux-client ``` +> ***NOTE***: Usage: `linux-client -ip ://:` + if -ip not specified, manufacturer_addr.bin will be used + `-ss`: specify if backend servers are using self-signed certificates + `-r`: enable resale > ***NOTE***: To do the DI again we need to clear the Device status from CSE storage. > To clear the storage, compile the code with "-DCSE_CLEAR=true" flag and then execute the following command ```shell diff --git a/docs/linux.md b/docs/linux.md index 84380c6f..e102225d 100644 --- a/docs/linux.md +++ b/docs/linux.md @@ -1,5 +1,6 @@ + # Linux* OS The development and execution OS used was `Ubuntu* OS version 20.04 or 22.04 / RHEL* OS version 8.4 or 8.6 / Debian 11.4` on x86. Follow these steps to compile and execute FIDO Device Onboard (FDO). @@ -229,3 +230,8 @@ After a successful compilation, the FDO Client SDK Linux device executable can b ```shell ./build/linux-client ``` + +> ***NOTE***: Usage: `linux-client -ip ://:` + if -ip not specified, manufacturer_addr.bin will be used + `-ss`: specify if backend servers are using self-signed certificates + `-r`: enable resale diff --git a/docs/tpm.md b/docs/tpm.md index a27d23cd..4d9143ed 100644 --- a/docs/tpm.md +++ b/docs/tpm.md @@ -377,6 +377,10 @@ After a successful compilation, the FDO Client SDK Linux device executable can b ./build/linux-client ``` > ***NOTE***: linux-client may require elevated privileges. Please use 'sudo' to execute. +> ***NOTE***: Usage: `linux-client -ip ://:` + if -ip not specified, manufacturer_addr.bin will be used + `-ss`: specify if backend servers are using self-signed certificates + `-r`: enable resale diff --git a/include/fdo.h b/include/fdo.h index ea8b8eff..9a3416e4 100644 --- a/include/fdo.h +++ b/include/fdo.h @@ -43,6 +43,9 @@ typedef enum { FDO_STATE_ERROR } fdo_sdk_device_state; +extern char *mfg_addr; +extern bool use_mfg_addr_bin; + #if defined(SELF_SIGNED_CERTS_SUPPORTED) extern bool useSelfSignedCerts; #endif diff --git a/lib/fdo.c b/lib/fdo.c index 78288984..737f9998 100644 --- a/lib/fdo.c +++ b/lib/fdo.c @@ -55,6 +55,9 @@ static app_data_t *g_fdo_data = NULL; extern int g_argc; extern char **g_argv; +char *mfg_addr = NULL; +bool use_mfg_addr_bin = true; + #if defined(DEVICE_CSE_ENABLED) TEEHANDLE fdo_cse_handle; #endif @@ -1256,32 +1259,47 @@ static bool _STATE_DI(void) fdo_prot_di_init(&g_fdo_data->prot, g_fdo_data->devcred); - fsize = fdo_blob_size((char *)MANUFACTURER_ADDR, FDO_SDK_RAW_DATA); - if (fsize > 0) { - buffer = fdo_alloc(fsize + 1); - if (buffer == NULL) { - LOG(LOG_ERROR, "malloc failed\n"); - goto end; - } + if (use_mfg_addr_bin) { + fsize = + fdo_blob_size((char *)MANUFACTURER_ADDR, FDO_SDK_RAW_DATA); + if (fsize > 0) { + buffer = fdo_alloc(fsize + 1); + if (buffer == NULL) { + LOG(LOG_ERROR, "malloc failed\n"); + goto end; + } - if (fdo_blob_read((char *)MANUFACTURER_ADDR, FDO_SDK_RAW_DATA, - (uint8_t *)buffer, fsize) == -1) { - LOG(LOG_ERROR, "Failed to read Manufacturer address\n"); - goto end; - } + if (fdo_blob_read((char *)MANUFACTURER_ADDR, + FDO_SDK_RAW_DATA, (uint8_t *)buffer, + fsize) == -1) { + LOG(LOG_ERROR, + "Failed to read Manufacturer address\n"); + goto end; + } - buffer[fsize] = '\0'; + buffer[fsize] = '\0'; - if (!parse_manufacturer_address(buffer, fsize, &tls, &mfg_ip, + if (!parse_manufacturer_address( + buffer, fsize, &tls, &mfg_ip, mfg_dns, + sizeof(mfg_dns), &mfg_port)) { + LOG(LOG_ERROR, "Failed to parse Manufacturer " + "Network address.\n"); + goto end; + } + } else { + LOG(LOG_ERROR, + "Manufacturer Network address file is empty.\n"); + goto end; + } + } else { + fsize = strnlen_s(mfg_addr, FDO_MAX_STR_SIZE); + if (!parse_manufacturer_address(mfg_addr, fsize, &tls, &mfg_ip, mfg_dns, sizeof(mfg_dns), &mfg_port)) { LOG(LOG_ERROR, "Failed to parse Manufacturer Network address.\n"); goto end; } - } else { - LOG(LOG_ERROR, "Manufacturer Network address file is empty.\n"); - goto end; } g_fdo_data->delaysec = default_delay; From 1ff59f91a34e6de924bec7a2bac470be3b892103 Mon Sep 17 00:00:00 2001 From: Shrikant Temburwar Date: Mon, 13 Nov 2023 12:01:51 +0530 Subject: [PATCH 2/2] Add support to get device serial from system BIOS table (#258) * Add support to get device serial from system BIOS table Added support to get device serial from system BIOS table. linux-client required elevated privileges. Use 'sudo' to execute. * Add compile time option to get device serial number from system BIOS table * Update build_conf.md Signed-off-by: Shrikant Temburwar --- cmake/cli_input.cmake | 28 ++++++++++++++++++++ cmake/extension.cmake | 4 +++ docs/build_conf.md | 6 ++++- lib/include/util.h | 5 ++++ lib/m-string.c | 59 +++++++++++++++++++++++++++++++++++++++++-- storage/util.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 3 deletions(-) diff --git a/cmake/cli_input.cmake b/cmake/cli_input.cmake index fd79f0c5..181e86e5 100644 --- a/cmake/cli_input.cmake +++ b/cmake/cli_input.cmake @@ -30,6 +30,7 @@ set (TPM2_TCTI_TYPE tabrmd) set (RESALE true) set (REUSE true) set (MTLS false) +set (GET_DEV_SERIAL false) #for CSE set (CSE_SHUTDOWN true) @@ -855,3 +856,30 @@ endif() set(CACHED_MTLS ${MTLS} CACHE STRING "Selected MTLS") message("Selected MTLS ${MTLS}") ########################################### +# FOR GET_DEV_SERIAL +get_property(cached_get_dev_serial_value CACHE GET_DEV_SERIAL PROPERTY VALUE) + +set(get_dev_serial_cli_arg ${cached_get_dev_serial_value}) +if(get_dev_serial_cli_arg STREQUAL CACHED_GET_DEV_SERIAL) + unset(get_dev_serial_cli_arg) +endif() + +set(get_dev_serial_app_cmake_lists ${GET_DEV_SERIAL}) +if(cached_get_dev_serial_value STREQUAL GET_DEV_SERIAL) + unset(get_dev_serial_app_cmake_lists) +endif() + +if(DEFINED CACHED_GET_DEV_SERIAL) + if ((DEFINED get_dev_serial_cli_arg) AND (NOT(CACHED_GET_DEV_SERIAL STREQUAL get_dev_serial_cli_arg))) + message(WARNING "Need to do make pristine before cmake args can change.") + endif() + set(GET_DEV_SERIAL ${CACHED_GET_DEV_SERIAL}) +elseif(DEFINED get_dev_serial_cli_arg) + set(GET_DEV_SERIAL ${get_dev_serial_cli_arg}) +elseif(DEFINED get_dev_serial_app_cmake_lists) + set(GET_DEV_SERIAL ${get_dev_serial_app_cmake_lists}) +endif() + +set(CACHED_GET_DEV_SERIAL ${GET_DEV_SERIAL} CACHE STRING "Selected GET_DEV_SERIAL") +message("Selected GET_DEV_SERIAL ${GET_DEV_SERIAL}") +########################################### diff --git a/cmake/extension.cmake b/cmake/extension.cmake index a5cc5e32..152715b5 100644 --- a/cmake/extension.cmake +++ b/cmake/extension.cmake @@ -275,4 +275,8 @@ endif() if(${MTLS} STREQUAL true) client_sdk_compile_definitions(-DMTLS) endif() + +if(${GET_DEV_SERIAL} STREQUAL true) + client_sdk_compile_definitions(-DGET_DEV_SERIAL) +endif() ############################################################ diff --git a/docs/build_conf.md b/docs/build_conf.md index 686d4b96..49c2e368 100644 --- a/docs/build_conf.md +++ b/docs/build_conf.md @@ -89,7 +89,7 @@ server name in that list for SNI enablement to work as expected. ``` Option to enable/disable mTLS connection: MTLS=true # mTLS connection enabled -MTLS=false # mTLS connection disabled (default) +MTLS=false # mTLS connection disabled (default) Option to enable/disable Device credential resue and resale feature: REUSE=true # Reuse feature enabled (default) @@ -101,6 +101,10 @@ Option to enable/disable Error Recovery: RETRY=true # Error Recovery enabled (default) RETRY=false # Error Recovery disabled +Option to get device serial from system BIOS table: +GET_DEV_SERIAL=true # get device serial enabled +GET_DEV_SERIAL=false # get device serial disabled (default) + List of options to clean targets: pristine # cleanup by remove generated files diff --git a/lib/include/util.h b/lib/include/util.h index 0dbc1cd8..2d2efc63 100644 --- a/lib/include/util.h +++ b/lib/include/util.h @@ -158,6 +158,11 @@ char *strdup_s(const char *str); /* Print timestamp */ int print_timestamp(void); +#if defined(GET_DEV_SERIAL) +/* Get device serial number */ +int get_device_serial(char *str); +#endif + #ifdef __cplusplus } #endif diff --git a/lib/m-string.c b/lib/m-string.c index 2c1a948c..4a62fb5e 100644 --- a/lib/m-string.c +++ b/lib/m-string.c @@ -69,12 +69,65 @@ static int read_fill_modelserial(void) uint8_t def_model_sz = 0; size_t fsize = 0; +#if defined(GET_DEV_SERIAL) + int strcmp_res = -1; + char temp_device_serial[MAX_DEV_SERIAL_SZ]; + uint8_t temp_serial_sz = 0; + + if (memset_s(temp_device_serial, sizeof(temp_device_serial), 0) != 0) { + LOG(LOG_ERROR, "Memset() failed!\n"); + goto err; + } + + ret = get_device_serial(temp_device_serial); + if (ret) { + LOG(LOG_ERROR, "Failed to get serial no.\n"); + } + + if (ret || (!strcmp_s((char *)temp_device_serial, MAX_DEV_SERIAL_SZ, + "Not Specified\n", &strcmp_res) && + !strcmp_res)) { + LOG(LOG_DEBUG, "Defaulting serial num to 'abcdef'\n"); + def_serial_sz = strnlen_s(DEF_SERIAL_NO, MAX_DEV_SERIAL_SZ); + if (!def_serial_sz || def_serial_sz == MAX_DEV_SERIAL_SZ) { + LOG(LOG_ERROR, "Default serial number string isn't " + "NULL terminated\n"); + goto err; + } + + ret = strncpy_s(device_serial, MAX_DEV_SERIAL_SZ, DEF_SERIAL_NO, + def_serial_sz); + if (ret) { + LOG(LOG_ERROR, "Failed to copy serial no!\n"); + goto err; + } + } else { + temp_serial_sz = + strnlen_s(temp_device_serial, MAX_DEV_SERIAL_SZ); + if (!temp_serial_sz || temp_serial_sz == MAX_DEV_SERIAL_SZ) { + LOG(LOG_ERROR, "Default serial number string isn't " + "NULL terminated\n"); + goto err; + } + + if (*temp_device_serial && + temp_device_serial[temp_serial_sz - 1] == '\n') { + temp_device_serial[temp_serial_sz - 1] = '\0'; + } + + ret = strncpy_s(device_serial, MAX_DEV_SERIAL_SZ, + temp_device_serial, temp_serial_sz); + if (ret) { + LOG(LOG_ERROR, "Failed to copy serial no!\n"); + goto err; + } + } +#else fsize = fdo_blob_size((const char *)SERIAL_FILE, FDO_SDK_RAW_DATA); if ((fsize > 0) && (fsize <= MAX_DEV_SERIAL_SZ)) { if (fdo_blob_read((const char *)SERIAL_FILE, FDO_SDK_RAW_DATA, (uint8_t *)device_serial, fsize) <= 0) { - LOG(LOG_ERROR, "Failed to get serial no\n"); goto err; } @@ -82,7 +135,7 @@ static int read_fill_modelserial(void) if (fsize > MAX_DEV_SERIAL_SZ) { LOG(LOG_INFO, "Serialno exceeds 255 characters. " "Defaulting it to 'abcdef'\n"); - } else { + } else if (!fsize) { LOG(LOG_INFO, "No serialno file present!\n"); } @@ -100,6 +153,8 @@ static int read_fill_modelserial(void) goto err; } } +#endif + LOG(LOG_DEBUG, "Device serial = %s\n", device_serial); fsize = fdo_blob_size((const char *)MODEL_FILE, FDO_SDK_RAW_DATA); if ((fsize > 0) && (fsize <= MAX_MODEL_NO_SZ)) { diff --git a/storage/util.c b/storage/util.c index 2b79b18a..942f1c1a 100644 --- a/storage/util.c +++ b/storage/util.c @@ -20,6 +20,10 @@ #include "freertos/task.h" #endif +#ifndef MAX_DEV_SERIAL_SZ +#define MAX_DEV_SERIAL_SZ 255 +#endif + bool file_exists(char const *filename) { FILE *fp = NULL; @@ -317,3 +321,58 @@ int print_timestamp(void) #endif return 0; } + +#if defined(GET_DEV_SERIAL) +// Get device serial number +int get_device_serial(char *serial_buff) +{ + FILE *fp; + char *cmd = "dmidecode -s system-serial-number"; + int out_sz; + char out[MAX_DEV_SERIAL_SZ]; + int results_sz = 0; + int ret = -1; + char *results = (char *)malloc(MAX_DEV_SERIAL_SZ * sizeof(char)); + + if (cmd != NULL) { + /* Open the command for reading. */ + fp = popen(cmd, "r"); + if (fp != NULL) { + + /* Read the output a line at a time - output it. */ + while (fgets(out, out_sz = sizeof(out), fp) != NULL) { + if (strcat_s(results, MAX_DEV_SERIAL_SZ, out) != + 0) { + LOG(LOG_ERROR, "Strcat() failed!\n"); + goto end; + } + } + + results_sz = strnlen_s(results, MAX_DEV_SERIAL_SZ); + if (!results_sz) { + goto end; + } + + if (memcpy_s(serial_buff, results_sz, results, + results_sz)) { + LOG(LOG_ERROR, + "Failed to copy device serial contents\n"); + goto end; + } + } else { + goto end; + } + ret = 0; + } +end: + /* close */ + if (fp) { + pclose(fp); + } + if (results) { + free(results); + results = NULL; + } + return ret; +} +#endif \ No newline at end of file