rizin/librz/hash/algorithms/fletcher/fletcher.c
Giovanni 82e7917294
Refactoring Hash (#1082)
* Added authors and licenses and plugin access to crypto related files
* removed `rz_hash` and related files
* introduced `rz_msg_digest_*` with plugins
* updated all old methods with newer ones.
* added HMAC support to `rz-hash` (moved key option under `-K`)
* removed wrong algorithms on `woD`/`woE`
* fixed parity digest size
* fixed the behaviour on all hash functions
* added unit test for hash
* optimized code for HMAC key calculation
* removed hash legacy tests
2021-05-02 20:47:17 +08:00

136 lines
3.3 KiB
C

// SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
// SPDX-License-Identifier: LGPL-3.0-only
#include "fletcher.h"
#include <rz_util.h>
// Fletcher 8
bool rz_fletcher8_init(RzFletcher8 *ctx) {
rz_return_val_if_fail(ctx, false);
memset(ctx, 0, sizeof(RzFletcher8));
return true;
}
bool rz_fletcher8_update(RzFletcher8 *ctx, const ut8 *data, size_t len) {
rz_return_val_if_fail(ctx && data, false);
for (size_t i = 0; i < len; i++) {
ctx->low += data[i];
ctx->low = (ctx->low & 0xff) + (ctx->low >> 8);
ctx->high += ctx->low;
ctx->high = (ctx->high & 0xff) + (ctx->high >> 8);
}
return true;
}
bool rz_fletcher8_final(ut8 *digest, RzFletcher8 *ctx) {
rz_return_val_if_fail(ctx && digest, false);
rz_write_le8(digest, (ctx->low & 0xff));
return true;
}
// Fletcher 16
bool rz_fletcher16_init(RzFletcher16 *ctx) {
rz_return_val_if_fail(ctx, false);
memset(ctx, 0, sizeof(RzFletcher16));
return true;
}
bool rz_fletcher16_update(RzFletcher16 *ctx, const ut8 *data, size_t len) {
rz_return_val_if_fail(ctx && data, false);
size_t i;
for (; len >= 5802; len -= 5802) {
for (i = 0; i < 5802; i++) {
ctx->low = ctx->low + *data++;
ctx->high = ctx->high + ctx->low;
}
ctx->low %= 0xff;
ctx->high %= 0xff;
}
for (i = 0; i < len; i++) {
ctx->low += *data++;
ctx->high += ctx->low;
}
return true;
}
bool rz_fletcher16_final(ut8 *digest, RzFletcher16 *ctx) {
rz_return_val_if_fail(ctx && digest, false);
ctx->low %= 0xff;
ctx->high %= 0xff;
rz_write_le16(digest, (ctx->high << 8 | ctx->low));
return true;
}
// Fletcher 32
bool rz_fletcher32_init(RzFletcher32 *ctx) {
rz_return_val_if_fail(ctx, false);
memset(ctx, 0, sizeof(RzFletcher32));
return true;
}
bool rz_fletcher32_update(RzFletcher32 *ctx, const ut8 *data, size_t len) {
rz_return_val_if_fail(ctx && data, false);
size_t i;
ut8 word[sizeof(ut16)];
for (; len >= 360; len -= 360) {
for (i = 0; i < 360; i += 2) {
size_t left = 360 - i;
memset(word, 0, sizeof(word));
memcpy(word, data, RZ_MIN(sizeof(word), left));
ctx->low += rz_read_le16(word);
ctx->high += ctx->low;
data += 2;
}
ctx->low %= UT16_MAX;
ctx->high %= UT16_MAX;
}
for (i = 0; i < len; i += 2) {
size_t left = len - i;
memset(word, 0, sizeof(word));
memcpy(word, data, RZ_MIN(sizeof(word), left));
ctx->low += rz_read_le16(word);
ctx->high += ctx->low;
data += 2;
}
return true;
}
bool rz_fletcher32_final(ut8 *digest, RzFletcher32 *ctx) {
rz_return_val_if_fail(ctx && digest, false);
ctx->low %= UT16_MAX;
ctx->high %= UT16_MAX;
rz_write_le32(digest, ctx->high << 16 | ctx->low);
return true;
}
// Fletcher 64
bool rz_fletcher64_init(RzFletcher64 *ctx) {
rz_return_val_if_fail(ctx, false);
memset(ctx, 0, sizeof(RzFletcher64));
return true;
}
bool rz_fletcher64_update(RzFletcher64 *ctx, const ut8 *data, size_t len) {
rz_return_val_if_fail(ctx && data, false);
ut8 word[sizeof(ut32)];
for (size_t i = 0; i < len; i += sizeof(ut32)) {
size_t left = RZ_MIN(sizeof(ut32), len - i);
memset(word, 0, sizeof(word));
memcpy(word, &data[i], left);
ut32 value = rz_read_le32(word);
ctx->low += value;
ctx->high += ctx->low;
}
return true;
}
bool rz_fletcher64_final(ut8 *digest, RzFletcher64 *ctx) {
rz_return_val_if_fail(ctx && digest, false);
rz_write_le64(digest, ((ut64)ctx->high << 32) | ctx->low);
return true;
}