diff --git a/doc/spdm_emu.md b/doc/spdm_emu.md index a9c56f5..55c6160 100644 --- a/doc/spdm_emu.md +++ b/doc/spdm_emu.md @@ -28,6 +28,7 @@ This document describes spdm_requester_emu and spdm_responder_emu tool. It can b [--key_upd REQ|ALL|RSP] [--slot_id <0~7|0xFF>] [--slot_count <1~8>] + [--req_slot_id <0~7|0xFF>] [--save_state ] [--load_state ] [--exe_mode SHUTDOWN|CONTINUE] @@ -63,7 +64,8 @@ This document describes spdm_requester_emu and spdm_responder_emu tool. It can b [--meas_op] is the measurement operation in GET_MEASUREMENT. By default, ONE_BY_ONE is used. [--meas_att] is the measurement attribute in GET_MEASUREMENT. By default, HASH is used. [--key_upd] is the key update operation in KEY_UPDATE. By default, ALL is used. RSP will trigger encapsulated KEY_UPDATE. - [--slot_id] is to select the peer slot ID in GET_MEASUREMENT, CHALLENGE_AUTH, KEY_EXCHANGE and FINISH. By default, 0 is used. + [--slot_id] is to select the responder slot ID in GET_MEASUREMENT, CHALLENGE_AUTH and KEY_EXCHANGE. By default, 0 is used. + [--req_slot_id] is to select the requester slot ID in KEY_EXCHANGE_RSP and FINISH. By default, 0 is used. 0xFF can be used to indicate provisioned certificate chain. No GET_CERTIFICATE is needed. [--slot_count] is to select the local slot count. By default, 3 is used. And the slot store cert chain continuously in emu. [--save_state] is to save the current negotiated state to a write-only file. diff --git a/spdm_emu/spdm_emu_common/key.c b/spdm_emu/spdm_emu_common/key.c index c64172f..c678fd1 100644 --- a/spdm_emu/spdm_emu_common/key.c +++ b/spdm_emu/spdm_emu_common/key.c @@ -89,6 +89,7 @@ uint8_t m_use_measurement_operation = uint8_t m_use_measurement_attribute = 0; uint8_t m_use_slot_id = 0; uint8_t m_use_slot_count = 3; +uint8_t m_use_req_slot_id = 0; /* * LIBSPDM_KEY_UPDATE_ACTION_REQUESTER diff --git a/spdm_emu/spdm_emu_common/spdm_emu.c b/spdm_emu/spdm_emu_common/spdm_emu.c index f5eb346..60c0dfc 100644 --- a/spdm_emu/spdm_emu_common/spdm_emu.c +++ b/spdm_emu/spdm_emu_common/spdm_emu.c @@ -67,6 +67,7 @@ void print_usage(const char *name) printf(" [--key_upd REQ|ALL|RSP]\n"); printf(" [--slot_id <0~7|0xFF>]\n"); printf(" [--slot_count <1~8>]\n"); + printf(" [--req_slot_id <0~7|0xFF>]\n"); printf(" [--save_state ]\n"); printf(" [--load_state ]\n"); printf(" [--exe_mode SHUTDOWN|CONTINUE]\n"); @@ -119,7 +120,9 @@ void print_usage(const char *name) printf( " [--key_upd] is the key update operation in KEY_UPDATE. By default, ALL is used. RSP will trigger encapsulated KEY_UPDATE.\n"); printf( - " [--slot_id] is to select the peer slot ID in GET_MEASUREMENT, CHALLENGE_AUTH, KEY_EXCHANGE and FINISH. By default, 0 is used.\n"); + " [--slot_id] is to select the responder slot ID in GET_MEASUREMENT, CHALLENGE_AUTH and KEY_EXCHANGE. By default, 0 is used.\n"); + printf( + " [--req_slot_id] is to select the requester slot ID in KEY_EXCHANGE_RSP and FINISH. By default, 0 is used.\n"); printf( " 0xFF can be used to indicate provisioned certificate chain. No GET_CERTIFICATE is needed.\n"); printf( @@ -1124,6 +1127,29 @@ void process_args(char *program_name, int argc, char *argv[]) } } + if (strcmp(argv[0], "--req_slot_id") == 0) { + if (argc >= 2) { + if (!get_value_from_name( + m_slot_id_string_table, + LIBSPDM_ARRAY_SIZE(m_slot_id_string_table), + argv[1], &data32)) { + printf("invalid --req_slot_id %s\n", + argv[1]); + print_usage(program_name); + exit(0); + } + m_use_req_slot_id = (uint8_t)data32; + printf("req_slot_id - 0x%02x\n", m_use_req_slot_id); + argc -= 2; + argv += 2; + continue; + } else { + printf("invalid --req_slot_id\n"); + print_usage(program_name); + exit(0); + } + } + if (strcmp(argv[0], "--save_state") == 0) { if (argc >= 2) { m_save_state_file_name = argv[1]; diff --git a/spdm_emu/spdm_emu_common/spdm_emu.h b/spdm_emu/spdm_emu_common/spdm_emu.h index 87e30f7..57e4138 100644 --- a/spdm_emu/spdm_emu_common/spdm_emu.h +++ b/spdm_emu/spdm_emu_common/spdm_emu.h @@ -37,6 +37,7 @@ extern uint8_t m_use_measurement_operation; extern uint8_t m_use_measurement_attribute; extern uint8_t m_use_slot_id; extern uint8_t m_use_slot_count; +extern uint8_t m_use_req_slot_id; extern bool g_private_key_mode; #define ENCAP_KEY_UPDATE 0x8000 diff --git a/spdm_emu/spdm_requester_emu/spdm_requester_spdm.c b/spdm_emu/spdm_requester_emu/spdm_requester_spdm.c index 2cdb389..e408c2a 100644 --- a/spdm_emu/spdm_requester_emu/spdm_requester_spdm.c +++ b/spdm_emu/spdm_requester_emu/spdm_requester_spdm.c @@ -272,7 +272,7 @@ void *spdm_client_init(void) libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_CT_EXPONENT, ¶meter, &data8, sizeof(data8)); data32 = m_use_requester_capability_flags; - if (m_use_slot_id == 0xFF) { + if (m_use_req_slot_id == 0xFF) { data32 |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP; data32 &= ~SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP; data32 &= ~SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP; @@ -435,7 +435,7 @@ void *spdm_client_init(void) if ((m_use_requester_capability_flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP) != 0) { - m_use_slot_id = 0xFF; + m_use_req_slot_id = 0xFF; } if (((m_exe_connection & EXE_CONNECTION_CERT) == 0) && (m_use_slot_id != 0xFF)) { m_exe_connection &= ~EXE_CONNECTION_CHAL; @@ -443,6 +443,10 @@ void *spdm_client_init(void) m_exe_session &= ~EXE_SESSION_KEY_EX; m_exe_session &= ~EXE_SESSION_MEAS; } + + printf("slot_id - %x\n", m_use_slot_id); + printf("req_slot_id - %x\n", m_use_req_slot_id); + if (m_use_slot_id == 0xFF) { res = libspdm_read_responder_public_key(m_use_asym_algo, &data, &data_size); if (res) { @@ -458,20 +462,6 @@ void *spdm_client_init(void) m_spdm_context = NULL; return NULL; } - res = libspdm_read_requester_public_key(m_use_req_asym_algo, &data, &data_size); - if (res) { - libspdm_zero_mem(¶meter, sizeof(parameter)); - parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_PUBLIC_KEY, - ¶meter, data, data_size); - /* Do not free it.*/ - } else { - printf("read_requester_public_key fail!\n"); - free(m_spdm_context); - m_spdm_context = NULL; - return NULL; - } } else { res = libspdm_read_responder_root_public_certificate(m_use_hash_algo, m_use_asym_algo, @@ -518,42 +508,61 @@ void *spdm_client_init(void) } } - if (m_use_req_asym_algo != 0) { - res = libspdm_read_requester_public_certificate_chain(m_use_hash_algo, - m_use_req_asym_algo, - &data, &data_size, NULL, - NULL); - if (res) { - libspdm_zero_mem(¶meter, sizeof(parameter)); - parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; - - for (index = 0; index < m_use_slot_count; index++) { - parameter.additional_data[0] = index; + if (m_use_req_slot_id == 0xFF) { + if (m_use_req_asym_algo != 0) { + res = libspdm_read_requester_public_key(m_use_req_asym_algo, &data, &data_size); + if (res) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN, + LIBSPDM_DATA_LOCAL_PUBLIC_KEY, ¶meter, data, data_size); - data8 = (uint8_t)(0xB0 + index); - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_KEY_PAIR_ID, - ¶meter, &data8, sizeof(data8)); - data8 = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT; - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_CERT_INFO, - ¶meter, &data8, sizeof(data8)); - data16 = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE | - SPDM_KEY_USAGE_BIT_MASK_CHALLENGE_USE | - SPDM_KEY_USAGE_BIT_MASK_MEASUREMENT_USE | - SPDM_KEY_USAGE_BIT_MASK_ENDPOINT_INFO_USE; - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK, - ¶meter, &data16, sizeof(data16)); + /* Do not free it.*/ + } else { + printf("read_requester_public_key fail!\n"); + free(m_spdm_context); + m_spdm_context = NULL; + return NULL; + } + } + } else { + if (m_use_req_asym_algo != 0) { + res = libspdm_read_requester_public_certificate_chain(m_use_hash_algo, + m_use_req_asym_algo, + &data, &data_size, NULL, + NULL); + if (res) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + + for (index = 0; index < m_use_slot_count; index++) { + parameter.additional_data[0] = index; + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN, + ¶meter, data, data_size); + data8 = (uint8_t)(0xB0 + index); + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_KEY_PAIR_ID, + ¶meter, &data8, sizeof(data8)); + data8 = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT; + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_CERT_INFO, + ¶meter, &data8, sizeof(data8)); + data16 = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE | + SPDM_KEY_USAGE_BIT_MASK_CHALLENGE_USE | + SPDM_KEY_USAGE_BIT_MASK_MEASUREMENT_USE | + SPDM_KEY_USAGE_BIT_MASK_ENDPOINT_INFO_USE; + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK, + ¶meter, &data16, sizeof(data16)); + } + /* do not free it*/ + } else { + printf("read_requester_public_certificate_chain fail!\n"); + free(m_spdm_context); + m_spdm_context = NULL; + return NULL; } - /* do not free it*/ - } else { - printf("read_requester_public_certificate_chain fail!\n"); - free(m_spdm_context); - m_spdm_context = NULL; - return NULL; } } diff --git a/spdm_emu/spdm_responder_emu/spdm_responder_spdm.c b/spdm_emu/spdm_responder_emu/spdm_responder_spdm.c index 80e4236..80bb036 100644 --- a/spdm_emu/spdm_responder_emu/spdm_responder_spdm.c +++ b/spdm_emu/spdm_responder_emu/spdm_responder_spdm.c @@ -407,73 +407,86 @@ void spdm_server_connection_state_callback( libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &data32, &data_size); - if ((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP) == 0) { - res = libspdm_read_responder_public_certificate_chain(m_use_hash_algo, - m_use_asym_algo, - &data, &data_size, - NULL, NULL); + if ((m_use_responder_capability_flags & + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP) != 0) { + m_use_slot_id = 0xFF; + } + if ((m_use_requester_capability_flags & + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP) != 0) { + m_use_req_slot_id = 0xFF; + } + + printf("slot_id - %x\n", m_use_slot_id); + printf("req_slot_id - %x\n", m_use_req_slot_id); + + if (m_use_slot_id == 0xFF) { + res = libspdm_read_responder_public_key(m_use_asym_algo, &data, &data_size); + if (res) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_PUBLIC_KEY, + ¶meter, data, data_size); + /* Do not free it.*/ + } } else { - res = libspdm_read_responder_public_certificate_chain_alias_cert( + if ((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP) == 0) { + res = libspdm_read_responder_public_certificate_chain( + m_use_hash_algo, + m_use_asym_algo, + &data, &data_size, + NULL, NULL); + } else { + res = libspdm_read_responder_public_certificate_chain_alias_cert( + m_use_hash_algo, + m_use_asym_algo, + &data, &data_size, + NULL, NULL); + } + + res = libspdm_read_responder_public_certificate_chain_per_slot( + 1, m_use_hash_algo, m_use_asym_algo, - &data, &data_size, + &data1, &data1_size, NULL, NULL); - } - - res = libspdm_read_responder_public_certificate_chain_per_slot(1, - m_use_hash_algo, - m_use_asym_algo, - &data1, &data1_size, - NULL, NULL); - if (res) { - libspdm_zero_mem(¶meter, sizeof(parameter)); - parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; - - for (index = 0; index < m_use_slot_count; index++) { - parameter.additional_data[0] = index; - if (index == 1) { + if (res) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + + for (index = 0; index < m_use_slot_count; index++) { + parameter.additional_data[0] = index; + if (index == 1) { + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN, + ¶meter, data1, data1_size); + } else { + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN, + ¶meter, data, data_size); + } + data8 = (uint8_t)(0xA0 + index); libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN, - ¶meter, data1, data1_size); - } else { + LIBSPDM_DATA_LOCAL_KEY_PAIR_ID, + ¶meter, &data8, sizeof(data8)); + data8 = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT; libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN, - ¶meter, data, data_size); + LIBSPDM_DATA_LOCAL_CERT_INFO, + ¶meter, &data8, sizeof(data8)); + data16 = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE | + SPDM_KEY_USAGE_BIT_MASK_CHALLENGE_USE | + SPDM_KEY_USAGE_BIT_MASK_MEASUREMENT_USE | + SPDM_KEY_USAGE_BIT_MASK_ENDPOINT_INFO_USE; + libspdm_set_data(spdm_context, + LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK, + ¶meter, &data16, sizeof(data16)); } - data8 = (uint8_t)(0xA0 + index); - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_KEY_PAIR_ID, - ¶meter, &data8, sizeof(data8)); - data8 = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT; - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_CERT_INFO, - ¶meter, &data8, sizeof(data8)); - data16 = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE | - SPDM_KEY_USAGE_BIT_MASK_CHALLENGE_USE | - SPDM_KEY_USAGE_BIT_MASK_MEASUREMENT_USE | - SPDM_KEY_USAGE_BIT_MASK_ENDPOINT_INFO_USE; - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK, - ¶meter, &data16, sizeof(data16)); + /* do not free it*/ } - /* do not free it*/ } - if (m_use_req_asym_algo != 0) { - if ((m_use_responder_capability_flags & - SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP) != 0) { - m_use_slot_id = 0xFF; - } - if (m_use_slot_id == 0xFF) { - res = libspdm_read_responder_public_key(m_use_asym_algo, &data, &data_size); - if (res) { - libspdm_zero_mem(¶meter, sizeof(parameter)); - parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; - libspdm_set_data(spdm_context, - LIBSPDM_DATA_LOCAL_PUBLIC_KEY, - ¶meter, data, data_size); - /* Do not free it.*/ - } + if (m_use_req_slot_id == 0xFF) { + if (m_use_req_asym_algo != 0) { res = libspdm_read_requester_public_key(m_use_req_asym_algo, &data, &data_size); if (res) { libspdm_zero_mem(¶meter, sizeof(parameter)); @@ -483,7 +496,9 @@ void spdm_server_connection_state_callback( ¶meter, data, data_size); /* Do not free it.*/ } - } else { + } + } else { + if (m_use_req_asym_algo != 0) { res = libspdm_read_requester_root_public_certificate( m_use_hash_algo, m_use_req_asym_algo, &data, &data_size, &hash, &hash_size); @@ -501,22 +516,24 @@ void spdm_server_connection_state_callback( /* Do not free it.*/ } } + } + if (m_use_req_asym_algo != 0) { if (res) { - if (m_use_slot_id == 0xFF) { + if (m_use_req_slot_id == 0xFF) { /* 0xFF slot is only allowed in */ m_use_mut_auth = SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED; } data8 = m_use_mut_auth; parameter.additional_data[0] = - m_use_slot_id; /* req_slot_id;*/ + m_use_req_slot_id; /* req_slot_id;*/ libspdm_set_data(spdm_context, LIBSPDM_DATA_MUT_AUTH_REQUESTED, ¶meter, &data8, sizeof(data8)); data8 = m_use_basic_mut_auth; parameter.additional_data[0] = - m_use_slot_id; /* req_slot_id;*/ + m_use_req_slot_id; /* req_slot_id;*/ libspdm_set_data(spdm_context, LIBSPDM_DATA_BASIC_MUT_AUTH_REQUESTED, ¶meter, &data8, sizeof(data8));