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

Delete ak_belt_hash.c

parent 02805d7f
No related merge requests found
Showing with 0 additions and 198 deletions
+0 -198
/* ----------------------------------------------------------------------------------------------- */
/* */
/* Реализация хэширования сообщения */
/* из Белорусского стандарта 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 битам (32 байтам), все плохо
while (quot > 0) {
memcpy(compress_in, dt, 32); // Загружаем данные для функции сжатия
memcpy(compress_in + 4, cx->h, 32);
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 > 32) 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);
memcpy(lastBlock + 4, cx->h, 32);
ak_uint64 final[6];
ak_belt_compress(final, lastBlock, &(cx->bcctx));
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_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
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