解析ECC私钥缓冲区

时间:2019-02-19 11:12:18

标签: mbedtls op-tee

我正在使用OPTEE-OS和mbedTLS,并想创建一个CSR。我正在使用Global Platform API创建EC密钥:

res = TEE_AllocateTransientObject(
    TEE_TYPE_ECDSA_KEYPAIR,
    DSEC_ECDSA_SHA256_KEY_BITS,
    &key_pair);
if (res != TEE_SUCCESS) {
    return res;
}

然后提取私钥:

res = TEE_GetObjectBufferAttribute(
    key_pair,
    TEE_ATTR_ECC_PRIVATE_VALUE,
    buffer,
    &bufferlen);
if (res != TEE_SUCCESS) {
    return res;
}

然后使用mbedTLS解析此值并创建一个以创建CSR:

mbedtls_pk_context priv_key;
mbedtls_pk_init(&priv_key);

ret = mbedtls_pk_parse_key(
    &priv_key,
    key,
    size,
    NULL ,
    0
  );

但是,从TEE_GetObjectBufferAttribute提取的值没有标题和足迹:

"-----BEGIN EC PRIVATE KEY-----"
"-----END EC PRIVATE KEY-----"

并且仅是一个二进制数组(不是字符串)。我目前收到以下错误代码:"-15616: PK - Invalid key tag or value".

有什么方法可以仅使用我的私钥的二进制值来创建mbedtls_pk_context吗?

2 个答案:

答案 0 :(得分:1)

Mbed TLS的pk.h中的解析功能需要DER或PEM输入。如果您可以找到现成的代码来从OPTEE中将密钥导出为DER(或PEM),那么会更容易(但可能效率较低)。另一方面,手动编写要比编写DER导出功能容易。

您需要调用mbedtls_pk_setup()声明上下文将包含ECC密钥,然后直接使用ecp.h中的接口来构建ECC密钥。将曲线名称从TEE编码转换为Mbed TLS编码,然后根据私有值计算公钥。 (或者,您可以导出TEE_ATTR_ECC_PUBLIC_VALUE并设置ec->Q,但这需要更多工作。)

mbedtls_ecp_grp_id grp_id = …; // you need to convert this from the `TEE_ATTR_ECC_CURVE`
mbedtls_pk_context pk;
mbedtls_ecp_keypair *ec = malloc(sizeof(mbedtls_ecp_keypair));
mbedtls_pk_init(&pk);
mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA));
mbedtls_ecp_keypair_init(ec);
mbedtls_ecp_group_load(&ec->grp, grp_id);
mbedtls_mpi_read_binary(&ec->d, buffer, bufferlen);
mbedtls_ecp_check_privkey(&ec->grp, &ec->d);
mbedtls_ecp_mul(&ec->grp, &ec->Q, &ec->d, &ec->grp.G, mbedtls_ctr_drbg_random, &ctr_drbg);
pk->pk_ctx = ec;

完全未经测试。省略错误检查。 ctr_drbg是一个CTR_DRBG实例,用于在计算公钥期间造成盲目。

答案 1 :(得分:0)

要添加到接受的答案,这里是如果X和Y可用作缓冲区,则导入Q的代码。而且我猜想这些是可用的,因为要使用GlobalPlatform加密API在OPTEE中创建ECDSA密钥,必须提供所有4个属性(TEE_ATTR_xxx)(d,Q(X,Y)和曲线ID)

rc = mbedtls_mpi_read_binary(&ec->Q.X, buffer_x, buffer_x_size);
rc = mbedtls_mpi_read_binary(&ec->Q.Y, buffer_y, buffer_y_size);
rc = mbedtls_mpi_lset(&ec->Q.Z, 1);
rc = mbedtls_ecp_check_pubkey(&ec->grp, &ec->Q);
相关问题