Refactoring rz-hash, crypto and hashes interfaces (#1072)

* Refactoring rz-hash main, crypto interfaces and hashes
* ops. removed method that was removed later on
* fixed punycode oob read
* use RZ_ARRAY_SIZE instead of looking for null pointer
* Added broken flag on rz-hash -L test
This commit is contained in:
Giovanni 2021-04-26 11:07:52 +02:00 committed by GitHub
parent 3506ffc41d
commit 54fd6a66bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 2278 additions and 1434 deletions

View file

@ -203,13 +203,12 @@ static bool encrypt_or_decrypt_block(RzCore *core, const char *algo, const char
rz_crypto_final(cry, NULL, 0);
int result_size = 0;
ut8 *result = rz_crypto_get_output(cry, &result_size);
const ut8 *result = rz_crypto_get_output(cry, &result_size);
if (result) {
if (!rz_core_write_at(core, core->offset, result, result_size)) {
eprintf("rz_core_write_at failed at 0x%08" PFMT64x "\n", core->offset);
}
eprintf("Written %d byte(s)\n", result_size);
free(result);
}
} else {
eprintf("Invalid key\n");

View file

@ -1,8 +1,11 @@
// SPDX-FileCopyrightText: 2009-2017 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include "rz_crypto.h"
#include <rz_crypto.h>
#include "config.h"
#include <rz_util.h>
#define RZ_CRYPTO_OUTPUT_SIZE 4096
RZ_LIB_VERSION(rz_crypto);
@ -24,7 +27,6 @@ static const struct {
{ "des-ecb", RZ_CRYPTO_DES_ECB },
{ "xor", RZ_CRYPTO_XOR },
{ "serpent-ecb", RZ_CRYPTO_SERPENT },
{ NULL, 0 }
};
static const struct {
@ -35,13 +37,12 @@ static const struct {
{ "base64", RZ_CODEC_B64 },
{ "base91", RZ_CODEC_B91 },
{ "punycode", RZ_CODEC_PUNYCODE },
{ NULL, 0 }
};
RZ_API const char *rz_crypto_name(const RzCryptoSelector bit) {
size_t i;
for (i = 1; crypto_name_bytes[i].bit; i++) {
if (bit & crypto_name_bytes[i].bit) {
for (i = 1; i < RZ_ARRAY_SIZE(crypto_name_bytes); i++) {
if (bit == crypto_name_bytes[i].bit) {
return crypto_name_bytes[i].name;
}
}
@ -50,8 +51,8 @@ RZ_API const char *rz_crypto_name(const RzCryptoSelector bit) {
RZ_API const char *rz_crypto_codec_name(const RzCryptoSelector bit) {
size_t i;
for (i = 1; codec_name_bytes[i].bit; i++) {
if (bit & codec_name_bytes[i].bit) {
for (i = 1; i < RZ_ARRAY_SIZE(codec_name_bytes); i++) {
if (bit == codec_name_bytes[i].bit) {
return codec_name_bytes[i].name;
}
}
@ -62,31 +63,6 @@ static RzCryptoPlugin *crypto_static_plugins[] = {
RZ_CRYPTO_STATIC_PLUGINS
};
RZ_API RzCrypto *rz_crypto_init(RzCrypto *cry, int hard) {
int i;
if (cry) {
cry->iv = NULL;
cry->key = NULL;
cry->key_len = 0;
cry->user = NULL;
if (hard) {
// first call initializes the output_* variables
rz_crypto_get_output(cry, NULL);
cry->plugins = rz_list_newf(NULL);
for (i = 0; crypto_static_plugins[i]; i++) {
RzCryptoPlugin *p = RZ_NEW0(RzCryptoPlugin);
if (!p) {
free(cry);
return NULL;
}
memcpy(p, crypto_static_plugins[i], sizeof(RzCryptoPlugin));
rz_crypto_add(cry, p);
}
}
}
return cry;
}
RZ_API int rz_crypto_add(RzCrypto *cry, RzCryptoPlugin *h) {
// add a check ?
rz_list_append(cry->plugins, h);
@ -98,22 +74,43 @@ RZ_API int rz_crypto_del(RzCrypto *cry, RzCryptoPlugin *h) {
return true;
}
RZ_API struct rz_crypto_t *rz_crypto_new(void) {
RZ_API RzCrypto *rz_crypto_new(void) {
RzCrypto *cry = RZ_NEW0(RzCrypto);
return rz_crypto_init(cry, true);
}
RZ_API struct rz_crypto_t *rz_crypto_as_new(struct rz_crypto_t *cry) {
RzCrypto *c = RZ_NEW0(RzCrypto);
if (c) {
rz_crypto_init(c, false); // soft init
memcpy(&c->plugins, &cry->plugins, sizeof(cry->plugins));
if (!cry) {
goto rz_crypto_new_bad;
}
return c;
cry->output_size = RZ_CRYPTO_OUTPUT_SIZE;
cry->output = malloc(RZ_CRYPTO_OUTPUT_SIZE);
if (!cry->output) {
goto rz_crypto_new_bad;
}
cry->plugins = rz_list_newf((RzListFree)free);
if (!cry->plugins) {
goto rz_crypto_new_bad;
}
for (ut32 i = 0; crypto_static_plugins[i]; i++) {
RzCryptoPlugin *p = RZ_NEW0(RzCryptoPlugin);
if (!p) {
goto rz_crypto_new_bad;
}
memcpy(p, crypto_static_plugins[i], sizeof(RzCryptoPlugin));
rz_crypto_add(cry, p);
}
return cry;
rz_crypto_new_bad:
RZ_LOG_ERROR("[!] crypto: failed to allocate\n");
rz_crypto_free(cry);
return NULL;
}
RZ_API struct rz_crypto_t *rz_crypto_free(RzCrypto *cry) {
// TODO: call the destructor function of the plugin to destroy the *user pointer if needed
if (cry->h && cry->h->fini && !cry->h->fini(cry)) {
RZ_LOG_ERROR("[!] crypto: error terminating '%s' plugin\n", cry->h->name);
}
rz_list_free(cry->plugins);
free(cry->output);
free(cry->key);
@ -125,12 +122,19 @@ RZ_API struct rz_crypto_t *rz_crypto_free(RzCrypto *cry) {
RZ_API bool rz_crypto_use(RzCrypto *cry, const char *algo) {
RzListIter *iter;
RzCryptoPlugin *h;
if (cry->h && cry->h->fini && !cry->h->fini(cry)) {
RZ_LOG_ERROR("[!] crypto: error terminating '%s' plugin\n", cry->h->name);
}
rz_list_foreach (cry->plugins, iter, h) {
if (h && h->use && h->use(algo)) {
rz_warn_if_fail(h && h->use);
if (h && h->use(algo)) {
if (h->init && !h->init(cry)) {
RZ_LOG_ERROR("[!] crypto: error initializing '%s' plugin\n", cry->h->name);
return false;
}
cry->h = h;
cry->key_len = h->get_key_size(cry);
cry->key = calloc(1, cry->key_len);
return cry->key != NULL;
return true;
}
}
return false;
@ -146,10 +150,6 @@ RZ_API bool rz_crypto_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mod
return cry->h->set_key(cry, key, keylen, mode, direction);
}
RZ_API int rz_crypto_get_key_size(RzCrypto *cry) {
return (cry && cry->h && cry->h->get_key_size) ? cry->h->get_key_size(cry) : 0;
}
RZ_API bool rz_crypto_set_iv(RzCrypto *cry, const ut8 *iv, int ivlen) {
return (cry && cry->h && cry->h->set_iv) ? cry->h->set_iv(cry, iv, ivlen) : 0;
}
@ -172,34 +172,25 @@ RZ_API int rz_crypto_append(RzCrypto *cry, const ut8 *buf, int len) {
cry->output_size += 4096 + len;
cry->output = realloc(cry->output, cry->output_size);
}
if (!cry->output) {
rz_warn_if_reached();
cry->output_size = 0;
return 0;
}
memcpy(cry->output + cry->output_len, buf, len);
cry->output_len += len;
return cry->output_len;
}
RZ_API ut8 *rz_crypto_get_output(RzCrypto *cry, int *size) {
if (cry->output_size < 1) {
return NULL;
}
ut8 *buf = calloc(1, cry->output_size);
if (!buf) {
RZ_API const ut8 *rz_crypto_get_output(RzCrypto *cry, int *size) {
if (cry->output_size < 1 || !cry->output) {
if (size) {
*size = 0;
}
return NULL;
}
if (size) {
*size = cry->output_len;
memcpy(buf, cry->output, *size);
} else {
/* initialize */
const int size = 4096;
cry->output = realloc(buf, size);
if (!cry->output) {
free(buf);
return NULL;
}
cry->output_len = 0;
cry->output_size = size;
return NULL;
}
return buf;
return cry->output;
}

View file

@ -5,23 +5,26 @@
#include <rz_crypto.h>
#include "crypto_aes_algo.h"
// TODO: avoid globals
static struct aes_state st = { { 0 } };
static bool aes_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
rz_return_val_if_fail(cry->user && key, false);
aes_state_t *st = (aes_state_t *)cry->user;
if (!(keylen == 128 / 8 || keylen == 192 / 8 || keylen == 256 / 8)) {
return false;
}
st.key_size = keylen;
st.rounds = 6 + (int)(keylen / 4);
st.columns = (int)(keylen / 4);
memcpy(st.key, key, keylen);
st->key_size = keylen;
st->rounds = 6 + (int)(keylen / 4);
st->columns = (int)(keylen / 4);
memcpy(st->key, key, keylen);
cry->dir = direction;
return true;
}
static int aes_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
aes_state_t *st = (aes_state_t *)cry->user;
return st->key_size;
}
static bool aes_use(const char *algo) {
@ -31,6 +34,13 @@ static bool aes_use(const char *algo) {
#define BLOCK_SIZE 16
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, 0);
aes_state_t *st = (aes_state_t *)cry->user;
if (len < 1) {
return false;
}
// Pad to the block size, do not append dummy block
const int diff = (BLOCK_SIZE - (len % BLOCK_SIZE)) % BLOCK_SIZE;
const int size = len + diff;
@ -54,15 +64,15 @@ static bool update(RzCrypto *cry, const ut8 *buf, int len) {
ibuf[len] = 8; //0b1000;
}
if (cry->dir == 0) {
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
for (i = 0; i < blocks; i++) {
const int delta = BLOCK_SIZE * i;
aes_encrypt(&st, ibuf + delta, obuf + delta);
aes_encrypt(st, ibuf + delta, obuf + delta);
}
} else if (cry->dir > 0) {
} else {
for (i = 0; i < blocks; i++) {
const int delta = BLOCK_SIZE * i;
aes_decrypt(&st, ibuf + delta, obuf + delta);
aes_decrypt(st, ibuf + delta, obuf + delta);
}
}
@ -78,13 +88,29 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool aes_ecb_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(aes_state_t);
return cry->user != NULL;
}
static bool aes_ecb_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_aes = {
.name = "aes-ecb",
.set_key = aes_set_key,
.get_key_size = aes_get_key_size,
.use = aes_use,
.update = update,
.final = final
.final = final,
.init = aes_ecb_init,
.fini = aes_ecb_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -1,19 +1,11 @@
// original code from:
//====================
// advanced encryption standard
// author: karl malbrain, malbrain@yahoo.com
//
// adapted from Christophe Devine's tables
// and George Anescu's c++ code.
// SPDX-FileCopyrightText: Karl Malbrain <malbrain@yahoo.com>
// SPDX-License-Identifier: MS-PL
#include "crypto_aes_algo.h"
#define Nb 4 // number of columns in the state & expanded key
// #define Nk 4 // number of columns in a key
// #define Nr 10 // number of rounds in encryption
// #define AES_KEY (4 * Nk)
// #define ROUND_KEY_COUNT ((Nr + 1) * 4)
#define Nb 4 // number of columns in the state & expanded key
#define Nr 16 // max number of rounds in encryption
#define Nk 8 // max number of columns in a key
static const ut8 Rcon[30] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
@ -22,45 +14,30 @@ static const ut8 Rcon[30] = {
0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
};
// Expand a user-supplied key material into a session key.
// key - The 128/192/256-bit user-key to use.
//expkey[2][Nr + 1][Nb]
//void aes_expkey (const struct aes_state *st, ut32 ***expkey) { //expkey[2][st->rounds + 1][Nb]) {
#if defined(__GNUC__)
void aes_expkey(const struct aes_state *st, ut32 expkey[2][st->rounds + 1][Nb])
#else
// XXX this is wrong, but at least it compiles
#ifdef _MSC_VER
#pragma message("AES broken for non-gcc compilers")
#else
#warning AES broken for non-gcc compilers
#endif
#define Nr_AES256 (6 + ((256 / 8) / 4))
void aes_expkey(const struct aes_state *st, ut32 expkey[2][Nr_AES256 + 1][Nb])
#endif
{
// ut32 expkey[2][st->rounds + 1][Nb];
// memcpy (&expkey, _expkey, 2 * (st->rounds + 1) * Nb);
int ROUND_KEY_COUNT = 4 * (1 + st->rounds);
#ifdef _MSC_VER
ut32 *tk = (ut32 *)malloc(sizeof(ut32) * st->columns);
#else
ut32 tk[st->columns];
#endif
typedef struct {
ut32 key0[Nr][Nb];
ut32 key1[Nr][Nb];
} expkey_t;
void aes_expkey(const aes_state_t *st, expkey_t *ek) {
rz_return_if_fail(st->rounds <= Nr && st->columns <= Nk); // This can't happen
int round_key_count = 4 * (1 + st->rounds);
ut32 tk[Nk];
ut32 tt;
st32 idx = 0, t = 0;
const ut8 *key = st->key;
st32 i, j, r;
for (i = 0; i <= st->rounds; i++) {
for (j = 0; j < Nb; j++) {
expkey[0][i][j] = 0;
ek->key0[i][j] = 0;
}
}
for (i = 0; i <= st->rounds; i++) {
for (j = 0; j < Nb; j++) {
expkey[1][i][j] = 0;
ek->key1[i][j] = 0;
}
}
@ -73,12 +50,12 @@ void aes_expkey(const struct aes_state *st, ut32 expkey[2][Nr_AES256 + 1][Nb])
}
// Copy values into round key arrays
for (j = 0; j < st->columns && t < ROUND_KEY_COUNT; j++, t++) {
expkey[0][t / Nb][t % Nb] = tk[j];
expkey[1][st->rounds - (t / Nb)][t % Nb] = tk[j];
for (j = 0; j < st->columns && t < round_key_count; j++, t++) {
ek->key0[t / Nb][t % Nb] = tk[j];
ek->key1[st->rounds - (t / Nb)][t % Nb] = tk[j];
}
while (t < ROUND_KEY_COUNT) {
while (t < round_key_count) {
// Extrapolate using phi (the round key evolution function)
tt = tk[st->columns - 1];
tk[0] ^= Sbox[(ut8)(tt >> 16)] << 24 ^ Sbox[(ut8)(tt >> 8)] << 16 ^
@ -102,35 +79,29 @@ void aes_expkey(const struct aes_state *st, ut32 expkey[2][Nr_AES256 + 1][Nb])
}
// Copy values into round key arrays
for (j = 0; j < st->columns && t < ROUND_KEY_COUNT; j++, t++) {
expkey[0][t / Nb][t % Nb] = tk[j];
expkey[1][st->rounds - (t / Nb)][t % Nb] = tk[j];
for (j = 0; j < st->columns && t < round_key_count; j++, t++) {
ek->key0[t / Nb][t % Nb] = tk[j];
ek->key1[st->rounds - (t / Nb)][t % Nb] = tk[j];
}
}
// Inverse MixColumn where needed
for (r = 1; r < st->rounds; r++) {
for (j = 0; j < Nb; j++) {
tt = expkey[1][r][j];
expkey[1][r][j] = U0[(ut8)(tt >> 24)] ^ U1[(ut8)(tt >> 16)] ^
tt = ek->key1[r][j];
ek->key1[r][j] = U0[(ut8)(tt >> 24)] ^ U1[(ut8)(tt >> 16)] ^
U2[(ut8)(tt >> 8)] ^ U3[(ut8)tt];
}
}
#ifdef _MSC_VER
free(tk);
#endif
}
// Convenience method to encrypt exactly one block of plaintext, assuming
// Rijndael's default block size (128-bit).
// in - The plaintext
// result - The ciphertext generated from a plaintext using the key
void aes_encrypt(struct aes_state *st, ut8 *in, ut8 *result) {
#if defined(_MSC_VER) || defined(__TINYC__)
ut32 expkey[2][Nr_AES256 + 1][Nb];
#else
ut32 expkey[2][st->rounds + 1][Nb];
#endif
aes_expkey(st, expkey);
void aes_encrypt(aes_state_t *st, ut8 *in, ut8 *result) {
expkey_t ek = { 0 };
aes_expkey(st, &ek);
ut32 t0, t1, t2, t3, tt;
ut32 a0, a1, a2, a3, r;
@ -139,25 +110,25 @@ void aes_encrypt(struct aes_state *st, ut8 *in, ut8 *result) {
t0 |= *in++ << 16;
t0 |= *in++ << 8;
t0 |= *in++;
t0 ^= expkey[0][0][0];
t0 ^= ek.key0[0][0];
t1 = *in++ << 24;
t1 |= *in++ << 16;
t1 |= *in++ << 8;
t1 |= *in++;
t1 ^= expkey[0][0][1];
t1 ^= ek.key0[0][1];
t2 = *in++ << 24;
t2 |= *in++ << 16;
t2 |= *in++ << 8;
t2 |= *in++;
t2 ^= expkey[0][0][2];
t2 ^= ek.key0[0][2];
t3 = *in++ << 24;
t3 |= *in++ << 16;
t3 |= *in++ << 8;
t3 |= *in++;
t3 ^= expkey[0][0][3];
t3 ^= ek.key0[0][3];
// Apply Round Transforms
for (r = 1; r < st->rounds; r++) {
@ -169,33 +140,33 @@ void aes_encrypt(struct aes_state *st, ut8 *in, ut8 *result) {
FT3[(ut8)t1]);
a3 = (FT0[(ut8)(t3 >> 24)] ^ FT1[(ut8)(t0 >> 16)] ^ FT2[(ut8)(t1 >> 8)] ^
FT3[(ut8)t2]);
t0 = a0 ^ expkey[0][r][0];
t1 = a1 ^ expkey[0][r][1];
t2 = a2 ^ expkey[0][r][2];
t3 = a3 ^ expkey[0][r][3];
t0 = a0 ^ ek.key0[r][0];
t1 = a1 ^ ek.key0[r][1];
t2 = a2 ^ ek.key0[r][2];
t3 = a3 ^ ek.key0[r][3];
}
// Last Round is special
tt = expkey[0][st->rounds][0];
tt = ek.key0[st->rounds][0];
result[0] = Sbox[(ut8)(t0 >> 24)] ^ (ut8)(tt >> 24);
result[1] = Sbox[(ut8)(t1 >> 16)] ^ (ut8)(tt >> 16);
result[2] = Sbox[(ut8)(t2 >> 8)] ^ (ut8)(tt >> 8);
result[3] = Sbox[(ut8)t3] ^ (ut8)tt;
tt = expkey[0][st->rounds][1];
tt = ek.key0[st->rounds][1];
result[4] = Sbox[(ut8)(t1 >> 24)] ^ (ut8)(tt >> 24);
result[5] = Sbox[(ut8)(t2 >> 16)] ^ (ut8)(tt >> 16);
result[6] = Sbox[(ut8)(t3 >> 8)] ^ (ut8)(tt >> 8);
result[7] = Sbox[(ut8)t0] ^ (ut8)tt;
tt = expkey[0][st->rounds][2];
tt = ek.key0[st->rounds][2];
result[8] = Sbox[(ut8)(t2 >> 24)] ^ (ut8)(tt >> 24);
result[9] = Sbox[(ut8)(t3 >> 16)] ^ (ut8)(tt >> 16);
result[10] = Sbox[(ut8)(t0 >> 8)] ^ (ut8)(tt >> 8);
result[11] = Sbox[(ut8)t1] ^ (ut8)tt;
tt = expkey[0][st->rounds][3];
tt = ek.key0[st->rounds][3];
result[12] = Sbox[(ut8)(t3 >> 24)] ^ (ut8)(tt >> 24);
result[13] = Sbox[(ut8)(t0 >> 16)] ^ (ut8)(tt >> 16);
result[14] = Sbox[(ut8)(t1 >> 8)] ^ (ut8)(tt >> 8);
@ -206,14 +177,10 @@ void aes_encrypt(struct aes_state *st, ut8 *in, ut8 *result) {
// Rijndael's default block size (128-bit).
// in - The ciphertext.
// result - The plaintext generated from a ciphertext using the session key.
void aes_decrypt(struct aes_state *st, ut8 *in, ut8 *result) {
#if defined(_MSC_VER) || defined(__TINYC__)
ut32 expkey[2][Nr_AES256 + 1][Nb];
#else
ut32 expkey[2][st->rounds + 1][Nb];
#endif
void aes_decrypt(aes_state_t *st, ut8 *in, ut8 *result) {
expkey_t ek = { 0 };
aes_expkey(st, expkey);
aes_expkey(st, &ek);
ut32 t0, t1, t2, t3, tt;
ut32 a0, a1, a2, a3, r;
@ -222,25 +189,25 @@ void aes_decrypt(struct aes_state *st, ut8 *in, ut8 *result) {
t0 |= *in++ << 16;
t0 |= *in++ << 8;
t0 |= *in++;
t0 ^= expkey[1][0][0];
t0 ^= ek.key1[0][0];
t1 = *in++ << 24;
t1 |= *in++ << 16;
t1 |= *in++ << 8;
t1 |= *in++;
t1 ^= expkey[1][0][1];
t1 ^= ek.key1[0][1];
t2 = *in++ << 24;
t2 |= *in++ << 16;
t2 |= *in++ << 8;
t2 |= *in++;
t2 ^= expkey[1][0][2];
t2 ^= ek.key1[0][2];
t3 = *in++ << 24;
t3 |= *in++ << 16;
t3 |= *in++ << 8;
t3 |= *in++;
t3 ^= expkey[1][0][3];
t3 ^= ek.key1[0][3];
// Apply round transforms
for (r = 1; r < st->rounds; r++) {
@ -248,32 +215,32 @@ void aes_decrypt(struct aes_state *st, ut8 *in, ut8 *result) {
a1 = (RT0[(ut8)(t1 >> 24)] ^ RT1[(ut8)(t0 >> 16)] ^ RT2[(ut8)(t3 >> 8)] ^ RT3[(ut8)t2]);
a2 = (RT0[(ut8)(t2 >> 24)] ^ RT1[(ut8)(t1 >> 16)] ^ RT2[(ut8)(t0 >> 8)] ^ RT3[(ut8)t3]);
a3 = (RT0[(ut8)(t3 >> 24)] ^ RT1[(ut8)(t2 >> 16)] ^ RT2[(ut8)(t1 >> 8)] ^ RT3[(ut8)t0]);
t0 = a0 ^ expkey[1][r][0];
t1 = a1 ^ expkey[1][r][1];
t2 = a2 ^ expkey[1][r][2];
t3 = a3 ^ expkey[1][r][3];
t0 = a0 ^ ek.key1[r][0];
t1 = a1 ^ ek.key1[r][1];
t2 = a2 ^ ek.key1[r][2];
t3 = a3 ^ ek.key1[r][3];
}
// Last Round is special
tt = expkey[1][st->rounds][0];
tt = ek.key1[st->rounds][0];
result[0] = InvSbox[(ut8)(t0 >> 24)] ^ (ut8)(tt >> 24);
result[1] = InvSbox[(ut8)(t3 >> 16)] ^ (ut8)(tt >> 16);
result[2] = InvSbox[(ut8)(t2 >> 8)] ^ (ut8)(tt >> 8);
result[3] = InvSbox[(ut8)t1] ^ (ut8)tt;
tt = expkey[1][st->rounds][1];
tt = ek.key1[st->rounds][1];
result[4] = InvSbox[(ut8)(t1 >> 24)] ^ (ut8)(tt >> 24);
result[5] = InvSbox[(ut8)(t0 >> 16)] ^ (ut8)(tt >> 16);
result[6] = InvSbox[(ut8)(t3 >> 8)] ^ (ut8)(tt >> 8);
result[7] = InvSbox[(ut8)t2] ^ (ut8)tt;
tt = expkey[1][st->rounds][2];
tt = ek.key1[st->rounds][2];
result[8] = InvSbox[(ut8)(t2 >> 24)] ^ (ut8)(tt >> 24);
result[9] = InvSbox[(ut8)(t1 >> 16)] ^ (ut8)(tt >> 16);
result[10] = InvSbox[(ut8)(t0 >> 8)] ^ (ut8)(tt >> 8);
result[11] = InvSbox[(ut8)t3] ^ (ut8)tt;
tt = expkey[1][st->rounds][3];
tt = ek.key1[st->rounds][3];
result[12] = InvSbox[(ut8)(t3 >> 24)] ^ (ut8)(tt >> 24);
result[13] = InvSbox[(ut8)(t2 >> 16)] ^ (ut8)(tt >> 16);
result[14] = InvSbox[(ut8)(t1 >> 8)] ^ (ut8)(tt >> 8);

View file

@ -1,16 +1,20 @@
// SPDX-FileCopyrightText: karl malbrain <malbrain@yahoo.com>
// SPDX-License-Identifier: MS-PL
#ifndef CRYPTO_AES_ALGO_H
#define CRYPTO_AES_ALGO_H
#include <rz_crypto.h>
#include <rz_util.h>
#include <rz_crypto/rz_aes.h>
#include <memory.h>
struct aes_state {
typedef struct aes_state {
ut8 key[32];
int key_size;
int columns;
int rounds;
};
} aes_state_t;
/* forward tables */
@ -267,7 +271,7 @@ static const ut32 U3[256] = { UT };
#undef V
#undef UT
void aes_encrypt(struct aes_state *, ut8 *, ut8 *);
void aes_decrypt(struct aes_state *, ut8 *, ut8 *);
void aes_encrypt(aes_state_t *st, ut8 *in, ut8 *result);
void aes_decrypt(aes_state_t *st, ut8 *in, ut8 *result);
#endif

View file

@ -7,32 +7,44 @@
#define BLOCK_SIZE 16
static struct aes_state st;
static bool iv_set = 0;
static ut8 iv[32];
typedef struct aes_cbc_context_t {
aes_state_t st;
bool iv_set;
ut8 iv[32];
} AesCbcCtx;
static bool aes_cbc_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
rz_return_val_if_fail(cry->user && key, false);
if (!(keylen == 128 / 8 || keylen == 192 / 8 || keylen == 256 / 8)) {
return false;
}
st.key_size = keylen;
st.rounds = 6 + (int)(keylen / 4);
st.columns = (int)(keylen / 4);
memcpy(st.key, key, keylen);
AesCbcCtx *ctx = (AesCbcCtx *)cry->user;
ctx->st.key_size = keylen;
ctx->st.rounds = 6 + (int)(keylen / 4);
ctx->st.columns = (int)(keylen / 4);
memcpy(ctx->st.key, key, keylen);
cry->dir = direction;
return true;
}
static int aes_cbc_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
AesCbcCtx *ctx = (AesCbcCtx *)cry->user;
return ctx->st.key_size;
}
static bool aes_cbc_set_iv(RzCrypto *cry, const ut8 *iv_src, int ivlen) {
rz_return_val_if_fail(cry->user && iv_src, false);
AesCbcCtx *ctx = (AesCbcCtx *)cry->user;
if (ivlen != BLOCK_SIZE) {
return false;
}
memcpy(iv, iv_src, BLOCK_SIZE);
iv_set = 1;
memcpy(ctx->iv, iv_src, BLOCK_SIZE);
ctx->iv_set = true;
return true;
}
@ -41,7 +53,14 @@ static bool aes_cbc_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (!iv_set) {
rz_return_val_if_fail(cry->user, false);
AesCbcCtx *ctx = (AesCbcCtx *)cry->user;
if (len < 1) {
return false;
}
if (!ctx->iv_set) {
eprintf("IV not set. Use -I [iv]\n");
return false;
}
@ -68,21 +87,21 @@ static bool update(RzCrypto *cry, const ut8 *buf, int len) {
}
int i, j;
if (cry->dir == 0) {
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
for (i = 0; i < blocks; i++) {
for (j = 0; j < BLOCK_SIZE; j++) {
ibuf[i * BLOCK_SIZE + j] ^= iv[j];
ibuf[i * BLOCK_SIZE + j] ^= ctx->iv[j];
}
aes_encrypt(&st, ibuf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
memcpy(iv, obuf + BLOCK_SIZE * i, BLOCK_SIZE);
aes_encrypt(&ctx->st, ibuf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
memcpy(ctx->iv, obuf + BLOCK_SIZE * i, BLOCK_SIZE);
}
} else if (cry->dir == 1) {
} else {
for (i = 0; i < blocks; i++) {
aes_decrypt(&st, ibuf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
aes_decrypt(&ctx->st, ibuf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
for (j = 0; j < BLOCK_SIZE; j++) {
obuf[i * BLOCK_SIZE + j] ^= iv[j];
obuf[i * BLOCK_SIZE + j] ^= ctx->iv[j];
}
memcpy(iv, buf + BLOCK_SIZE * i, BLOCK_SIZE);
memcpy(ctx->iv, buf + BLOCK_SIZE * i, BLOCK_SIZE);
}
}
@ -96,6 +115,20 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool aes_cbc_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(AesCbcCtx);
return cry->user != NULL;
}
static bool aes_cbc_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_aes_cbc = {
.name = "aes-cbc",
.set_key = aes_cbc_set_key,
@ -103,7 +136,9 @@ RzCryptoPlugin rz_crypto_plugin_aes_cbc = {
.set_iv = aes_cbc_set_iv,
.use = aes_cbc_use,
.update = update,
.final = final
.final = final,
.init = aes_cbc_init,
.fini = aes_cbc_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -19,16 +19,20 @@ static bool base64_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (len < 1) {
return false;
}
int olen = 0;
ut8 *obuf = NULL;
if (cry->dir == 0) {
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
olen = ((len + 2) / 3) * 4;
obuf = malloc(olen + 1);
if (!obuf) {
return false;
}
rz_base64_encode((char *)obuf, (const ut8 *)buf, len);
} else if (cry->dir == 1) {
} else {
olen = 4 + ((len / 4) * 3);
if (len > 0) {
olen -= (buf[len - 1] == '=') ? ((buf[len - 2] == '=') ? 2 : 1) : 0;

View file

@ -21,6 +21,10 @@ static bool base91_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (len < 1) {
return false;
}
int olen = INSIZE;
if (!cry || !buf || len < 1) {
return false;
@ -29,7 +33,7 @@ static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (!obuf) {
return false;
}
if (cry->dir == 0) {
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
olen = rz_base91_encode((char *)obuf, (const ut8 *)buf, len);
} else if (cry->dir == 1) {
olen = rz_base91_decode(obuf, (const char *)buf, len);

View file

@ -6,6 +6,7 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <memory.h>
#include <rz_util.h>
#define BLOCK_SIZE 8
@ -240,7 +241,7 @@ static void blowfish_decrypt(struct blowfish_state *const state, const ut8 *inbu
}
}
static bool blowfish_init(struct blowfish_state *const state, const ut8 *key, int keylen) {
static bool blowfish_init_state(struct blowfish_state *const state, const ut8 *key, int keylen) {
if (!state || !key || keylen > 56) {
return false;
}
@ -280,15 +281,19 @@ static bool blowfish_init(struct blowfish_state *const state, const ut8 *key, in
return true;
}
static struct blowfish_state st = { { 0 } };
static bool blowfish_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
rz_return_val_if_fail(cry->user && key, false);
struct blowfish_state *st = (struct blowfish_state *)cry->user;
cry->dir = direction;
return blowfish_init(&st, key, keylen);
return blowfish_init_state(st, key, keylen);
}
static int blowfish_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
struct blowfish_state *st = (struct blowfish_state *)cry->user;
return st->key_size;
}
static bool blowfish_use(const char *algo) {
@ -296,17 +301,20 @@ static bool blowfish_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (!cry || !buf) {
rz_return_val_if_fail(cry->user, false);
struct blowfish_state *st = (struct blowfish_state *)cry->user;
if (!buf || len < 1) {
return false;
}
ut8 *obuf = calloc(1, len);
if (!obuf) {
return false;
}
if (cry->dir == 0) {
blowfish_crypt(&st, buf, obuf, len);
} else if (cry->dir == 1) {
blowfish_decrypt(&st, buf, obuf, len);
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
blowfish_crypt(st, buf, obuf, len);
} else {
blowfish_decrypt(st, buf, obuf, len);
}
rz_crypto_append(cry, obuf, len);
free(obuf);
@ -317,6 +325,20 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool blowfish_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct blowfish_state);
return cry->user != NULL;
}
static bool blowfish_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_blowfish = {
.name = "blowfish",
.license = "LGPL3",
@ -324,7 +346,9 @@ RzCryptoPlugin rz_crypto_plugin_blowfish = {
.get_key_size = blowfish_get_key_size,
.use = blowfish_use,
.update = update,
.final = final
.final = final,
.init = blowfish_init,
.fini = blowfish_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -14,6 +14,7 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
// license:BSD-3-Clause
// copyright-holders:Paul Leaman, Andreas Naive, Nicola Salmoria,Charles MacDonald
@ -2884,9 +2885,10 @@ main(cps_state,cps2crypt) {
}
#endif
static ut32 cps2key[2] = { 0 };
static bool set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
rz_return_val_if_fail(cry->user && key, false);
ut32 *cps2key = (ut32 *)cry->user;
cry->dir = direction;
if (keylen == 8) {
/* fix key endianness */
@ -2908,7 +2910,14 @@ static bool cps2_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, false);
ut32 *cps2key = (ut32 *)cry->user;
ut8 *output = calloc(1, len);
if (!output) {
return false;
}
/* TODO : control decryption errors */
cps2_crypt(cry->dir, (const ut16 *)buf, (ut16 *)output, len, cps2key, UPPER_LIMIT);
rz_crypto_append(cry, output, len);
@ -2916,12 +2925,28 @@ static bool update(RzCrypto *cry, const ut8 *buf, int len) {
return true;
}
static bool cps2_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEWS0(ut32, 2);
return cry->user != NULL;
}
static bool cps2_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_cps2 = {
.name = "cps2",
.set_key = set_key,
.get_key_size = get_key_size,
.use = cps2_use,
.update = update
.update = update,
.init = cps2_init,
.fini = cps2_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -15,8 +15,6 @@ struct des_state {
int i;
};
static struct des_state st = { { 0 } };
static ut32 be32(const ut8 *buf4) {
ut32 val = buf4[0] << 8;
val |= buf4[1];
@ -79,6 +77,9 @@ static int des_decrypt(struct des_state *st, const ut8 *input, ut8 *output) {
}
static bool des_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
rz_return_val_if_fail(cry->user && key, 0);
struct des_state *st = (struct des_state *)cry->user;
ut32 keylo, keyhi, i;
if (keylen != DES_KEY_SIZE) {
return false;
@ -87,22 +88,24 @@ static bool des_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int
keylo = be32(key);
keyhi = be32(key + 4);
st.key_size = DES_KEY_SIZE;
st.rounds = 16;
cry->dir = direction; // = direction == 0;
st->key_size = DES_KEY_SIZE;
st->rounds = 16;
cry->dir = direction;
// key permutation to derive round keys
rz_des_permute_key(&keylo, &keyhi);
for (i = 0; i < 16; i++) {
// filling round keys space
rz_des_round_key(i, &st.keylo[i], &st.keyhi[i], &keylo, &keyhi);
rz_des_round_key(i, &st->keylo[i], &st->keyhi[i], &keylo, &keyhi);
}
return true;
}
static int des_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
struct des_state *st = (struct des_state *)cry->user;
return st->key_size;
}
static bool des_use(const char *algo) {
@ -110,6 +113,9 @@ static bool des_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, false);
struct des_state *st = (struct des_state *)cry->user;
if (len <= 0) {
return false;
}
@ -139,15 +145,15 @@ static bool update(RzCrypto *cry, const ut8 *buf, int len) {
// }
int i;
if (cry->dir) {
if (cry->dir == RZ_CRYPTO_DIR_DECRYPT) {
for (i = 0; i < blocks; i++) {
ut32 next = (DES_BLOCK_SIZE * i);
des_decrypt(&st, ibuf + next, obuf + next);
des_decrypt(st, ibuf + next, obuf + next);
}
} else {
for (i = 0; i < blocks; i++) {
ut32 next = (DES_BLOCK_SIZE * i);
des_encrypt(&st, ibuf + next, obuf + next);
des_encrypt(st, ibuf + next, obuf + next);
}
}
@ -161,13 +167,28 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool des_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct des_state);
return cry->user != NULL;
}
static bool des_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_des = {
.name = "des-ecb",
.set_key = des_set_key,
.get_key_size = des_get_key_size,
.use = des_use,
.update = update,
.final = final
.final = final,
.init = des_init,
.fini = des_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -5,10 +5,8 @@
#include <rz_lib.h>
#include <rz_crypto.h>
static int flag = 0;
static bool punycode_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
flag = direction;
cry->dir = direction;
return true;
}
@ -21,9 +19,13 @@ static bool punycode_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (len < 1 || !buf) {
return false;
}
char *obuf;
int olen;
if (flag) {
if (cry->dir == RZ_CRYPTO_DIR_DECRYPT) {
obuf = rz_punycode_decode((const char *)buf, len, &olen);
} else {
obuf = rz_punycode_encode(buf, len, &olen);

View file

@ -1,5 +1,6 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
#define BITS 1024
#define RC2_KEY_SIZE 64 // bytes
@ -435,17 +436,19 @@ static void rc2_crypt(struct rc2_state *state, const ut8 *inbuf, ut8 *outbuf, in
///////////////////////////////////////////////////////////
static struct rc2_state state;
static int flag = 0;
static bool rc2_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
flag = direction;
state.key_size = 1024;
return rc2_expandKey(&state, key, keylen);
rz_return_val_if_fail(cry->user && key, false);
struct rc2_state *state = (struct rc2_state *)cry->user;
cry->dir = direction;
state->key_size = 1024;
return rc2_expandKey(state, key, keylen);
}
static int rc2_get_key_size(RzCrypto *cry) {
return state.key_size;
rz_return_val_if_fail(cry->user, 0);
struct rc2_state *state = (struct rc2_state *)cry->user;
return state->key_size;
}
static bool rc2_use(const char *algo) {
@ -453,14 +456,17 @@ static bool rc2_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, false);
struct rc2_state *state = (struct rc2_state *)cry->user;
ut8 *obuf = calloc(1, len);
if (!obuf) {
return false;
}
if (flag == 0) {
rc2_crypt(&state, buf, obuf, len);
} else if (flag == 1) {
rc2_dcrypt(&state, buf, obuf, len);
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
rc2_crypt(state, buf, obuf, len);
} else {
rc2_dcrypt(state, buf, obuf, len);
}
rz_crypto_append(cry, obuf, len);
free(obuf);
@ -471,13 +477,29 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool rc2_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct rc2_state);
return cry->user != NULL;
}
static bool rc2_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_rc2 = {
.name = "rc2",
.set_key = rc2_set_key,
.get_key_size = rc2_get_key_size,
.use = rc2_use,
.update = update,
.final = final
.final = final,
.init = rc2_init,
.fini = rc2_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -3,6 +3,7 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
struct rc4_state {
ut8 perm[256];
@ -24,7 +25,7 @@ static __inline void swap_bytes(ut8 *a, ut8 *b) {
* which can have arbitrary length.
*/
static bool rc4_init(struct rc4_state *const state, const ut8 *key, int keylen) {
static bool rc4_init_state(struct rc4_state *const state, const ut8 *key, int keylen) {
ut8 j;
int i;
@ -72,14 +73,18 @@ static void rc4_crypt(struct rc4_state *const state, const ut8 *inbuf, ut8 *outb
///////////////////////////////////////////////////////////
static struct rc4_state st;
static bool rc4_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
return rc4_init(&st, key, keylen);
rz_return_val_if_fail(cry->user && key, false);
struct rc4_state *st = (struct rc4_state *)cry->user;
return rc4_init_state(st, key, keylen);
}
static int rc4_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
struct rc4_state *st = (struct rc4_state *)cry->user;
return st->key_size;
}
static bool rc4_use(const char *algo) {
@ -87,11 +92,14 @@ static bool rc4_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, false);
struct rc4_state *st = (struct rc4_state *)cry->user;
ut8 *obuf = calloc(1, len);
if (!obuf) {
return false;
}
rc4_crypt(&st, buf, obuf, len);
rc4_crypt(st, buf, obuf, len);
rz_crypto_append(cry, obuf, len);
free(obuf);
return false;
@ -101,13 +109,29 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool rc4_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct rc4_state);
return cry->user != NULL;
}
static bool rc4_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_rc4 = {
.name = "rc4",
.set_key = rc4_set_key,
.get_key_size = rc4_get_key_size,
.use = rc4_use,
.update = update,
.final = final
.final = final,
.init = rc4_init,
.fini = rc4_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -4,6 +4,7 @@
//Implemented AES version of RC6. keylen = 16, 23, or 32 bytes; w = 32; and r = 20.
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
#define Pw 0xb7e15163
#define Qw 0x9e3779b9
@ -18,33 +19,28 @@ struct rc6_state {
int key_size;
};
static bool flag;
static bool rc6_init(struct rc6_state *const state, const ut8 *key, int keylen, int direction) {
static bool rc6_init_state(struct rc6_state *const state, const ut8 *key, int keylen) {
if (keylen != 128 / 8 && keylen != 192 / 8 && keylen != 256 / 8) {
return false;
}
flag = (direction != 0);
int u = w / 8;
int c = keylen / u;
int t = 2 * r + 4;
#ifdef _MSC_VER
ut32 *L = (ut32 *)malloc(sizeof(ut32) * c);
#else
ut32 L[c];
#endif
ut32 *L = RZ_NEWS(ut32, c);
if (!L) {
rz_warn_if_reached();
return false;
}
ut32 A = 0, B = 0, k = 0, j = 0;
ut32 v = 3 * t; //originally v = 2 * ((c > t) ? c : t);
int i, off;
int i;
for (i = 0, off = 0; i < c; i++) {
L[i] = ((key[off++] & 0xff));
L[i] |= ((key[off++] & 0xff) << 8);
L[i] |= ((key[off++] & 0xff) << 16);
L[i] |= ((key[off++] & 0xff) << 24);
for (i = 0; i < c; i++) {
L[i] = rz_read_at_le32(key, i * 4);
}
(state->S)[0] = Pw;
@ -60,9 +56,8 @@ static bool rc6_init(struct rc6_state *const state, const ut8 *key, int keylen,
}
state->key_size = keylen / 8;
#ifdef _MSC_VER
free(L);
#endif
return true;
}
@ -71,12 +66,8 @@ static void rc6_encrypt(struct rc6_state *const state, const ut8 *inbuf, ut8 *ou
ut32 aux;
ut32 data[BLOCK_SIZE / 4];
int i;
int off = 0;
for (i = 0; i < BLOCK_SIZE / 4; i++) {
data[i] = ((inbuf[off++] & 0xff));
data[i] |= ((inbuf[off++] & 0xff) << 8);
data[i] |= ((inbuf[off++] & 0xff) << 16);
data[i] |= ((inbuf[off++] & 0xff) << 24);
data[i] = rz_read_at_le32(inbuf, i * 4);
}
ut32 A = data[0], B = data[1], C = data[2], D = data[3];
@ -155,14 +146,20 @@ static void rc6_decrypt(struct rc6_state *const state, const ut8 *inbuf, ut8 *ou
}
}
static struct rc6_state st;
static bool rc6_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
return rc6_init(&st, key, keylen, direction);
rz_return_val_if_fail(cry->user && key, false);
struct rc6_state *st = (struct rc6_state *)cry->user;
cry->dir = direction;
return rc6_init_state(st, key, keylen);
}
static int rc6_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
struct rc6_state *st = (struct rc6_state *)cry->user;
return st->key_size;
}
static bool rc6_use(const char *algo) {
@ -170,6 +167,9 @@ static bool rc6_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, false);
struct rc6_state *st = (struct rc6_state *)cry->user;
if (len % BLOCK_SIZE != 0) { //let user handle with with pad.
eprintf("Input should be multiple of 128bit.\n");
return false;
@ -183,13 +183,13 @@ static bool update(RzCrypto *cry, const ut8 *buf, int len) {
}
int i;
if (flag) {
if (cry->dir == RZ_CRYPTO_DIR_DECRYPT) {
for (i = 0; i < blocks; i++) {
rc6_decrypt(&st, buf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
rc6_decrypt(st, buf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
}
} else {
for (i = 0; i < blocks; i++) {
rc6_encrypt(&st, buf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
rc6_encrypt(st, buf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
}
}
@ -202,13 +202,29 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool rc6_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct rc6_state);
return cry->user != NULL;
}
static bool rc6_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_rc6 = {
.name = "rc6",
.set_key = rc6_set_key,
.get_key_size = rc6_get_key_size,
.use = rc6_use,
.update = update,
.final = final
.final = final,
.init = rc6_init,
.fini = rc6_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -3,6 +3,7 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
#define NAME "rol"
@ -13,7 +14,7 @@ struct rol_state {
int key_size;
};
static bool rol_init(struct rol_state *const state, const ut8 *key, int keylen) {
static bool rol_init_state(struct rol_state *const state, const ut8 *key, int keylen) {
if (!state || !key || keylen < 1 || keylen > MAX_rol_KEY_SIZE) {
return false;
}
@ -34,16 +35,19 @@ static void rol_crypt(struct rol_state *const state, const ut8 *inbuf, ut8 *outb
}
}
static struct rol_state st;
static int flag = 0;
static bool rol_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
flag = direction;
return rol_init(&st, key, keylen);
rz_return_val_if_fail(cry->user && key, false);
struct rol_state *st = (struct rol_state *)cry->user;
cry->dir = direction;
return rol_init_state(st, key, keylen);
}
static int rol_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
struct rol_state *st = (struct rol_state *)cry->user;
return st->key_size;
}
static bool rol_use(const char *algo) {
@ -51,20 +55,37 @@ static bool rol_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (flag) {
eprintf("Use ROR\n");
rz_return_val_if_fail(cry->user, false);
struct rol_state *st = (struct rol_state *)cry->user;
if (cry->dir) {
eprintf("Use ROR algorithm to decrypt\n");
return false;
}
ut8 *obuf = calloc(1, len);
if (!obuf) {
return false;
}
rol_crypt(&st, buf, obuf, len);
rol_crypt(st, buf, obuf, len);
rz_crypto_append(cry, obuf, len);
free(obuf);
return true;
}
static bool rol_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct rol_state);
return cry->user != NULL;
}
static bool rol_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_rol = {
.name = NAME,
.set_key = rol_set_key,
@ -72,6 +93,8 @@ RzCryptoPlugin rz_crypto_plugin_rol = {
.use = rol_use,
.update = update,
.final = update,
.init = rol_init,
.fini = rol_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -1,5 +1,6 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
#define NAME "ror"
@ -10,7 +11,7 @@ struct ror_state {
int key_size;
};
static bool ror_init(struct ror_state *const state, const ut8 *key, int keylen) {
static bool ror_init_state(struct ror_state *const state, const ut8 *key, int keylen) {
if (!state || !key || keylen < 1 || keylen > MAX_ror_KEY_SIZE) {
return false;
}
@ -31,16 +32,19 @@ static void ror_crypt(struct ror_state *const state, const ut8 *inbuf, ut8 *outb
}
}
static struct ror_state st;
static int flag = 0;
static bool ror_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
flag = direction;
return ror_init(&st, key, keylen);
rz_return_val_if_fail(cry->user && key, false);
struct ror_state *st = (struct ror_state *)cry->user;
cry->dir = direction;
return ror_init_state(st, key, keylen);
}
static int ror_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
struct ror_state *st = (struct ror_state *)cry->user;
return st->key_size;
}
static bool ror_use(const char *algo) {
@ -48,20 +52,37 @@ static bool ror_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
if (flag) {
eprintf("USE ROL\n");
rz_return_val_if_fail(cry->user, false);
struct ror_state *st = (struct ror_state *)cry->user;
if (cry->dir) {
eprintf("Use ROL algorithm to decrypt\n");
return false;
}
ut8 *obuf = calloc(1, len);
if (!obuf) {
return false;
}
ror_crypt(&st, buf, obuf, len);
ror_crypt(st, buf, obuf, len);
rz_crypto_append(cry, obuf, len);
free(obuf);
return true;
}
static bool ror_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct ror_state);
return cry->user != NULL;
}
static bool ror_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_ror = {
.name = NAME,
.set_key = ror_set_key,
@ -69,6 +90,8 @@ RzCryptoPlugin rz_crypto_plugin_ror = {
.use = ror_use,
.update = update,
.final = update,
.init = ror_init,
.fini = ror_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -3,6 +3,7 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
int mod(int a, int b) {
if (b < 0) {
@ -15,7 +16,7 @@ int mod(int a, int b) {
return ret;
}
static bool rot_init(ut8 *rotkey, const ut8 *key, int keylen) {
static bool rot_init_state(ut8 *rotkey, const ut8 *key, int keylen) {
if (rotkey && key && keylen > 0) {
int i = atoi((const char *)key);
*rotkey = (ut8)mod(i, 26);
@ -53,12 +54,17 @@ static void rot_decrypt(ut8 key, const ut8 *inbuf, ut8 *outbuf, int buflen) {
}
}
static ut8 rot_key;
static int flag = 0;
static bool rot_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
flag = direction;
return rot_init(&rot_key, key, keylen);
rz_return_val_if_fail(cry->user && key, false);
ut8 *rot_key = (ut8 *)cry->user;
if (keylen > (sizeof(ut8) * 8) || keylen < 0) {
return false;
}
cry->dir = direction;
return rot_init_state(rot_key, key, keylen);
}
static int rot_get_key_size(RzCrypto *cry) {
@ -71,14 +77,17 @@ static bool rot_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, false);
ut8 *rot_key = (ut8 *)cry->user;
ut8 *obuf = calloc(1, len);
if (!obuf) {
return false;
}
if (flag == 0) {
rot_crypt(rot_key, buf, obuf, len);
} else if (flag == 1) {
rot_decrypt(rot_key, buf, obuf, len);
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
rot_crypt(*rot_key, buf, obuf, len);
} else {
rot_decrypt(*rot_key, buf, obuf, len);
}
rz_crypto_append(cry, obuf, len);
free(obuf);
@ -89,13 +98,29 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool rol_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(ut8);
return cry->user != NULL;
}
static bool rol_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_rot = {
.name = "rot",
.set_key = rot_set_key,
.get_key_size = rot_get_key_size,
.use = rot_use,
.update = update,
.final = final
.final = final,
.init = rol_init,
.fini = rol_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -2,22 +2,24 @@
#include <rz_crypto.h>
#include "crypto_serpent_algo.h"
static struct serpent_state st = { { 0 } };
static bool serpent_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
eprintf("key_size: %d\n", keylen);
rz_return_val_if_fail(cry->user && key, false);
serpent_state_t *st = (serpent_state_t *)cry->user;
if ((keylen != 128 / 8) && (keylen != 192 / 8) && (keylen != 256 / 8)) {
return false;
}
st.key_size = keylen * 8;
eprintf("key_size: %d\n", st.key_size);
memcpy(st.key, key, keylen);
st->key_size = keylen * 8;
memcpy(st->key, key, keylen);
cry->dir = direction;
return true;
}
static int serpent_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
serpent_state_t *st = (serpent_state_t *)cry->user;
return st->key_size;
}
static bool serpent_use(const char *algo) {
@ -27,6 +29,12 @@ static bool serpent_use(const char *algo) {
#define BLOCK_SIZE 16
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, 0);
serpent_state_t *st = (serpent_state_t *)cry->user;
if (len < 1) {
return false;
}
// Pad to the block size, do not append dummy block
const int diff = (BLOCK_SIZE - (len % BLOCK_SIZE)) % BLOCK_SIZE;
const int size = len + diff;
@ -59,17 +67,17 @@ static bool update(RzCrypto *cry, const ut8 *buf, int len) {
ibuf[len / 4] = rz_read_le32(tail);
}
if (cry->dir == 0) {
if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
for (i = 0; i < blocks; i++) {
// delta in number of ut32
const int delta = (BLOCK_SIZE * i) / 4;
serpent_encrypt(&st, ibuf + delta, tmp + delta);
serpent_encrypt(st, ibuf + delta, tmp + delta);
}
} else if (cry->dir > 0) {
} else {
for (i = 0; i < blocks; i++) {
// delta in number of ut32
const int delta = (BLOCK_SIZE * i) / 4;
serpent_decrypt(&st, ibuf + delta, tmp + delta);
serpent_decrypt(st, ibuf + delta, tmp + delta);
}
}
@ -94,13 +102,29 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool serpent_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(serpent_state_t);
return cry->user != NULL;
}
static bool serpent_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_serpent = {
.name = "serpent-ecb",
.set_key = serpent_set_key,
.get_key_size = serpent_get_key_size,
.use = serpent_use,
.update = update,
.final = final
.final = final,
.init = serpent_init,
.fini = serpent_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -87,9 +87,8 @@ void apply_FP(ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK]) {
}
}
void serpent_keyschedule(struct serpent_state st,
ut32 subkeys[NB_SUBKEYS * DW_BY_BLOCK]) {
rz_return_if_fail((st.key_size == 128) || (st.key_size == 192) || (st.key_size == 256));
void serpent_keyschedule(const serpent_state_t *st, ut32 subkeys[NB_SUBKEYS * DW_BY_BLOCK]) {
rz_return_if_fail((st->key_size == 128) || (st->key_size == 192) || (st->key_size == 256));
ut32 tmpkeys[DW_BY_BLOCK * NB_SUBKEYS + DW_BY_USERKEY] = { 0 };
const ut32 phi = 0x9e3779b9;
@ -97,13 +96,13 @@ void serpent_keyschedule(struct serpent_state st,
ut8 in, out;
int i, j, l;
for (i = 0; i < st.key_size / 32; i++) {
tmpkeys[i] = st.key[i];
for (i = 0; i < st->key_size / 32; i++) {
tmpkeys[i] = st->key[i];
}
// Padding key
if (st.key_size != 256) {
tmpkeys[st.key_size / 32] = 1;
if (st->key_size != 256) {
tmpkeys[st->key_size / 32] = 1;
}
for (i = DW_BY_USERKEY; i < NB_SUBKEYS * DW_BY_BLOCK + DW_BY_USERKEY; i++) {
@ -127,8 +126,7 @@ void serpent_keyschedule(struct serpent_state st,
// Apply IP on every subkey
for (i = 0; i < NB_SUBKEYS; i++) {
apply_IP(&subkeys[i * DW_BY_BLOCK],
&tmpkeys[DW_BY_USERKEY + i * DW_BY_BLOCK]);
apply_IP(&subkeys[i * DW_BY_BLOCK], &tmpkeys[DW_BY_USERKEY + i * DW_BY_BLOCK]);
}
memcpy(subkeys, tmpkeys + DW_BY_USERKEY, 132 * sizeof(ut32));
@ -216,13 +214,13 @@ void apply_round_inv(int round, ut32 block[DW_BY_BLOCK],
apply_xor(block, subkeys + 4 * round);
}
void serpent_encrypt(struct serpent_state *st, ut32 in[DW_BY_BLOCK],
void serpent_encrypt(serpent_state_t *st, ut32 in[DW_BY_BLOCK],
ut32 out[DW_BY_BLOCK]) {
int i;
ut32 subkeys[DW_BY_BLOCK * NB_SUBKEYS] = { 0 };
ut32 tmp_block[DW_BY_BLOCK] = { 0 };
serpent_keyschedule(*st, subkeys);
serpent_keyschedule(st, subkeys);
apply_IP(in, tmp_block);
for (i = 0; i < NB_ROUNDS; i++) {
@ -231,13 +229,13 @@ void serpent_encrypt(struct serpent_state *st, ut32 in[DW_BY_BLOCK],
apply_FP(tmp_block, out);
}
void serpent_decrypt(struct serpent_state *st, ut32 in[DW_BY_BLOCK],
void serpent_decrypt(serpent_state_t *st, ut32 in[DW_BY_BLOCK],
ut32 out[DW_BY_BLOCK]) {
int i;
ut32 subkeys[DW_BY_BLOCK * NB_SUBKEYS] = { 0 };
ut32 tmp_block[DW_BY_BLOCK] = { 0 };
serpent_keyschedule(*st, subkeys);
serpent_keyschedule(st, subkeys);
apply_IP(in, tmp_block);
for (i = NB_ROUNDS - 1; i >= 0; i--) {

View file

@ -2,16 +2,17 @@
#define CRYPTO_SERPENT_ALGO_H
#include <rz_crypto.h>
#include <rz_util.h>
#define DW_BY_BLOCK 4
#define DW_BY_USERKEY 8
#define NB_ROUNDS 32
#define NB_SUBKEYS 33
#define NIBBLES_BY_SUBKEY 32
struct serpent_state {
typedef struct serpent_state {
ut32 key[8];
int key_size;
};
} serpent_state_t;
/*
* st: A pointer to a serpent_state structure containing the key and the key size.
@ -19,7 +20,7 @@ struct serpent_state {
* out: When the function returns, the block of data encrypted by serpent
* with the key contained in st.
*/
void serpent_encrypt(struct serpent_state *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK]);
void serpent_encrypt(serpent_state_t *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK]);
/*
* st: A pointer to a serpent_state structure containing the key and the key size.
@ -27,14 +28,13 @@ void serpent_encrypt(struct serpent_state *st, ut32 in[DW_BY_BLOCK], ut32 out[DW
* out: When the function returns, the block of data decrypted by serpent
* with the key contained in st.
*/
void serpent_decrypt(struct serpent_state *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK]);
void serpent_decrypt(serpent_state_t *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK]);
/*
* st: A serpent_state structure containing the key and the key size.
* subkeys: When the function returns, an array of double words containings
* all the subkeys needed for the encryptio/dcryption with serpent.
*/
void serpent_keyschedule(struct serpent_state st,
ut32 subkeys[NB_SUBKEYS * DW_BY_BLOCK]);
void serpent_keyschedule(const serpent_state_t *st, ut32 subkeys[NB_SUBKEYS * DW_BY_BLOCK]);
#endif

View file

@ -3,6 +3,7 @@
#include <rz_lib.h>
#include <rz_crypto.h>
#include <rz_util.h>
#define MAX_xor_KEY_SIZE 32768
@ -11,34 +12,39 @@ struct xor_state {
int key_size;
};
static struct xor_state st;
static bool xor_init(struct xor_state *const state, const ut8 *key, int keylen) {
static bool xor_init_state(struct xor_state *const state, const ut8 *key, int keylen) {
if (!state || !key || keylen < 1) { // || keylen > MAX_xor_KEY_SIZE) {
return false;
}
state->key_size = keylen;
state->key = malloc(keylen);
if (!state->key) {
return false;
}
memcpy(state->key, key, keylen);
return true;
}
/*
* Encrypt/Decrypt xor state buffer using the supplied key
*/
// Encrypt/Decrypt xor state buffer using the supplied key
static void xor_crypt(struct xor_state *const state, const ut8 *inbuf, ut8 *outbuf, int buflen) {
int i; //index for input
for (i = 0; i < buflen; i++) {
outbuf[i] = inbuf[i] ^ state->key[(i % state->key_size)];
}
}
static bool xor_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
return xor_init(&st, key, keylen);
rz_return_val_if_fail(cry->user, 0);
struct xor_state *st = (struct xor_state *)cry->user;
return xor_init_state(st, key, keylen);
}
static int xor_get_key_size(RzCrypto *cry) {
return st.key_size;
rz_return_val_if_fail(cry->user, 0);
struct xor_state *st = (struct xor_state *)cry->user;
return st->key_size;
}
static bool xor_use(const char *algo) {
@ -46,11 +52,14 @@ static bool xor_use(const char *algo) {
}
static bool update(RzCrypto *cry, const ut8 *buf, int len) {
rz_return_val_if_fail(cry->user, false);
struct xor_state *st = (struct xor_state *)cry->user;
ut8 *obuf = calloc(1, len);
if (!obuf) {
return false;
}
xor_crypt(&st, buf, obuf, len);
xor_crypt(st, buf, obuf, len);
rz_crypto_append(cry, obuf, len);
free(obuf);
return true;
@ -60,13 +69,33 @@ static bool final(RzCrypto *cry, const ut8 *buf, int len) {
return update(cry, buf, len);
}
static bool xor_init(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
cry->user = RZ_NEW0(struct xor_state);
return cry->user != NULL;
}
static bool xor_fini(RzCrypto *cry) {
rz_return_val_if_fail(cry, false);
struct xor_state *state = (struct xor_state *)cry->user;
if (state) {
free(state->key);
}
free(cry->user);
return true;
}
RzCryptoPlugin rz_crypto_plugin_xor = {
.name = "xor",
.set_key = xor_set_key,
.get_key_size = xor_get_key_size,
.use = xor_use,
.update = update,
.final = final
.final = final,
.init = xor_init,
.fini = xor_fini,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -1,13 +1,6 @@
// SPDX-FileCopyrightText: 2009 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
/*
* This code was done
* by an anonymous gnome
* ------------------------
* That's pure mathematics, so no sense to adding a license here.
*/
#include <stdlib.h>
#include <math.h>
#include "rz_types.h"
@ -29,8 +22,10 @@ RZ_API double rz_hash_entropy(const ut8 *data, ut64 size) {
}
return h;
}
RZ_API double rz_hash_entropy_fraction(const ut8 *data, ut64 size) {
return size ? rz_hash_entropy(data, size) /
log2((double)RZ_MIN(size, 256))
: 0;
if (size) {
return rz_hash_entropy(data, size) / log2((double)RZ_MIN(size, 256));
}
return 0;
}

View file

@ -27,9 +27,6 @@ static const struct {
{ "hamdist", RZ_HASH_HAMDIST },
{ "pcprint", RZ_HASH_PCPRINT },
{ "mod255", RZ_HASH_MOD255 },
// {"base64", RZ_HASH_BASE64},
// {"base91", RZ_HASH_BASE91},
// {"punycode", RZ_HASH_PUNYCODE},
{ "luhn", RZ_HASH_LUHN },
{ "fletcher8", RZ_HASH_FLETCHER8 },
@ -108,7 +105,6 @@ static const struct {
{ /* CRC-64/XZ */ "crc64xz", RZ_HASH_CRC64_XZ },
{ /* CRC-64/ISO */ "crc64iso", RZ_HASH_CRC64_ISO },
#endif /* #if RZ_HAVE_CRC64_EXTRA */
{ NULL, 0 }
};
/* returns 0-100 */
@ -177,9 +173,9 @@ RZ_API ut8 rz_hash_deviation(const ut8 *b, ut64 len) {
}
RZ_API const char *rz_hash_name(ut64 bit) {
int i;
for (i = 1; hash_name_bytes[i].bit; i++) {
if (bit & hash_name_bytes[i].bit) {
size_t i;
for (i = 1; i < RZ_ARRAY_SIZE(hash_name_bytes); i++) {
if (bit == hash_name_bytes[i].bit) {
return hash_name_bytes[i].name;
}
}
@ -289,7 +285,7 @@ RZ_API int rz_hash_size(ut64 algo) {
/* Converts a comma separated list of names to the respective bit combination */
RZ_API ut64 rz_hash_name_to_bits(const char *name) {
char tmp[128];
int i;
size_t i;
const char *ptr = name;
ut64 ret = 0;
@ -306,7 +302,7 @@ RZ_API ut64 rz_hash_name_to_bits(const char *name) {
/* Safety net */
tmp[i] = '\0';
for (i = 0; hash_name_bytes[i].name; i++) {
for (i = 0; i < RZ_ARRAY_SIZE(hash_name_bytes); i++) {
if (!strcmp(tmp, hash_name_bytes[i].name)) {
ret |= hash_name_bytes[i].bit;
break;
@ -327,7 +323,7 @@ RZ_API void rz_hash_do_spice(RzHash *ctx, ut64 algo, int loops, RzHashSeed *seed
int i, len, hlen = rz_hash_size(algo);
for (i = 0; i < loops; i++) {
if (seed) {
if (seed->prefix) {
if (seed->as_prefix) {
memcpy(buf, seed->buf, seed->len);
memcpy(buf + seed->len, ctx->digest, hlen);
} else {

View file

@ -30,7 +30,7 @@ RZ_API void rz_hash_do_begin(RzHash *ctx, ut64 flags) {
rz_md4_init(&ctx->md4);
}
if_has_flag(RZ_HASH_MD5) {
rz_hash_do_md5(ctx, NULL, -1);
MD5_Init(&ctx->md5);
}
if_has_flag(RZ_HASH_SHA1) {
rz_sha1_init(&ctx->sha1);
@ -47,12 +47,194 @@ RZ_API void rz_hash_do_begin(RzHash *ctx, ut64 flags) {
ctx->rst = false;
}
#define HANDLE_CRC_PRESET(rbits, aname) \
do { \
if (algobit & RZ_HASH_##aname) { \
ut##rbits res = rz_hash_crc_preset(buf, len, CRC_PRESET_##aname); \
rz_write_be##rbits(ctx->digest, res); \
} \
} while (0)
RZ_API void rz_hash_do_update(RzHash *ctx, ut64 algobit, const ut8 *buf, ut64 len) {
if (algobit & RZ_HASH_MD4) {
rz_md4_update(&ctx->md4, buf, len);
}
if (algobit & RZ_HASH_MD5) {
MD5_Update(&ctx->md5, buf, len);
}
if (algobit & RZ_HASH_SHA1) {
rz_sha1_update(&ctx->sha1, buf, len);
}
if (algobit & RZ_HASH_SHA256) {
SHA256_Update(&ctx->sha256, buf, len);
}
if (algobit & RZ_HASH_SHA384) {
SHA384_Update(&ctx->sha384, buf, len);
}
if (algobit & RZ_HASH_SHA512) {
SHA512_Update(&ctx->sha512, buf, len);
}
if (algobit & RZ_HASH_XXHASH) {
ut32 res = rz_hash_xxhash(buf, len);
rz_write_le32(ctx->digest, res);
}
if (algobit & RZ_HASH_FLETCHER8) {
ut8 res = rz_hash_fletcher8(buf, len);
rz_write_le8(ctx->digest, res);
}
if (algobit & RZ_HASH_FLETCHER16) {
ut16 res = rz_hash_fletcher16(buf, len);
rz_write_le16(ctx->digest, res);
}
if (algobit & RZ_HASH_FLETCHER32) {
ut32 res = rz_hash_fletcher32(buf, len);
rz_write_le32(ctx->digest, res);
}
if (algobit & RZ_HASH_FLETCHER64) {
ut64 res = rz_hash_fletcher64(buf, len);
rz_write_le64(ctx->digest, res);
}
if (algobit & RZ_HASH_ADLER32) {
ut32 res = rz_hash_adler32(buf, len);
rz_write_le32(ctx->digest, res);
}
if (algobit & RZ_HASH_HAMDIST) {
*ctx->digest = rz_hash_hamdist(buf, len);
}
if (algobit & RZ_HASH_PCPRINT) {
*ctx->digest = rz_hash_pcprint(buf, len);
}
if (algobit & RZ_HASH_PARITY) {
*ctx->digest = rz_hash_parity(buf, len);
}
if (algobit & RZ_HASH_ENTROPY) {
rz_mem_memzero(ctx->digest, sizeof(ctx->entropy));
ctx->entropy = rz_hash_entropy(buf, len);
}
if (algobit & RZ_HASH_XOR) {
*ctx->digest = rz_hash_xor(buf, len);
}
if (algobit & RZ_HASH_XORPAIR) {
ut16 res = rz_hash_xorpair(buf, len);
rz_write_le16(ctx->digest, res);
}
if (algobit & RZ_HASH_MOD255) {
*ctx->digest = rz_hash_mod255(buf, len);
}
if (algobit & RZ_HASH_LUHN) {
*ctx->digest = rz_hash_luhn(buf, len);
}
if (algobit & RZ_HASH_CRC8_SMBUS) {
ut8 res = rz_hash_crc_preset(buf, len, CRC_PRESET_8_SMBUS);
rz_write_le8(ctx->digest, res);
}
#if RZ_HAVE_CRC8_EXTRA
HANDLE_CRC_PRESET(8, CRC8_CDMA2000);
HANDLE_CRC_PRESET(8, CRC8_CDMA2000);
HANDLE_CRC_PRESET(8, CRC8_DARC);
HANDLE_CRC_PRESET(8, CRC8_DVB_S2);
HANDLE_CRC_PRESET(8, CRC8_EBU);
HANDLE_CRC_PRESET(8, CRC8_ICODE);
HANDLE_CRC_PRESET(8, CRC8_ITU);
HANDLE_CRC_PRESET(8, CRC8_MAXIM);
HANDLE_CRC_PRESET(8, CRC8_ROHC);
HANDLE_CRC_PRESET(8, CRC8_WCDMA);
#endif /* #if RZ_HAVE_CRC8_EXTRA */
#if RZ_HAVE_CRC15_EXTRA
if (algobit & RZ_HASH_CRC15_CAN) {
ut16 res = rz_hash_crc_preset(buf, len, CRC_PRESET_15_CAN);
rz_write_be16(ctx->digest, res);
}
#endif /* #if RZ_HAVE_CRC15_EXTRA */
if (algobit & RZ_HASH_CRC16) {
ut16 res = rz_hash_crc_preset(buf, len, CRC_PRESET_16);
rz_write_be16(ctx->digest, res);
}
if (algobit & RZ_HASH_CRC16_HDLC) {
ut16 res = rz_hash_crc_preset(buf, len, CRC_PRESET_16_HDLC);
rz_write_be16(ctx->digest, res);
}
if (algobit & RZ_HASH_CRC16_USB) {
ut16 res = rz_hash_crc_preset(buf, len, CRC_PRESET_16_USB);
rz_write_be16(ctx->digest, res);
}
if (algobit & RZ_HASH_CRC16_CITT) {
ut16 res = rz_hash_crc_preset(buf, len, CRC_PRESET_16_CITT);
rz_write_be16(ctx->digest, res);
}
#if RZ_HAVE_CRC16_EXTRA
HANDLE_CRC_PRESET(16, CRC16_AUG_CCITT);
HANDLE_CRC_PRESET(16, CRC16_BUYPASS);
HANDLE_CRC_PRESET(16, CRC16_CDMA2000);
HANDLE_CRC_PRESET(16, CRC16_DDS110);
HANDLE_CRC_PRESET(16, CRC16_DECT_R);
HANDLE_CRC_PRESET(16, CRC16_DECT_X);
HANDLE_CRC_PRESET(16, CRC16_DNP);
HANDLE_CRC_PRESET(16, CRC16_EN13757);
HANDLE_CRC_PRESET(16, CRC16_GENIBUS);
HANDLE_CRC_PRESET(16, CRC16_MAXIM);
HANDLE_CRC_PRESET(16, CRC16_MCRF4XX);
HANDLE_CRC_PRESET(16, CRC16_RIELLO);
HANDLE_CRC_PRESET(16, CRC16_T10_DIF);
HANDLE_CRC_PRESET(16, CRC16_TELEDISK);
HANDLE_CRC_PRESET(16, CRC16_TMS37157);
HANDLE_CRC_PRESET(16, CRCA);
HANDLE_CRC_PRESET(16, CRC16_KERMIT);
HANDLE_CRC_PRESET(16, CRC16_MODBUS);
HANDLE_CRC_PRESET(16, CRC16_X25);
HANDLE_CRC_PRESET(16, CRC16_XMODEM);
#endif /* #if RZ_HAVE_CRC16_EXTRA */
#if RZ_HAVE_CRC24
if (algobit & RZ_HASH_CRC24) {
ut32 res = rz_hash_crc_preset(buf, len, CRC_PRESET_24);
rz_write_be24(ctx->digest, res);
}
#endif /* #if RZ_HAVE_CRC24 */
if (algobit & RZ_HASH_CRC32) {
ut32 res = rz_hash_crc_preset(buf, len, CRC_PRESET_32);
rz_write_be32(ctx->digest, res);
}
if (algobit & RZ_HASH_CRC32C) {
ut32 res = rz_hash_crc_preset(buf, len, CRC_PRESET_32C);
rz_write_be32(ctx->digest, res);
}
if (algobit & RZ_HASH_CRC32_ECMA_267) {
ut32 res = rz_hash_crc_preset(buf, len, CRC_PRESET_32_ECMA_267);
rz_write_be32(ctx->digest, res);
}
#if RZ_HAVE_CRC32_EXTRA
HANDLE_CRC_PRESET(32, CRC32_BZIP2);
HANDLE_CRC_PRESET(32, CRC32D);
HANDLE_CRC_PRESET(32, CRC32_MPEG2);
HANDLE_CRC_PRESET(32, CRC32_POSIX);
HANDLE_CRC_PRESET(32, CRC32Q);
HANDLE_CRC_PRESET(32, CRC32_JAMCRC);
HANDLE_CRC_PRESET(32, CRC32_XFER);
#endif /* #if RZ_HAVE_CRC32_EXTRA */
#if RZ_HAVE_CRC64
HANDLE_CRC_PRESET(64, CRC64);
#endif /* #if RZ_HAVE_CRC64 */
#if RZ_HAVE_CRC64_EXTRA
HANDLE_CRC_PRESET(64, CRC64_ECMA182);
HANDLE_CRC_PRESET(64, CRC64_WE);
HANDLE_CRC_PRESET(64, CRC64_XZ);
HANDLE_CRC_PRESET(64, CRC64_ISO);
#endif /* #if RZ_HAVE_CRC64_EXTRA */
}
RZ_API void rz_hash_do_end(RzHash *ctx, ut64 flags) {
if_has_flag(RZ_HASH_MD4) {
rz_md4_fini(ctx->digest, &ctx->md4);
}
if_has_flag(RZ_HASH_MD5) {
rz_hash_do_md5(ctx, NULL, -2);
MD5_Final(ctx->digest, &ctx->md5);
}
if_has_flag(RZ_HASH_SHA1) {
rz_sha1_fini(ctx->digest, &ctx->sha1);

View file

@ -18,9 +18,10 @@ enum {
RZ_CRYPTO_MODE_CFB,
};
/* Defines in which direction the set_key methods needs to run */
enum {
RZ_CRYPTO_DIR_CIPHER,
RZ_CRYPTO_DIR_DECIPHER,
RZ_CRYPTO_DIR_ENCRYPT = 0,
RZ_CRYPTO_DIR_DECRYPT,
};
typedef struct rz_crypto_t {
@ -45,14 +46,13 @@ typedef struct rz_crypto_plugin_t {
bool (*update)(RzCrypto *cry, const ut8 *buf, int len);
bool (*final)(RzCrypto *cry, const ut8 *buf, int len);
bool (*use)(const char *algo);
int (*fini)(RzCrypto *cry);
bool (*init)(RzCrypto *cry);
bool (*fini)(RzCrypto *cry);
} RzCryptoPlugin;
typedef ut64 RzCryptoSelector;
#ifdef RZ_API
RZ_API RzCrypto *rz_crypto_init(RzCrypto *cry, int hard);
RZ_API RzCrypto *rz_crypto_as_new(RzCrypto *cry);
RZ_API int rz_crypto_add(RzCrypto *cry, RzCryptoPlugin *h);
RZ_API RzCrypto *rz_crypto_new(void);
RZ_API RzCrypto *rz_crypto_free(RzCrypto *cry);
@ -62,7 +62,7 @@ RZ_API bool rz_crypto_set_iv(RzCrypto *cry, const ut8 *iv, int ivlen);
RZ_API int rz_crypto_update(RzCrypto *cry, const ut8 *buf, int len);
RZ_API int rz_crypto_final(RzCrypto *cry, const ut8 *buf, int len);
RZ_API int rz_crypto_append(RzCrypto *cry, const ut8 *buf, int len);
RZ_API ut8 *rz_crypto_get_output(RzCrypto *cry, int *size);
RZ_API const ut8 *rz_crypto_get_output(RzCrypto *cry, int *size);
RZ_API const char *rz_crypto_name(const RzCryptoSelector bit);
RZ_API const char *rz_crypto_codec_name(const RzCryptoSelector bit);
#endif

View file

@ -197,9 +197,9 @@ struct rz_hash_t {
};
typedef struct rz_hash_seed_t {
int prefix;
bool as_prefix;
ut8 *buf;
int len;
size_t len;
} RzHashSeed;
#define RZ_HASH_SIZE_CRC8_SMBUS 1
@ -537,6 +537,7 @@ RZ_API int rz_hash_pcprint(const ut8 *buffer, ut64 len);
/* lifecycle */
RZ_API void rz_hash_do_begin(RzHash *ctx, ut64 flags);
RZ_API void rz_hash_do_update(RzHash *ctx, ut64 flags, const ut8 *data, ut64 len);
RZ_API void rz_hash_do_end(RzHash *ctx, ut64 flags);
RZ_API void rz_hash_do_spice(RzHash *ctx, ut64 algo, int loops, RzHashSeed *seed);
#endif

File diff suppressed because it is too large Load diff

View file

@ -65,37 +65,34 @@ ut8 *utf32toutf8(ut32 *input) {
return result;
}
ut32 *utf8toutf32(const ut8 *input) {
ut32 *utf8toutf32(const ut8 *input, int len) {
if (!input) {
eprintf("ERROR input is null\n");
return NULL;
}
int i = 0;
int j = 0;
int val = 0;
int len = strlen((const char *)input);
ut32 *result = calloc(strlen((const char *)input) + 1, 4);
ut32 *result = calloc(len + 1, 4);
if (!result) {
eprintf("ERROR: out of memory\n");
return NULL;
}
while (i < len) {
for (int i = 0, j = 0; i < len; j++) {
if (input[i] >> 7 == 0) {
val = input[i];
i += 1;
} else if (input[i] >> 5 == 0x6) {
} else if (input[i] >> 5 == 0x6 && (len - i) > 1) {
val = (((input[i] & 0x1f) << 6) & 0xfc0) |
(input[i + 1] & 0x3f);
i += 2;
} else if (input[i] >> 4 == 0xe) {
} else if (input[i] >> 4 == 0xe && (len - i) > 2) {
val = (((input[i] & 0xf) << 12) & 0xf000) |
(((input[i + 1] & 0x3f) << 6) & 0xffc0) |
(input[i + 2] & 0x3f);
i += 3;
} else if (input[i] >> 3 == 0x1e) {
} else if (input[i] >> 3 == 0x1e && (len - i) > 3) {
val = (((input[i] & 0xf) << 18) & 0x1c0000) |
(((input[i + 1] & 0x3f) << 12) & 0x1ff000) |
(((input[i + 2] & 0x3f) << 6) & 0x1fffc0) |
@ -107,7 +104,6 @@ ut32 *utf8toutf32(const ut8 *input) {
return NULL;
}
result[j] = val;
j++;
}
return result;
@ -192,7 +188,7 @@ RZ_API char *rz_punycode_encode(const ut8 *src, int srclen, int *dstlen) {
return NULL;
}
actualsrc = utf8toutf32(src);
actualsrc = utf8toutf32(src, srclen);
if (!actualsrc) {
return NULL;
}

View file

@ -193,13 +193,12 @@ static bool _encrypt(iobnet_t *obj, ut8 *buf, int size, int type) {
}
// Overwrite the buffer with encrypted data
int sz;
ut8 *encbuf = rz_crypto_get_output(cry, &sz);
const ut8 *encbuf = rz_crypto_get_output(cry, &sz);
if (!encbuf) {
goto end;
}
memcpy(buf, encbuf, size - KDNET_HMAC_SIZE);
free(encbuf);
ret = true;
end:
rz_crypto_free(cry);
@ -301,14 +300,13 @@ static bool _decrypt(iobnet_t *obj, ut8 *buf, int size, int type) {
}
// Overwrite it with decrypted data
int sz;
ut8 *decbuf = rz_crypto_get_output(cry, &sz);
const ut8 *decbuf = rz_crypto_get_output(cry, &sz);
if (!decbuf) {
goto end;
}
memcpy(buf, decbuf, size - KDNET_HMAC_SIZE);
ret = true;
free(decbuf);
end:
rz_crypto_free(cry);
return ret;

View file

@ -3,16 +3,16 @@ FILE=bins/elf/analysis/x86-helloworld-gcc
CMDS=<<EOF
e io.va=0
ph sha1 $s-32 @ 32
!rz-hash -a sha1 -f 32 -t 4898 bins/elf/analysis/x86-helloworld-gcc
!rz-hash -a sha1 -f 32 -t 4899 bins/elf/analysis/x86-helloworld-gcc
ph sha1 $s @0
!rz-hash -a sha1 bins/elf/analysis/x86-helloworld-gcc
ph sha1 @s:fofofofo
EOF
EXPECT=<<EOF
1fa8a7fd5c661af321d09f5951b35684f209f815
bins/elf/analysis/x86-helloworld-gcc: 0x00000020-0x00001322 sha1: 1fa8a7fd5c661af321d09f5951b35684f209f815
bins/elf/analysis/x86-helloworld-gcc: 0x00000020-0x00001323 sha1: 1fa8a7fd5c661af321d09f5951b35684f209f815
e218202875386cf4a0cd3ce22490fcd48db91491
bins/elf/analysis/x86-helloworld-gcc: 0x00000000-0x00001322 sha1: e218202875386cf4a0cd3ce22490fcd48db91491
bins/elf/analysis/x86-helloworld-gcc: 0x00000000-0x00001323 sha1: e218202875386cf4a0cd3ce22490fcd48db91491
b9a2dc76a3571526786cf651570df206a93f63fa
EOF
RUN

View file

@ -31,9 +31,9 @@ ph crc16 11
ph crc32 11
EOF
EXPECT=<<EOF
string: crc16: 39c1
39c1
39c1
0d4a1185
string: crc32: 0d4a1185
0d4a1185
EOF
RUN
@ -43,7 +43,7 @@ FILE==
CMDS=<<EOF
b 12
w hello world
!rz-hash -qa rz-hash -a crc8smbus,crc15can,crc16hdlc,crc16usb,crc16citt,crc24,crc32c,crc32ecma267 -s "hello world"
!rz-hash -qa crc8smbus,crc15can,crc16hdlc,crc16usb,crc16citt,crc24,crc32c,crc32ecma267 -s "hello world"
ph crc8smbus 11
ph crc15can 11
ph crc16hdlc 11
@ -54,14 +54,14 @@ ph crc32c 11
ph crc32ecma267 11
EOF
EXPECT=<<EOF
a8
727a
ae06
2238
efeb
b03cb7
c99465aa
ac86f845
string: crc8smbus: a8
string: crc15can: 727a
string: crc16hdlc: ae06
string: crc16usb: 2238
string: crc16citt: efeb
string: crc24: b03cb7
string: crc32c: c99465aa
string: crc32ecma267: ac86f845
a8
727a
ae06

File diff suppressed because it is too large Load diff