Разобрать буфер закрытого ключа ECC

Я использую OPTEE-OS и mbedTLS и хочу создать CSR. Я создаю свой ключ EC с использованием API Global Platform:

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 не имеет заголовков и footpage:

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

и это только двоичный массив (не строка). В настоящее время я получаю следующий код ошибки: "-15616: PK - Invalid key tag or value".

Есть ли способ создать mbedtls_pk_context только с двоичным значением моего закрытого ключа?

0 ответов

Функции синтаксического анализа в Mbed TLS pk.h ожидайте вход DER или PEM. Если вы можете найти готовый код для экспорта ключа в виде DER (или PEM) из OPTEE, это будет проще (но, возможно, немного менее эффективно). С другой стороны, проще выполнить импорт вручную, чем написать функцию экспорта DER.

Вам нужно позвонить mbedtls_pk_setup() объявить, что контекст будет содержать ключ ECC, а затем создать ключ ECC напрямую, используя интерфейс в ecp.h, Преобразуйте обозначение кривой из кодировки 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, используемым для ослепления при вычислении открытого ключа.

Чтобы добавить к принятому ответу, вот код для импорта Q, если X и Y доступны в качестве буферов. И я предполагаю, что они доступны, поскольку для создания ключа ECDSA в OPTEE с использованием GlobalPlatform crypto API требуются все 4 атрибута (TEE_ATTR_xxx) (d, Q(X,Y) и идентификатор кривой)

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);
Другие вопросы по тегам