Add support for punycode via woE and woD and rahash2

Also add aes-cbc support by getting IV from user
This commit is contained in:
Rakholiya Jenish 2016-05-07 16:01:13 +05:30 committed by radare
parent 056f8a7efa
commit 3019bb477c
10 changed files with 324 additions and 10 deletions

View File

@ -291,7 +291,7 @@ int is_power_of_two(const ut64 x) {
//direction: 0 => encrypt, 1 => decrypt
int encrypt_or_decrypt(const char *algo, int direction, const char *hashstr, int hashstr_len, const ut8 *iv, int ivlen, int mode) {
bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo); //TODO: generalise this for all non key encoding/decoding.
bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo) || !strcmp ("punycode", algo); //TODO: generalise this for all non key encoding/decoding.
if (no_key_mode || s.len > 0) {
RCrypto *cry = r_crypto_new ();
if (r_crypto_use (cry, algo)) {
@ -328,7 +328,7 @@ int encrypt_or_decrypt(const char *algo, int direction, const char *hashstr, int
}
int encrypt_or_decrypt_file (const char *algo, int direction, char *filename, const ut8 *iv, int ivlen, int mode) {
bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo); //TODO: generalise this for all non key encoding/decoding.
bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo) || !strcmp ("punycode", algo); //TODO: generalise this for all non key encoding/decoding.
if (no_key_mode || s.len > 0) {
RCrypto *cry = r_crypto_new ();
if (r_crypto_use (cry, algo)) {

View File

@ -28,10 +28,10 @@ R_API int cmd_write_hexpair(RCore* core, const char* pairs) {
return !len;
}
static bool encrypt_or_decrypt_block(RCore *core, const char *algo, const char *key, int direction) {
static bool encrypt_or_decrypt_block(RCore *core, const char *algo, const char *key, int direction, const char *iv) {
//TODO: generalise no_key_mode for all non key encoding/decoding.
int keylen = key ? strlen (key): 0;
bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo);
bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo) || !strcmp ("punycode", algo);
if (no_key_mode || keylen > 0) {
RCrypto *cry = r_crypto_new ();
if (r_crypto_use (cry, algo)) {
@ -45,6 +45,19 @@ static bool encrypt_or_decrypt_block(RCore *core, const char *algo, const char *
keylen = len;
}
if (r_crypto_set_key (cry, binkey, keylen, 0, direction)) {
if (iv) {
ut8 *biniv = malloc (strlen (iv) + 1);
int ivlen = r_hex_str2bin (iv, biniv);
if (ivlen < 1) {
ivlen = strlen(iv);
strcpy ((char *)biniv, iv);
}
if (!r_crypto_set_iv (cry, biniv, ivlen)) {
eprintf ("Invalid IV.\n");
return 0;
}
}
r_crypto_update (cry, (const ut8*)core->block, core->blocksize);
r_crypto_final (cry, NULL, 0);
@ -109,9 +122,9 @@ static void cmd_write_op (RCore *core, const char *input) {
"woa"," [val]", "+= addition (f.ex: woa 0102)",
"woA"," [val]","&= and",
"wod"," [val]", "/= divide",
"woD","[algo] [key]","decrypt current block with given algo and key",
"woD","[algo] [key] [IV]","decrypt current block with given algo and key",
"woe"," [from to] [step] [wsz=1]",".. create sequence",
"woE"," [algo] [key]", "encrypt current block with given algo and key",
"woE"," [algo] [key] [IV]", "encrypt current block with given algo and key",
"wol"," [val]","<<= shift left",
"wom"," [val]", "*= multiply",
"woo"," [val]","|= or",
@ -168,17 +181,23 @@ static void cmd_write_op (RCore *core, const char *input) {
int direction = (input[1] == 'E') ? 0 : 1;
const char *algo = NULL;
const char *key = NULL;
const char *iv = NULL;
char *space, *args = strdup (r_str_chop_ro (input+2));
space = strchr (args, ' ');
if (space) {
*space++ = 0;
key = space;
space = strchr (key, ' ');
if (space) {
*space++ = 0;
iv = space;
}
}
algo = args;
if (algo && *algo) {
encrypt_or_decrypt_block (core, algo, key, direction);
encrypt_or_decrypt_block (core, algo, key, direction, iv);
} else {
eprintf ("Usage: wo%c [algo] [key]\n", ((!direction)?'E':'D'));
eprintf ("Usage: wo%c [algo] [key] [IV]\n", ((!direction)?'E':'D'));
eprintf ("TODO: list currently supported crypto algorithms\n");
eprintf (" rc2, rc4, xor, blowfish, aes, rot, ror, rol\n");
}

View File

@ -1,4 +1,4 @@
OBJS = crypto.c ;
OBJS += p/crypto_aes.c p/crypto_aes_algo.c p/crypto_xor.c p/crypto_blowfish.c p/crypto_rc2.c p/crypto_rot.c p/crypto_rol.c p/crypto_ror.c p/crypto_base64.c p/crypto_base91.c p/crypto_aes_cbc.c;
OBJS += p/crypto_aes.c p/crypto_aes_algo.c p/crypto_xor.c p/crypto_blowfish.c p/crypto_rc2.c p/crypto_rot.c p/crypto_rol.c p/crypto_ror.c p/crypto_base64.c p/crypto_base91.c p/crypto_aes_cbc.c p/crypto_punycode.c;
lib r_crypto : $(OBJS) : <include>../include <library>../util ;

View File

@ -0,0 +1,52 @@
#include <r_util.h>
#include <r_lib.h>
#include <r_crypto.h>
static int flag = 0;
static int punycode_set_key(RCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
flag = direction;
return true;
}
static int punycode_get_key_size(RCrypto *cry) {
return 0;
}
static bool punycode_use(const char *algo) {
return !strcmp (algo, "punycode");
}
static int update(RCrypto *cry, const ut8 *buf, int len) {
char *obuf;
int olen;
if (flag) {
obuf = r_punycode_decode ((const char *)buf, len, &olen);
} else {
obuf = r_punycode_encode ((const char *)buf, len, &olen);
}
r_crypto_append (cry, (ut8*)obuf, olen);
free (obuf);
return 0;
}
static int final(RCrypto *cry, const ut8* buf, int len) {
return update (cry, buf, len);
}
RCryptoPlugin r_crypto_plugin_punycode = {
.name = "punycode",
.set_key = punycode_set_key,
.get_key_size = punycode_get_key_size,
.use = punycode_use,
.update = update,
.final = final
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_CRYPTO,
.data = &r_crypto_plugin_punycode,
.version = R2_VERSION
}
#endif

View File

@ -0,0 +1,9 @@
OBJ_PUNY=crypto_punycode.o
STATIC_OBJ+=${OBJ_PUNY}
TARGET_PUNY=crypto_punycode.${EXT_SO}
ALL_TARGETS+=${TARGET_PUNY}
${TARGET_PUNY}: ${OBJ_PUNY}
${CC} $(call libname,crypto_punycode) ${LDFLAGS} ${CFLAGS} -o ${TARGET_PUNY} ${OBJ_PUNY}

View File

@ -72,6 +72,7 @@ extern RCryptoPlugin r_crypto_plugin_ror;
extern RCryptoPlugin r_crypto_plugin_base64;
extern RCryptoPlugin r_crypto_plugin_base91;
extern RCryptoPlugin r_crypto_plugin_aes_cbc;
extern RCryptoPlugin r_crypto_plugin_punycode;
#ifdef __cplusplus
}

View File

@ -483,6 +483,9 @@ R_API char *r_base64_encode_dyn(const char *str, int len);
R_API int r_base91_encode(char *bout, const ut8 *bin, int len);
R_API int r_base91_decode(ut8 *bout, const char *bin, int len);
R_API char *r_punycode_encode(const char*src, int srclen, int *dstlen);
R_API char *r_punycode_decode(const char *src, int srclen, int *dstlen);
/* strings */
static inline void r_str_rmch (char *s, char ch) {
for (;*s; s++) {

View File

@ -12,7 +12,7 @@ OBJS+=strpool.o bitmap.o strht.o p_date.o p_format.o print.o
OBJS+=p_seven.o slist.o randomart.o log.o zip.o debruijn.o
OBJS+=utf8.o strbuf.o lib.o name.o spaces.o
OBJS+=diff.o bdiff.o stack.o queue.o tree.o des.o
OBJS+=swap.o
OBJS+=swap.o punycode.o
# DO NOT BUILD r_big api (not yet used and its buggy)
ifeq (1,0)

229
libr/util/punycode.c Normal file
View File

@ -0,0 +1,229 @@
#include <assert.h>
#include <r_types.h>
#include <r_util.h>
#define BASE 36
#define TMIN 1
#define TMAX 26
#define SKEW 38
#define DAMP 700
#define INITIAL_N 128
#define INITIAL_BIAS 72
ut32 adapt_bias(ut32 delta, unsigned n_points, int is_first) {
ut32 k;
delta /= is_first ? DAMP : 2;
delta += delta / n_points;
for (k = 0; k > ((BASE - TMIN) * TMAX) / 2; k += BASE) {
delta /= (BASE - TMIN);
}
return k + (((BASE - TMIN + 1) * delta) / (delta + SKEW));
}
char encode_digit(int c) {
assert (c >= 0 && c <= BASE - TMIN);
if (c > 25) {
return c + 22;
}
return c + 'a';
}
static ut32 encode_var_int(const ut32 bias, const ut32 delta, char *dst) {
ut32 i, k, q, t;
i = 0;
k = BASE;
q = delta;
while (true) {
if (k <= bias) {
t = TMIN;
} else if (k >= bias + TMAX) {
t = TMAX;
} else {
t = k - bias;
}
if (q < t) {
break;
}
dst[i++] = encode_digit (t + (q - t) % (BASE - t));
q = (q - t) / (BASE - t);
k += BASE;
}
dst[i++] = encode_digit (q);
return i;
}
static char decode_digit(char v) {
if (v >= '0' && v <= '9') {
return v - 22;
}
if (v >= 'a' && v <= 'z') {
return v - 'a';
}
if (v >= 'A' && v <= 'Z') {
return v - 'A';
}
return -1;
}
R_API char *r_punycode_encode(const char *src, int srclen, int *dstlen) {
ut8 m, n;
ut32 b, h;
ut32 si, di;
ut32 delta, bias;
char *dst;
*dstlen = 0;
if (!src || srclen < 1) {
return NULL;
}
dst = calloc (2*srclen+10, 1);
if (!dst) {
return NULL;
}
for (si = 0, di = 0; si < srclen; si++) {
if ((ut8)src[si] < 128) {
dst[di++] = src[si];
}
}
b = h = di;
if (di > 0) {
dst[di++] = '-';
}
n = INITIAL_N;
bias = INITIAL_BIAS;
for (delta = 0; h < srclen; n++, delta++) {
for (m = 0xff, si = 0; si < srclen; si++) {
if ((ut8)src[si] >= n && (ut8)src[si] <= m) {
m = src[si];
}
}
if ((unsigned int)(m - n) > (UT32_MAX - delta) / (h + 1)) {
return NULL;
}
delta += (m - n) * (h + 1);
n = m;
for (si = 0; si < srclen; si++) {
if ((ut8)src[si] < n) {
if (++delta == 0) {
return NULL;
}
} else if ((ut8)src[si] == n) {
di += encode_var_int (bias, delta, &dst[di]);
bias = adapt_bias (delta, h+1, h == b);
delta = 0;
h++;
}
}
}
*dstlen = di;
return dst;
}
R_API char *r_punycode_decode(const char *src, int srclen, int *dstlen) {
ut8 n;
const char *p;
ut32 si, di;
ut32 b, t, i, k, w;
ut32 digit, org_i, bias;
char *dst;
*dstlen = 0;
if (!src || srclen < 1) {
return NULL;
}
dst = calloc (2*srclen + 10, 1);
if (!dst) {
return NULL;
}
for (si = 0; si < srclen; si++) {
if (src[si] & 0x80) {
return NULL; /*just return it*/
}
}
for (p = src + srclen - 1; p > src && *p != '-'; p--);
b = p - src;
di = b;
for (i = 0; i < di; i++) {
dst[i] = src[i];
}
i = 0;
n = INITIAL_N;
bias = INITIAL_BIAS;
for (si = b + (b > 0); si < srclen; di++) {
org_i = i;
for (w = 1, k = BASE; ; k += BASE) {
digit = decode_digit (src[si++]);
if ((char)digit == -1) {
free (dst);
return NULL;
}
if (digit > (UT32_MAX - i) / w) {
free (dst);
return NULL;
}
i += digit * w;
if (k <= bias) {
t = TMIN;
} else if (k >= bias + TMAX) {
t = TMAX;
} else {
t = k - bias;
}
if (digit < t) {
break;
}
if (w > UT32_MAX / (BASE - t)) {
free (dst);
return NULL;
}
w *= BASE- t;
}
bias = adapt_bias(i - org_i, di+1, org_i == 0);
if (i / (di + 1) > UT32_MAX - n) {
free (dst);
return NULL;
}
n += i / (di + 1);
i %= (di + 1);
memmove (dst+i+1, dst+i, (di-i) * sizeof(char));
dst[i++] = n;
}
*dstlen = di;
return dst;
}

View File

@ -159,6 +159,7 @@ crypto.ror
crypto.base64
crypto.base91
crypto.aes_cbc
crypto.punycode
debug.bf
debug.esil
debug.gdb