OpenSSL гостевая проблема двигателя - PullRequest
3 голосов
/ 11 января 2012

Я пытаюсь реализовать обмен ключами ECDH по ГОСТ 34.10-2001 с использованием OpenSSL 1.0.0d. Я загружаю гост двигатель, как это:

    ENGINE * e = ENGINE_by_id("gost");

    if(!e)
    {
        e = ENGINE_by_id("dynamic");
        if (!e)
        {
            ENGINE_load_dynamic();
            e = ENGINE_by_id("dynamic");
        }

        if (e && (!ENGINE_ctrl_cmd_string(e, "SO_PATH", "gost", 0) || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)))
            return 1;
    }

    if(!ENGINE_init(e))
        return 1;

    ENGINE_set_default(e, ENGINE_METHOD_ALL);
    OpenSSL_add_all_algorithms();

На данный момент двигатель ГОСТ загружен и работает нормально (я так думаю). Я провел несколько тестов с алгоритмами хеширования и шифрования.

Но когда я пытаюсь реализовать ECDH (генерация общего ключа путем импорта открытого ключа другой стороны), я получаю неправильный результат (общий ключ отличается от другой стороны).

Я проверил параметры a, b, p, q, x, y, проверил поток кода, но не могу понять, что не так.

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94
a6
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893
1
8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14

Есть одна вещь: алгоритм VKO 34.10-2001 реализован в openssl \ engine \ ccgost \ gost2001_keyx.c (функция VKO_compute_key), НО, когда я вызываю обобщенную функцию ECDH_compute_key, это не приводит к VKO_compute_key (проверено установка int3 в начале VKO_compute_key).

Я что-то не так понял? Или кто-то может показать пример генерации общего ключа с использованием движка гост из openssl?

1 Ответ

0 голосов
/ 18 февраля 2016

Я знаю, что это старый вопрос, но для некоторых он все еще актуален.

Следующий код прекрасно генерирует общий секрет при использовании механизма ГОСТ.

int get_shared_key(
    EVP_PKEY *priv, 
    EVP_PKEY *peer,     
    unsigned char *ukm, 
    int ukm_size, 
    unsigned char *secret, 
    size_t *secret_len)
{
    int result = 0;
    EVP_PKEY_CTX *ctx = NULL;
    int key_size = 0;

    if((ctx = EVP_PKEY_CTX_new(priv, NULL)) == NULL) 
        goto err;
    if(EVP_PKEY_derive_init(ctx) != 1) 
        goto err;
    if(EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_SET_IV, ukm_size, ukm) != 1) 
        goto err;
    if(EVP_PKEY_derive_set_peer(ctx, peer) != 1) 
        goto err;
    key_size=EVP_PKEY_derive(ctx, NULL, secret_len);
    if(key_size != GOST_R_34_12_2015_KEY_SIZE) 
        goto err;
    if(EVP_PKEY_derive(ctx, secret, secret_len) != 1) 
        goto err;

    result = 1;
    goto end;
err:
    ERR_print_errors_fp(stderr);
end:
    if(ctx)
        EVP_PKEY_CTX_free(ctx);
    return result;
}
...