Commit 7266e9f5 authored by Белов Никита Сергеевич's avatar Белов Никита Сергеевич
Browse files

Добавлен режим хеширования СТБ

parent 168223cd
No related merge requests found
Showing with 220 additions and 0 deletions
+220 -0
......@@ -96,6 +96,7 @@ set( AKRYPT_SOURCES
source/ak_kdf.c
source/ak_encrypt.c
source/ak_belt.c
source/ak_belt_hash.c
)
# -------------------------------------------------------------------------------------------------- #
......
/* ----------------------------------------------------------------------------------------------- */
/* */
/* */
/* STB 34.101.31-2020 */
/* */
/* ----------------------------------------------------------------------------------------------- */
#include <libakrypt-internal.h>
static const ak_uint8 belt_start_hash[32] =
{
0xB1, 0x94, 0xBA, 0xC8, 0x0A, 0x08, 0xF5, 0x3B,
0x36, 0x6D, 0x00, 0x8E, 0x58, 0x4A, 0x5D, 0xE4,
0x85, 0x04, 0xFA, 0x9D, 0x1B, 0xB6, 0xC7, 0xAC,
0x25, 0x2E, 0x72, 0xC2, 0x02, 0xFD, 0xCE, 0x0D,
};
/* ----------------------------------------------------------------------------------------------- */
/*! \brief 512
\note , 64 , 48
\note data result,
@param result .
@param bkey .
@param bkey .
/* ----------------------------------------------------------------------------------------------- */
static inline void ak_belt_compress (ak_uint64* result, ak_uint64* data, ak_bckey bkey)
{
ak_uint64* X1 = data;
ak_uint64* X2 = data + 2;
ak_uint64* X3 = data + 4;
ak_uint64* X4 = data + 6;
ak_uint64 temp[6]; //
temp[0] = X3[0] ^ X4[0]; // 128
temp[1] = X3[1] ^ X4[1];
ak_bckey_set_key(bkey, X1, 32); // X1 || X2
ak_bckey_encrypt_ecb(bkey, temp, temp + 2, 16); // 128 256 - (S ^ X3 ^ X4)
temp[2] ^= X3[0] ^ X4[0]; // S
temp[3] ^= X3[1] ^ X4[1];
memcpy(result, temp + 2, 16); // S
memcpy(temp + 4, X4, 16); // temp[2:5]
ak_bckey_set_key(bkey, temp + 2, 32); // S || X4
ak_bckey_encrypt_ecb(bkey, X1, result + 2, 16); // X1 S || X4. result[2:3]
result[2] ^= X1[0]; // Y1
result[3] ^= X1[1];
temp[2] = ~temp[2]; // S ^ 1^128
temp[3] = ~temp[3];
memcpy(temp + 4, X3, 16); // temp[2:5]
ak_bckey_set_key(bkey, temp + 2, 32); // ~S || X3
ak_bckey_encrypt_ecb(bkey, X2, result + 4, 16); // Y2 ^ X2 result[4:5]
result[4] ^= X2[0];
result[5] ^= X2[1];
memset(temp, 0, 48); //
}
static int ak_hash_context_belt_clean(ak_pointer sctx)
{
ak_belt_hash cx = (ak_belt_hash)sctx;
if (cx == NULL) return ak_error_null_pointer;
memset(cx->s, 0, 16);
memset(cx->r, 0, 16);
memcpy(cx->h, belt_start_hash, 32);
return ak_error_ok;
}
static int ak_hash_context_belt_update(ak_pointer sctx, const ak_pointer in, const size_t size)
{
ak_belt_hash cx = (ak_belt_hash)sctx;
ak_uint64 quot = size >> 5, * dt = (ak_uint64*)in;
ak_uint64 compress_in[8]; // ,
ak_uint64 compress_out[6]; //
if (cx == NULL) return ak_error_message(ak_error_null_pointer, __func__,
"using null pointer to internal streebog context");
if ((!size) || (in == NULL)) return ak_error_ok;
if ((size & 0x1F)) return ak_error_message(ak_error_wrong_length, __func__,
"data length is not a multiple of the length of the block"); // 256 (64 ),
while (quot > 0) {
memcpy(compress_in, dt, 32); //
memcpy(compress_in + 4, cx->h, 32);
printf("0: %s\n", ak_ptr_to_hexstr(compress_in, 64, ak_false));
ak_belt_compress(compress_out, compress_in, &(cx->bcctx)); //
memcpy(cx->h, compress_out + 2, 32); // h
cx->s[0] ^= compress_out[0]; // s
cx->s[1] ^= compress_out[1];
quot--;
dt += 4;
cx->r[14] += 1;
int j = 14;
while (j > 0 && cx->r[j] == 0)
cx->r[--j]++;
};
return ak_error_ok;
}
static int ak_hash_context_belt_finalize(ak_pointer sctx,
const ak_pointer in, const size_t size, ak_pointer out, const size_t out_size)
{
ak_belt_hash cx = (ak_belt_hash)sctx;
if (cx == NULL) return ak_error_message(ak_error_null_pointer, __func__,
"using null pointer to internal streebog context");
if (out == NULL) return ak_error_message(ak_error_null_pointer, __func__,
"using null pointer to externl result buffer");
if (size > 64) return ak_error_message(ak_error_wrong_length, __func__,
"input length is too huge");
if (out_size < 32) return ak_error_message(ak_error_wrong_length, __func__,
"output length is too small");
ak_uint64 lastBlock[8];
memset(lastBlock, 0, 64); //
memcpy(lastBlock, in, size);
if (cx->r[15] < 256 - (size << 3)) // r
{
int j = 14;
while (cx->r[j] == 0)
cx->r[j--] = 255;
cx->r[j] -= 1;
cx->r[15] -= 256 - (size << 3);
}
else
{
cx->r[15] -= 256 - (size << 3);
}
memcpy(lastBlock, cx->r, 16);
memcpy(lastBlock + 2, cx->s, 16);
memcpy(lastBlock + 4, cx->h, 32);
ak_uint64 final[6];
ak_belt_compress(final, lastBlock, &(cx->bcctx));
memcpy(out, final + 2, 32);
memset(lastBlock, 0, 64); //
memset(final, 0, 48);
return ak_error_ok;
}
int ak_hash_create_belt(ak_hash hctx)
{
int error = ak_error_ok;
if (hctx == NULL) return ak_error_message(ak_error_null_pointer, __func__,
"using null pointer to hash context");
hctx->data.bctx.hsize = 32;
if ((hctx->oid = ak_oid_find_by_name("belt_hash")) == NULL)
return ak_error_message(ak_error_wrong_oid, __func__,
"incorrect internal search of belt hash identifier");
if ((error = ak_bckey_create_belt(&(hctx->data.bctx.bcctx))) != ak_error_ok)
return ak_error_message(error, __func__, "incorrect initialization of inner bc_key");
if ((error = ak_mac_create(&hctx->mctx, 64, &hctx->data.bctx,
ak_hash_context_belt_clean,
ak_hash_context_belt_update,
ak_hash_context_belt_finalize)) != ak_error_ok)
return ak_error_message(error, __func__, "incorrect initialization of internal mac context");
return ak_hash_context_belt_clean(&hctx->data.sctx);
}
\ No newline at end of file
......@@ -84,6 +84,10 @@
static const char *asn1_kuznechik_i[] = { "1.2.643.7.1.1.5.2", NULL };
static const char *asn1_belt_n[] = { "belt", NULL };
static const char *asn1_belt_i[] = { "1.2.112.0.2.0.34.101.31.81", NULL };
// Идентификатор выше принадлежит алгоритму хэширование: https://www.consultant.ru/document/cons_doc_LAW_186638/1036e6ea13d3e0de451bc9b0e63c96e7823c740e/
static const char *asn1_belt_hash_n[] = { "belt_hash", NULL };
static const char *asn1_belt_hash_i[] = { "1.2.112.0.2.0.34.101.31.81", NULL };
static const char *asn1_ctr_magma_n[] = { "ctr-magma", NULL };
static const char *asn1_ctr_magma_i[] = { "1.2.643.2.52.1.5.1.1", NULL };
......@@ -570,6 +574,11 @@ static struct oid libakrypt_oids[] =
( ak_function_destroy_object *) ak_hash_destroy, NULL, NULL, NULL },
ak_object_undefined, (ak_function_run_object *) ak_hash_ptr, NULL }},
{ hash_function, algorithm, asn1_belt_hash_i, asn1_belt_hash_n, NULL,
{{ sizeof(struct hash), (ak_function_create_object*)ak_hash_create_belt,
(ak_function_destroy_object*)ak_hash_destroy, NULL, NULL, NULL },
ak_object_undefined, (ak_function_run_object*)ak_hash_ptr, NULL }},
{ hmac_function, algorithm, asn1_hmac_streebog256_i, asn1_hmac_streebog256_n, NULL,
{ ak_object_hmac_streebog256,
ak_object_undefined, (ak_function_run_object *) ak_hmac_ptr, NULL }},
......
......@@ -883,6 +883,20 @@ extern "C" {
size_t hsize;
} *ak_streebog;
typedef struct belt_hash {
/*! \brief Вектор r - временный */
ak_uint8 r[16];
/*! \brief Вектор s - временный */
ak_uint8 s[16];
/*! \brief Вектор h - временный + результат */
ak_uint8 h[32];
/*! \brief Размер блока выходных данных (хеш-кода)*/
size_t hsize;
/*! \brief Используемый контекст шифрования */
struct bckey bcctx;
} *ak_belt_hash;
/* ----------------------------------------------------------------------------------------------- */
/*! \brief Контекст бесключевой функции хеширования. */
/*! \details Класс предоставляет интерфейс для реализации бесключевых функций хеширования, построенных
......@@ -906,6 +920,8 @@ extern "C" {
union {
/*! \brief Структура алгоритмов семейства Стрибог. */
struct streebog sctx;
/*! \brief Структура алгоритма хэширования STB 34.101.31-2020. */
struct belt_hash bctx;
/*! \brief Вектор значений для алгоритмов семейства crc64 */
ak_uint64 b64;
} data;
......@@ -916,6 +932,8 @@ extern "C" {
dll_export int ak_hash_create_streebog256( ak_hash );
/*! \brief Инициализация контекста функции бесключевого хеширования ГОСТ Р 34.11-2012 (Стрибог512). */
dll_export int ak_hash_create_streebog512( ak_hash );
/*! \brief Инициализация контекста функции бесключевого хеширования СТБ 34.101.31-2020. */
dll_export int ak_hash_create_belt( ak_hash );
/*! \brief Инициализация контекста некриптографической функции хеширования crc64. */
dll_export int ak_hash_create_crc64( ak_hash );
/*! \brief Инициализация контекста функции бесключевого хеширования по заданному OID алгоритма. */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment