高通QCM2290平台eSIM调试 支持LPA on AP

问题描述:

高通QCM2290平台的项目eSIM调试,发现不通,我这边只知道有modem日志打印:

Request to select AID rejected: AID blacklisted

需要查看原因。

问题分析:

1、NV67312 apdu_security_restrictions

先找到日志打印的地方:

复制代码
static boolean qmi_uim_is_logical_channel_request_rejected
(
  mmgsdi_static_data_type    input_aid
)
{
  uint16                    i                = 0;
  boolean                   is_rejected      = TRUE;
  qmi_uim_aid_entry_type  * temp_aid_ptr     = NULL;

  ASSERT(qmi_uim_global_ptr);

  if (qmi_uim_global_ptr->apdu_sec_restr_value == QMI_UIM_APDU_SEC_RESTRICTIONS_NONE)
  {
    return FALSE;
  }
......
  temp_aid_ptr = qmi_uim_global_ptr->apdu_sec_aid_info.aid_list_ptr;

  /* First check what type of AID list we read from NV */
  if (qmi_uim_global_ptr->apdu_sec_aid_info.aid_list_type == UIM_AID_LIST_BLACK_LIST)
  {
    /* For an empty blacklist, all AIDs are allowed */
    is_rejected  = FALSE;

    /* Loop through the blacklist of AIDs to check these rules:
       1. If AID from EFS, then partial/exact AID matches, requested AID is rejected
       2. If AID is added by QMI UIM, then allow the partial AID only.
       3. If requested AID doesnt match any of the blacklisted AIDs, it is allowed
       4. Empty blacklist means all AIDs are allowed
    */
    for (i = 0;
         (i < qmi_uim_global_ptr->apdu_sec_aid_info.aid_count) && (temp_aid_ptr != NULL);
         i++, temp_aid_ptr++)
    {
      /* First check which of the AIDs is shorter, since we need to
         account for partial AID selection */
      uint16 shortest_aid_len = (uint16)(input_aid.data_len <= temp_aid_ptr->aid.data_len ?
                                          input_aid.data_len : temp_aid_ptr->aid.data_len);

      if (temp_aid_ptr->from_efs == FALSE &&
          temp_aid_ptr->aid.data_len > input_aid.data_len)
      {
        continue;
      }
      if (memcmp(input_aid.data_ptr, temp_aid_ptr->aid.data_ptr, shortest_aid_len) == 0)
      {
        /* Found a match, reject it */
        UIM_MSG_ERR_0("Request to select AID rejected: AID blacklisted");
        return TRUE;
      }
    }
    UIM_MSG_MED_0("Request to select AID accepted: AID not blacklisted");
  }

可以看出如果在刚开始的这里:

if (qmi_uim_global_ptr->apdu_sec_restr_value == QMI_UIM_APDU_SEC_RESTRICTIONS_NONE)

{

return FALSE;

}

就返回了,应该就没有问题了。

qmi_uim_global_ptr->apdu_sec_restr_value的来源是NV67312:

复制代码
<NvEfsItemData name="apdu_security_restrictions" id="67312" description="APDU Security Restrictions" comment="" category="UIM" mcfgAttributes="0x09" mcfgVariant="2" fullpathname="/nv/item_files/modem/qmi/uim/apdu_security_restrictions">		<Member name="apdu_security_restrictions" description="" comment="" sizeOf="1" type="uint8">0 </Member></NvEfsItemData>

查看设备发现是没有这项NV的,默认值是 QMI_UIM_APDU_SEC_RESTRICTIONS_ALL:

复制代码
static void qmi_uim_read_configuration
(
  boolean                                            * silent_pin1_supported_ptr,
  qmi_uim_apdu_sec_restr_type                        * apdu_sec_value_ptr,
  qmi_uimi_apdu_sec_aid_info_type                    * apdu_sec_aid_info_ptr,
  boolean                                            * close_channel_ind_pref_ptr,
  qmi_uim_auth_sec_restr_type                        * auth_sec_restr_value_ptr,
  boolean                                            * sap_sec_restr_supported_ptr,
  qmi_uim_simlock_display_type                       * simlock_display_for_valid_card_ptr
)
{
......
  *apdu_sec_value_ptr                 = QMI_UIM_APDU_SEC_RESTRICTIONS_ALL;

typedef enum

{

  QMI_UIM_APDU_SEC_RESTRICTIONS_NONE   = 0,

  QMI_UIM_APDU_SEC_RESTRICTIONS_ALL    = 1,

  QMI_UIM_APDU_SEC_RESTRICTIONS_II_CLA = 2

} qmi_uim_apdu_sec_restr_type;

如果给设备添加NV67312,并赋值QMI_UIM_APDU_SEC_RESTRICTIONS_NONE,该问题应该能解决。经验证发现这样确实可行,eSIM通了。

查看高通对该NV的描述:
Description:
whitelist: list of AIDs that any client can access. Any AID outside
QMI UIM APDU Security Restrictions.
This NV item has the following values and is used to enforce some security
restrictions in QMI UIM. For example, this NV item prevents AP from:

  1. Streaming MANAGE CHANNEL command.
  2. Streaming SELECT by DF name.
  3. Streaming APDUs on channel 0.
  4. Executing any operation (including APDU streaming) on a channel opened by
    another client.
  5. Opening any application other than USIM, ISIM or CSIM in SAP mode.
    This NV item can be modified only when the terminal is in FTM mode.
    Possible Values:
    0 = Security restrictions are disabled
    1 = Security restrictions are fully enabled (default value)
    2 = Security restrictions are enabled only for inter-industry CLA

可见NV67312在安全上还是有一定作用的,虽然修改NV67312可以调通eSIM,但不推荐。

继续分析。

2、Request to select AID rejected: AID blacklisted

从modem的打印:Request to select AID rejected: AID blacklisted是这里有问题:

复制代码
      if (memcmp(input_aid.data_ptr, temp_aid_ptr->aid.data_ptr, shortest_aid_len) == 0)
      {
        /* Found a match, reject it */
        UIM_MSG_ERR_0("Request to select AID rejected: AID blacklisted");
        return TRUE;
      }

input_aid.data_ptr与temp_aid_ptr->aid.data_ptr匹配上了,而

temp_aid_ptr = qmi_uim_global_ptr->apdu_sec_aid_info.aid_list_ptr;

qmi_uim_global_ptr->apdu_sec_aid_info的来源:

static boolean qmi_uim_service_initialize(void) -->

/* Read configuration for silent PIN1 verification & APDU security restrictions*/

qmi_uim_read_configuration(&qmi_uim_global_ptr->silent_pin1_supported,

&qmi_uim_global_ptr->apdu_sec_restr_value,

&qmi_uim_global_ptr->apdu_sec_aid_info,

&qmi_uim_global_ptr->close_channel_sync,

&qmi_uim_global_ptr->auth_sec_restr_value,

&qmi_uim_global_ptr->sap_sec_restr_supported,

&qmi_uim_global_ptr->simlock_display_for_valid_card);

-->

/* Retrieve APDU security AID list info from NV file */

if (qmi_uim_read_configuration_apdu_aid_list(apdu_sec_aid_info_ptr))

{

success_count++;

}

qmi_uim_global_ptr->apdu_sec_aid_info最终是从这里读取的:

复制代码
static boolean qmi_uim_read_configuration_apdu_aid_list
(
  qmi_uimi_apdu_sec_aid_info_type * apdu_sec_aid_info_ptr
)
{
......
  uint32          alloc_size                            = 0;
  uint8           isdr_aid_initials[]                   = {0xA0, 0x00, 0x00, 0x05,
                                                           0x59, 0x10, 0x10};
......
  /* Read the file. If read fails, means there is no list present.
     We need to block ISDR-AID from AP if the NV 73849 byte 2
     is not set */
  if (uim_common_efs_read(
        UIM_COMMON_EFS_UIMQMI_QMI_UIM_CONFIG_APDU_SEC_AID_LIST,
        UIM_COMMON_EFS_ITEM_FILE_TYPE,
        UIM_COMMON_EFS_DEVICE,
        aid_list_file_data_ptr,
        aid_list_file_data_len)!= UIM_COMMON_EFS_SUCCESS)
  {
    UIM_MSG_ERR_0( "Error in efs_get for APDU security AID list");
    uimqmi_free(aid_list_file_data_ptr);
    aid_list_file_data_ptr = NULL;
    apdu_sec_aid_info_ptr->aid_list_type = UIM_AID_LIST_BLACK_LIST;
    isdr_add_in_list = UIM_AID_LIST_BLACK_LIST;
  }
  else
  {
......
  }
......
  /* Allocate memory based on the number of AID entries. 1 extra entry space
     is allocated for ISD-R in case of Blacklist because access to ISD-R is
     only through LPA module. Add ISD-R AID in Blacklist explicitly.
     ISD-R AID: A0 00 00 05 59 10 10 FF FF FF FF 89 00 00 01 00 */
  alloc_size = apdu_sec_aid_info_ptr->aid_count * sizeof(qmi_uim_aid_entry_type);

  /* Check LPA support EFS. Byte 2 determines whether LPA functionality
     is controlled by APPs or not. If yes, then ISDR needs to be added
     in Whitelist. If No, then ISDR needs to be added in Blacklist */
  lpa_is_lpa_supported(NULL, NULL, NULL, NULL, &lpa_modem_solution);

  if (lpa_modem_solution == FALSE)
  {
    isdr_add_in_list  = UIM_AID_LIST_WHITE_LIST;
  }
  else
  {
    isdr_add_in_list  = UIM_AID_LIST_BLACK_LIST;
  }

  if ((apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_BLACK_LIST &&
       isdr_add_in_list == UIM_AID_LIST_BLACK_LIST)                         ||
      (apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_WHITE_LIST &&
       isdr_add_in_list == UIM_AID_LIST_WHITE_LIST))
  {
    alloc_size += sizeof(qmi_uim_aid_entry_type);
  }

  if (alloc_size == 0)
  {
    if(aid_list_file_data_ptr != NULL)
    {
      uimqmi_free(aid_list_file_data_ptr);
    }
    return FALSE;
  }
  apdu_sec_aid_info_ptr->aid_list_ptr = uimqmi_malloc(alloc_size);
......
  if ((apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_BLACK_LIST &&
         isdr_add_in_list == UIM_AID_LIST_BLACK_LIST)                         ||
        (apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_WHITE_LIST &&
         isdr_add_in_list == UIM_AID_LIST_WHITE_LIST))
  {
    apdu_sec_aid_info_ptr->aid_list_ptr[j].aid.data_len = sizeof(isdr_aid_initials);
    (void)memscpy((void *)apdu_sec_aid_info_ptr->aid_list_ptr[j].aid.data_ptr,
                  sizeof(apdu_sec_aid_info_ptr->aid_list_ptr[j].aid.data_ptr),
                  (void *)isdr_aid_initials,
                  sizeof(isdr_aid_initials));
    apdu_sec_aid_info_ptr->aid_list_ptr[j].from_efs = FALSE;

    apdu_sec_aid_info_ptr->aid_count++;
  }

  return is_read_from_efs;
} /* qmi_uim_read_configuration_apdu_aid_list */

UIM_COMMON_EFS_UIMQMI_QMI_UIM_CONFIG_APDU_SEC_AID_LIST是

<NvEfsFile name="apdu_security_aid_list" id="67317" description="APDU Security AID List" comment="" category="UIM" subscription_mask="0x07" mcfgAttributes="0x19" mcfgVariant="2" targetPath="/nv/item_files/modem/qmi/uim/apdu_security_aid_list" buildPath="modem_proc/uim/config/efs_files/apdu_security_aid_list"/>

查看设备里没有这项NV,可见代码进入到这里:

复制代码
  if (uim_common_efs_read(
        UIM_COMMON_EFS_UIMQMI_QMI_UIM_CONFIG_APDU_SEC_AID_LIST,
        UIM_COMMON_EFS_ITEM_FILE_TYPE,
        UIM_COMMON_EFS_DEVICE,
        aid_list_file_data_ptr,
        aid_list_file_data_len)!= UIM_COMMON_EFS_SUCCESS)
  {
    UIM_MSG_ERR_0( "Error in efs_get for APDU security AID list");
    uimqmi_free(aid_list_file_data_ptr);
    aid_list_file_data_ptr = NULL;
    apdu_sec_aid_info_ptr->aid_list_type = UIM_AID_LIST_BLACK_LIST;
    isdr_add_in_list = UIM_AID_LIST_BLACK_LIST;
  }

代码也肯定没在这里返回(return FALSE):

复制代码
  /* Check LPA support EFS. Byte 2 determines whether LPA functionality
     is controlled by APPs or not. If yes, then ISDR needs to be added
     in Whitelist. If No, then ISDR needs to be added in Blacklist */
  lpa_is_lpa_supported(NULL, NULL, NULL, NULL, &lpa_modem_solution);

  if (lpa_modem_solution == FALSE)
  {
    isdr_add_in_list  = UIM_AID_LIST_WHITE_LIST;
  }
  else
  {
    isdr_add_in_list  = UIM_AID_LIST_BLACK_LIST;
  }

  if ((apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_BLACK_LIST &&
       isdr_add_in_list == UIM_AID_LIST_BLACK_LIST)                         ||
      (apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_WHITE_LIST &&
       isdr_add_in_list == UIM_AID_LIST_WHITE_LIST))
  {
    alloc_size += sizeof(qmi_uim_aid_entry_type);
  }

  if (alloc_size == 0)
  {
    if(aid_list_file_data_ptr != NULL)
    {
      uimqmi_free(aid_list_file_data_ptr);
    }
    return FALSE;
  }
apdu_sec_aid_info_ptr->aid_list_ptr = uimqmi_malloc(alloc_size);

因为前面代码进入了这里:

复制代码
static boolean qmi_uim_is_logical_channel_request_rejected
(
  mmgsdi_static_data_type    input_aid
)
{
......
  if (qmi_uim_global_ptr->apdu_sec_aid_info.aid_list_type == UIM_AID_LIST_BLACK_LIST)
  {
......
      if (memcmp(input_aid.data_ptr, temp_aid_ptr->aid.data_ptr, shortest_aid_len) == 0)
      {
        /* Found a match, reject it */
        UIM_MSG_ERR_0("Request to select AID rejected: AID blacklisted");
        return TRUE;
      }

说明temp_aid_ptr->aid.data_ptr是有值的也就是apdu_sec_aid_info_ptr->aid_list_ptr是有值的,说明alloc_size != 0。代码肯定进入到了这里:

复制代码
  if ((apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_BLACK_LIST &&
       isdr_add_in_list == UIM_AID_LIST_BLACK_LIST)                         ||
      (apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_WHITE_LIST &&
       isdr_add_in_list == UIM_AID_LIST_WHITE_LIST))
  {
    alloc_size += sizeof(qmi_uim_aid_entry_type);
  }

因为qmi_uim_is_logical_channel_request_rejected()的

qmi_uim_global_ptr->apdu_sec_aid_info.aid_list_type == UIM_AID_LIST_BLACK_LIST,则这里

apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_BLACK_LIST,从而

isdr_add_in_list == UIM_AID_LIST_BLACK_LIST

从而可反推出这里:

复制代码
  lpa_is_lpa_supported(NULL, NULL, NULL, NULL, &lpa_modem_solution);

  if (lpa_modem_solution == FALSE)
  {
    isdr_add_in_list  = UIM_AID_LIST_WHITE_LIST;
  }
  else
  {
    isdr_add_in_list  = UIM_AID_LIST_BLACK_LIST;
  }

的lpa_modem_solution == TRUE。查看函数lpa_is_lpa_supported():

复制代码
void lpa_is_lpa_supported(
  boolean                            *lpdd_supported_ptr,
  boolean                            *luid_supported_ptr,
  boolean                            *ldsd_supported_ptr,
  boolean                            *luie_supported_ptr,
  boolean                            *modem_lpa_supported_ptr
)
{
......
  boolean                      modem_lpa_support         = TRUE;

......
  if ((uim_common_efs_read(UIM_COMMON_EFS_LPA_SUPPORT,
                           UIM_COMMON_EFS_ITEM_FILE_TYPE,
                           efs_context,
                           (uint8 *)lpa_support_nv_content,
                           sizeof(lpa_support_nv_content)) == UIM_COMMON_EFS_SUCCESS))
  {
    if(lpa_support_nv_content[UIM_COMMON_LPA_EFS_ITEM_LPA_ON_AP_OR_MODEM_INDEX] != 0x00)
    {
      lpdd_support      = FALSE;
      luid_support      = FALSE;
      ldsd_support      = FALSE;
      luie_support      = FALSE;
      modem_lpa_support = FALSE;
    }
    else
    {
......
    }
  }

  if(modem_lpa_supported_ptr != NULL)
  {
    *modem_lpa_supported_ptr = modem_lpa_support;
  }
} /* lpa_is_lpa_supported */

UIM_COMMON_EFS_LPA_SUPPORT是:

<NvEfsFile name="lpa_support" id="73849" description="LPA Support" comment="" category="UIM" mcfgAttributes="0x09" mcfgVariant="2" targetPath="/nv/item_files/modem/uim/lpa/lpa_support" buildPath="modem_proc/uim/config/efs_files/hw_settings/lpa_support"/>

只有这个NV读取失败*modem_lpa_supported_ptr的返回值才是TRUE。而查看设备也确实没有这项NV。这最终导致在函数的qmi_uim_read_configuration_apdu_aid_list()的后面:

复制代码
  if ((apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_BLACK_LIST &&
         isdr_add_in_list == UIM_AID_LIST_BLACK_LIST)                         ||
        (apdu_sec_aid_info_ptr->aid_list_type == UIM_AID_LIST_WHITE_LIST &&
         isdr_add_in_list == UIM_AID_LIST_WHITE_LIST))
  {
    apdu_sec_aid_info_ptr->aid_list_ptr[j].aid.data_len = sizeof(isdr_aid_initials);
    (void)memscpy((void *)apdu_sec_aid_info_ptr->aid_list_ptr[j].aid.data_ptr,
                  sizeof(apdu_sec_aid_info_ptr->aid_list_ptr[j].aid.data_ptr),
                  (void *)isdr_aid_initials,
                  sizeof(isdr_aid_initials));
    apdu_sec_aid_info_ptr->aid_list_ptr[j].from_efs = FALSE;

    apdu_sec_aid_info_ptr->aid_count++;
  }

  return is_read_from_efs;
} /* qmi_uim_read_configuration_apdu_aid_list */

添加了一个isdr_aid_initials到apdu_sec_aid_info_ptr->aid_list_ptr,相当于从EFS读到了isdr_aid_initials\[\] = {0xA0, 0x00, 0x00, 0x05, 0x59, 0x10, 0x10};这就是黑名单,只要

static boolean qmi_uim_is_logical_channel_request_rejected

(

mmgsdi_static_data_type input_aid

)这里传入的input_aid和isdr_aid_initials匹配上就拒绝接入。

3、为什么会有黑名单机制

为什么会有黑名单机制,把这段代码注释:

/* Allocate memory based on the number of AID entries. 1 extra entry space

is allocated for ISD-R in case of Blacklist because access to ISD-R is

only through LPA module. Add ISD-R AID in Blacklist explicitly.

ISD-R AID: A0 00 00 05 59 10 10 FF FF FF FF 89 00 00 01 00 */

发给豆包,让解释一下,得到:

这段话是高通 eSIM(euicc)AID 黑名单内存分配 + 安全策略的核心逻辑,我给你用通俗 + 专业双语讲清楚:


逐句翻译

plaintext

复制代码
Allocate memory based on the number of AID entries.
根据AID条目的数量分配内存空间。

1 extra entry space is allocated for ISD-R in case of Blacklist
黑名单场景下,**额外多分配1个条目空间给 ISD-R**

because access to ISD-R is only through LPA module.
因为**只有 LPA 模块允许访问 ISD-R**(其他模块都禁止)

Add ISD-R AID in Blacklist explicitly.
必须**显式把 ISD-R 的AID加入黑名单**

ISD-R AID: A0 00 00 05 59 10 10 FF FF FF FF 89 00 00 01 00
这是固定的 ISD-R 标准AID值

真正含义(关键点)

  1. 这是eSIM 安全锁
  • ISD-R = eUICC 卡的根安全域(eSIM 最高权限控制区)
  • LPA = 唯一能操作 eSIM 配置文件的系统模块(eSIM 管理器)
  • 系统设计目的:除了 LPA,任何人都不能碰 ISD-R
  1. 为什么要额外分配内存?

黑名单本来只存你配置的 AID但代码强制多留一个位置 专门给 ISD-R AID 使用

  1. 为什么要把 ISD-R 加入黑名单?
  • 把 ISD-R 加入黑名单 = 禁止 AP/Modem 其他模块访问它
  • 只有 LPA 可以绕过黑名单访问 ISD-R
  • 这是GSMA eSIM 标准安全要求
  1. 这个固定 AID 是什么?

plaintext

复制代码
A0 00 00 05 59 10 10 FF FF FF FF 89 00 00 01 00

这是 全球统一的 eUICC ISD-R 标准 AID所有品牌 eSIM 卡都用这个值。


总结(最简版)

这段代码的意思:为了 eSIM 安全,必须把 ISD-R(eSIM 根权限)加入黑名单,只允许 LPA 访问;内存分配时要专门多留一个位置给它。

4、LPA Support

从上面分析可知,为了 eSIM 安全,必须把 ISD-R(eSIM 根权限)加入黑名单,只允许 LPA 访问。 而设备的lpa_support NV/EFS是不存在的,因此设备不允许访问ISD-R。

只要把lpa_support的NV/EFS:

<NvEfsFile name="lpa_support" id="73849" description="LPA Support" comment="" category="UIM" mcfgAttributes="0x09" mcfgVariant="2" targetPath="/nv/item_files/modem/uim/lpa/lpa_support" buildPath="modem_proc/uim/config/efs_files/hw_settings/lpa_support"/>

添加到设备,问题应能得到解决;

添加lpa_support的NV/EFS后验证,eSIM确实通了。

解决方案:

modem_proc/uim/config/groups/common/SDM450/mcfg_hw_gen_SR_DSDS-LA-7+7_mode.xml添加

<NvEfsFile name="lpa_support" id="73849" description="LPA Support" comment="" category="UIM" mcfgAttributes="0x09" mcfgVariant="2" targetPath="/nv/item_files/modem/uim/lpa/lpa_support" buildPath="modem_proc/uim/config/efs_files/hw_settings/lpa_support"/>

相关推荐
物联通信量讯说15 天前
AI-eSIM 开启智联新入口,量讯物联助力企业把握万物智联新机遇
物联网·iot·esim
缘于自然816 天前
高通modem如何确认device_config.xml的使用路径
xml·modem·mbn·mcfg
月光技术杂谈1 个月前
拆解中国移动AI-eSIM:当一张SIM卡开始“调用大模型”,运营商到底在赌什么?
人工智能·esim·安全认证·中国移动·ai-esim·tocken·大模型调度
CHHC18801 个月前
eSIM SGP32/SGP22 EUICC.SDK - IPAd
ipad·esim·sgp32
缘于自然83 个月前
高通modem如何确定MBN选的是哪个carrier_policy.xml
xml·modem·mbn
巍巍泰然5 个月前
VSIM,SOFTSIM,eSIM,USIM的对比及通用架构思考(一)
ps·esim·lte·sim·softsim·vsim
大龙谈智能内容9 个月前
eSIM时代来临!iPhone Air引爆无卡化革命
iphone·esim·iphoneair·esim手机
___波子 Pro Max.1 年前
Cat.1与Cat.4区别及应用场景
modem
zyq~1 年前
【课堂笔记】标签传播算法Label Propagation Algorithm(LPA)
人工智能·笔记·算法·机器学习·概率论·lpa·半监督学习