Как реализовать программное поточное хеширование?

Здравствуйте. Знаю такие функции:

C_DigestInit(), C_DigestUpdate(), C_DigestFinal()

на сколько я понял - они реализуют аппаратное хеширование на токене. Как я могу реализовать поточное хеширование не на борту токена, а программно? Аппаратное хеширование уж очень долгое. Буду рад любой помощи, спасибо.

Re: Как реализовать программное поточное хеширование?

Binger, здравствуйте!

Программное хеширование реализуется c помощью C_DigestInit\C_Digest, если в качестве CK_MECHANISM передать:

CK_MECHANISM gostR3411_2012_256HashMech = { CKM_GOSTR3411_12_256, parametersGostR3411_2012_256, sizeof(parametersGostR3411_2012_256)};
 
CK_MECHANISM gostR3411_2012_512HashMech = { CKM_GOSTR3411_12_512, parametersGostR3411_2012_512, sizeof(parametersGostR3411_2012_512)};

Для программного подсчета хеша, нужно вычислять хеш с помощью функций C_DigestInit и C_Diigest, а затем только звать C_Sign:

CK_MECHANISM gostR3411_2012_256HashMech = { CKM_GOSTR3411_12_256, parametersGostR3411_2012_256, sizeof(parametersGostR3411_2012_256)};
 
/* Механизм подписи по алгоритму ГОСТ Р 34.10-2012(256)*/
CK_MECHANISM gostR3410_2001SigVerMech = {CKM_GOSTR3410, nullptr, 0};
 
     /*************************************************************************
     * Инициализировать хэш-функцию                                           *
     *************************************************************************/
     rv = functionList->C_DigestInit(session, &gostR3411_2012_256HashMech);
     CHECK_AND_LOG("  C_DigestInit", rv == CKR_OK, rvToStr(rv), free_objects1);
 
     /*************************************************************************
     * Определить размер хэш-кода                                             *
     *************************************************************************/
     rv = functionList->C_Digest(session, data, sizeof(data), NULL_PTR, &hashSize1);
     CHECK_AND_LOG("  C_Digest(get size)", rv == CKR_OK, rvToStr(rv), free_objects1);
 
     /*************************************************************************
     * Вычислить хэш-код данных                                               *
     *************************************************************************/
 
     hash1 = (CK_BYTE*)malloc(hashSize1 * sizeof(CK_BYTE));
     CHECK("  Memory allocation for hash", hash1 != NULL, free_objects1);
 
     rv = functionList->C_Digest(session, data, sizeof(data), hash1, &hashSize1);
     CHECK_AND_LOG("  C_Digest (get hash)", rv == CKR_OK, rvToStr(rv), free_hash1);
 
     /*************************************************************************
     * Сформировать цифровую подпись данных                                   *
     * по алгоритму ГОСТ Р 34.10-2012(256)                                    *
     *************************************************************************/
    /*************************************************************************
     * Инициализировать операцию подписи данных                               *
     *************************************************************************/
     rv = functionList->C_SignInit(session, &gostR3410_2012_256SigVerMech, objects1[0]);
     CHECK_AND_LOG("  C_SignInit", rv == CKR_OK, rvToStr(rv), free_hash1);
 
     /*************************************************************************
     * Определить размер данных подписи                                       *
     *************************************************************************/
    rv = functionList->C_Sign(session, hash1, 32, NULL_PTR, &signatureSize);
     CHECK_AND_LOG("  C_Sign (get size)", rv == CKR_OK, rvToStr(rv), free_hash1);
 
     /*************************************************************************
     * Подписать данные                                                      *
     ************************************************************************/
     signature = (CK_BYTE*)malloc(signatureSize * sizeof(CK_BYTE));
     CHECK("  Memory allocation for signature", signature != NULL, free_hash1);
 
     rv = functionList->C_Sign(session, hash1, hashSize1, signature, & signatureSize);
     CHECK_AND_LOG("  C_Sign (signing)", rv == CKR_OK, rvToStr(rv), free_signature);

Re: Как реализовать программное поточное хеширование?

Павел Анфимов, а возможно это реализовать с использованием поточных функций? C_DigestUpdate()...? Мне просто именно поточное хеширование нужно

Re: Как реализовать программное поточное хеширование?

Binger, возможно, главное правильные механизмы передать в C_DigestInit.

Re: Как реализовать программное поточное хеширование?

Павел Анфимов, понял вас. Спасибо, буду пробовать.

Re: Как реализовать программное поточное хеширование?

Павел Анфимов, для SHA-1 нет подобных решений? Для ГОСТ алгоритмов только нашёл наборы параметров в Common.h из SDK Rutoken

Re: Как реализовать программное поточное хеширование?

Binger, Рутокены имеют аппаратно реализованные ГОСТ-алгоритмы хеширования. SHA-1-- считается программно.

параметр для C_DigestInit:

/* Механизм хеширования SHA-1 */
CK_MECHANISM sha1Mech = {CKM_SHA_1, NULL_PTR, 0};

Re: Как реализовать программное поточное хеширование?

Павел Анфимов, всё, понял. Огромное спасибо, Павел.