读写RPLMN等APDU log显示为FF FF FF……问题研究
问题描述:
高通SM4250平台,一同事发现VDF卡写RPLMN等的APDU显示为FF FF FF……,具体代码如下,需要确定是否有问题:
[0xB0EC] OTA LOG 10:25:18.378008 LTE NAS EMM Plain OTA Incoming Message Attach accept Msg
[ 21/ 2] MSG 10:25:18.379722 User Identity Module/High [ uimgen_hal_iso.c 2051] UIM_1: UIM_UPDATE_BIN_MEM_ST - SFI used - 0x1e
[ 21/ 2] MSG 10:25:18.379730 User Identity Module/High [ uimdrv_hal_iso.c 1013] UIM_1: uim_send_command
[0x19B7] LOG 10:25:18.379904 UIM APDU SLOT_1 Type = TX Data = { 00 D6 9E 00 12 }
[0x19B7] LOG 10:25:18.380369 UIM APDU SLOT_1 Type = RX Data = D6
[0x19B7] LOG 10:25:18.380539 UIM APDU SLOT_1 Type = TX Data = { FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 }[ 21/ 2] MSG 10:25:18.416787 User Identity Module/High [ uimgen_hal_iso.c 2051] UIM_1: UIM_UPDATE_BIN_MEM_ST - SFI used - 0xb
[ 21/ 2] MSG 10:25:18.416794 User Identity Module/High [ uimdrv_hal_iso.c 1013] UIM_1: uim_send_command
[0x19B7] LOG 10:25:18.416962 UIM APDU SLOT_1 Type = TX Data = { 00 D6 8B 00 0B }
[0x19B7] LOG 10:25:18.417424 UIM APDU SLOT_1 Type = RX Data = D6
[0x19B7] LOG 10:25:18.417589 UIM APDU SLOT_1 Type = TX Data = { FF FF FF FF FF FF FF FF FF FF 00 }
代码研究:
经研究发现这不是VDF卡特有的问题,所有物理卡都是这样的,是高通对一些卡数据的log打印进行处理导致,实际写入卡或从卡读取的数据是正常的。
uim_tx()函数
void uim_tx
(unsigned char *buffer_ptr,int size,uim_instance_global_type *uim_ptr
)
{int i =0;unsigned char mul =0, rem=0;unsigned int y = 0;if(size <= 0){UIMDRV_MSG_ERR_0(uim_ptr->id,"Invalid size of data while writing to UART");return;}/* FEATURE_UIM_UART_DM_BUS_CONTENTION_FIXIf UIM tries to write to NO_CHARS_FOR_TX register andimmediately afterwards to the TX register, these 2 commandscould be written to UART_DM as a burst on its AHB bus.causing the 2nd command’s data (first 4 bytes) to be left out of the FIFO.Hence UIM needs to read one byte before writing again causing the burst ofwrites to be broken into single writes */(void)UIM_GET_NUM_CHARS_TO_SEND_SLOT(uim_ptr);if(uim_nv_is_feature_enabled(UIMDRV_FEATURE_DEBUG_LOG,uim_ptr) == TRUE){/* Logging of extended packtes */if(uim_ptr->rxtx_state_machine.rx_state == UIM_RX_RECEIVE_PPS){uim_log_put_pps_data(TRUE, (uint8 *)buffer_ptr, size, uim_ptr);}else{ //APDU log 显示为FF FF FF……是在这里处理的:uim_log_put_apdu_data(TRUE, TRUE, (uint8 *)buffer_ptr, size, uim_ptr);}}mul = size/4;rem = size%4;/* This adds 100usec delay ro be sure there is no contention on AHB bus */uim_clk_busy_wait(100);//实际发送到卡里的数据在这里处理,并不是FF FF FF……/* Send that many words */if(mul > 0){for (i=0; i<mul; i++){y = (buffer_ptr[i*4+3] << 24) | (buffer_ptr[i*4+2] << 16) | (buffer_ptr[i*4+1] << 8) | (buffer_ptr[i*4]);UIM_SEND_TX_FIFO_SLOT(uim_ptr,y);}}/* Send the remaining bytes packed as a word */if(rem > 0){y = 0;for(i=0; i<rem; i++){y += (buffer_ptr[4*mul+i] << (8*i));}UIM_SEND_TX_FIFO_SLOT(uim_ptr,y);}return;
} /*end uim_tx */
uim_log_put_apdu_data()函数
void uim_log_put_apdu_data(boolean is_tx,boolean is_commit,uint8 *buffer,uint16 buffer_len,uim_instance_global_type *uim_ptr)
{uint8 *temp_buffer = NULL;uint16 offset = 0;if(uim_ptr == NULL || uim_ptr->command.cmd_ptr == NULL ){return;}temp_buffer = &uim_ptr->debug.ext_log_buffer_data.buffer[0];offset = uim_ptr->debug.ext_log_buffer_data.buffer_offset;if(buffer != NULL && offset < UIM_EXT_LOG_MAX_SIZE){uim_memscpy(&temp_buffer[offset],UIM_EXT_LOG_MAX_SIZE - offset,buffer,buffer_len);offset = ((offset + buffer_len) > UIM_EXT_LOG_MAX_SIZE) ? UIM_EXT_LOG_MAX_SIZE : (offset + buffer_len);}if(is_commit && offset > 0){if(is_tx && uim_ptr->command.cmd_ptr->hdr.test_mode_req_log_masking_fn_ptr != NULL){if(uim_ptr->rxtx_state_machine.tx_state == UIM_TX_SND_CMD_DATA){ //写卡的APDU log显示为FF FF FF……就是在这里处理的:uim_ptr->command.cmd_ptr->hdr.test_mode_req_log_masking_fn_ptr(temp_buffer, temp_buffer, offset);}}else if(!is_tx && (uim_ptr->command.cmd_ptr->hdr.test_mode_rsp_log_masking_fn_ptr != NULL) &&(offset > (NUM_ACK_BYTES + NUM_STATUS_BYTES))){ //同样,读出的APDU log显示为FF FF FF……是在这里处理的:uim_ptr->command.cmd_ptr->hdr.test_mode_rsp_log_masking_fn_ptr(temp_buffer+1, temp_buffer+1, offset - (NUM_ACK_BYTES + NUM_STATUS_BYTES));}//这里进行APDU log的打印,具体就略了:uim_log_commit_buffer_ext(is_tx ? UIM_LOG_TX : UIM_LOG_RX,temp_buffer,offset,NULL,NULL,NULL,uim_ptr);#ifdef FEATURE_UIM_APDU_TRANSACTION_LOGGINGuim_log_commit_apdu_buffer_ext(is_tx ? UIM_LOG_TX : UIM_LOG_RX,temp_buffer,offset,NULL,NULL,NULL,uim_ptr);
#endif /* FEATURE_UIM_APDU_TRANSACTION_LOGGING */offset = 0;}uim_ptr->debug.ext_log_buffer_data.buffer_offset = offset;UIMDRV_MSG_ERR_0(uim_ptr->id,"ziran.zhang test uim_log_put_apdu_data() end");
} /* uim_log_put_apdu_data */
test_mode_req_log_masking_fn_ptr的指向
经查uim_cmd_ptr->hdr.test_mode_rsp_log_masking_fn_ptr 是指向 mmgsdi_log_masking_fn_all的:
case UIM_RUN_GSM_ALGO_F:if (is_test_mode_secure_log_enabled == FALSE){uim_cmd_ptr->hdr.test_mode_rsp_log_masking_fn_ptr = mmgsdi_log_masking_fn_all;} return;case UIM_VERIFY_CHV_F:if (is_test_mode_private_log_enabled == FALSE &&strnlen((const char *)uim_cmd_ptr->verify_chv.chv_digits, UIM_MAX_CHV_DIGITS) > 0){uim_cmd_ptr->hdr.test_mode_req_log_masking_fn_ptr = mmgsdi_log_masking_fn_all;}return;
……
mmgsdi_log_masking_fn_all()函数
static boolean mmgsdi_log_masking_fn_all(const uint8 *input_ptr,uint8 *output_ptr,uint32 length
)
{if (input_ptr == NULL || output_ptr == NULL || length == 0){return FALSE;}memset(output_ptr, 0xFF, length);return TRUE;
} /* mmgsdi_log_masking_fn_all */
可见经过mmgsdi_log_masking_fn_all()函数的处理APDU 的log打印就显示为FF FF FF……了。
结论:
读写一些卡文件,APDU log显示为FF FF FF……是高通对安全或私密数据在log打印上的处理,实际写入卡的或从卡里读取的数据不是这样的;只是显示上的问题,实际上没问题的。