diff --git a/binr/rahash2/rahash2.c b/binr/rahash2/rahash2.c index 51a48fc09e..4427757698 100644 --- a/binr/rahash2/rahash2.c +++ b/binr/rahash2/rahash2.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "../blob/version.c" static ut64 from = 0LL; @@ -230,7 +231,7 @@ static int do_hash(const char *file, const char *algo, RIO *io, int bsize, int r } static int do_help(int line) { - printf ("Usage: rahash2 [-rBhLkv] [-b S] [-a A] [-c H] [-s S] [-f O] [-t O] [file] ...\n"); + printf ("Usage: rahash2 [-rBhLkv] [-b S] [-a A] [-c H] [-E A] [-s S] [-f O] [-t O] [file] ...\n"); if (line) return 0; printf ( " -a algo comma separated list of algorithms (default is 'sha256')\n" @@ -238,10 +239,11 @@ static int do_help(int line) { " -B show per-block hash\n" " -c hash compare with this hash\n" " -e swap endian (use little endian)\n" + " -E algo encrypt (rc4 for now). Use -S to set key\n" " -d / -D encode/decode base64 string (-s) or file to stdout\n" " -f from start hashing at given address\n" " -i num repeat hash N iterations\n" - " -S seed use given seed (hexa or s:string) use ^ to prefix\n" + " -S seed use given seed (hexa or s:string) use ^ to prefix (key for -E)\n" " -k show hash using the openssh's randomkey algorithm\n" " -q run in quiet mode (only show results)\n" " -L list all available algorithms (see -a)\n" @@ -281,6 +283,7 @@ int main(int argc, char **argv) { int i, ret, c, rad = 0, bsize = 0, numblocks = 0, ule = 0, b64mode = 0; const char *algo = "sha256"; /* default hashing algorithm */ const char *seed = NULL; + const char *encrypt = NULL; char *hashstr = NULL; const char *compareStr = NULL; ut8 *compareBin = NULL; @@ -290,7 +293,7 @@ int main(int argc, char **argv) { RHash *ctx; RIO *io; - while ((c = getopt (argc, argv, "jdDrvea:i:S:s:x:b:nBhf:t:kLqc:")) != -1) { + while ((c = getopt (argc, argv, "jdDrveE:a:i:S:s:x:b:nBhf:t:kLqc:")) != -1) { switch (c) { case 'q': quiet = 1; break; case 'i': @@ -305,6 +308,7 @@ int main(int argc, char **argv) { case 'n': numblocks = 1; break; case 'd': b64mode = 1; break; case 'D': b64mode = 2; break; + case 'E': encrypt = optarg; break; case 'L': algolist (); return 0; case 'e': ule = 1; break; case 'r': rad = 1; break; @@ -410,6 +414,53 @@ int main(int argc, char **argv) { hashstr_len = to - from; hashstr[hashstr_len] = '\0'; hashstr_len = r_str_unescape (hashstr); + if (encrypt) { + int seedlen = seed? strlen (seed): 0; + if (seedlen > 0) { + RCrypto *cry = r_crypto_new (); + if (r_crypto_use (cry, encrypt)) { + ut8 *binseed = malloc (seedlen + 1); + if (binseed) { + int len = r_hex_str2bin (seed, binseed); + if (len <1) { + len = seedlen; + strcpy ((char *)binseed, seed); + } else { + seedlen = len; + } + if (r_crypto_set_key (cry, binseed, seedlen, 0, 0)) { + if (hashstr) { + const char *buf = hashstr; + int buflen = hashstr_len; + + r_crypto_update (cry, (const ut8*)buf, buflen); + r_crypto_final (cry, NULL, 0); + + int result_size = 0; + ut8 *result = r_crypto_get_output (cry, &result_size); + if (result) { + write (1, result, result_size); + free (result); + } + } + } else { + eprintf ("Invalid key\n"); + } + + free (binseed); + return 0; + } else { + eprintf ("Cannot allocate %d bytes\n", seedlen); + } + } else { + eprintf ("Unknown encryption algorithm '%s'\n", encrypt); + } + r_crypto_free (cry); + } else { + eprintf ("Encryption key not defined. Use -S [key]\n"); + } + return 1; + } else switch (b64mode) { case 1: // encode { diff --git a/libr/crypto/crypto.c b/libr/crypto/crypto.c index 2541e05edf..ee6bdd1c94 100644 --- a/libr/crypto/crypto.c +++ b/libr/crypto/crypto.c @@ -49,7 +49,7 @@ R_API struct r_crypto_t *r_crypto_new() { R_API struct r_crypto_t *r_crypto_as_new(struct r_crypto_t *cry) { RCrypto *c = R_NEW0 (RCrypto); - if (c != NULL) { + if (c) { r_crypto_init (c, false); // soft init memcpy (&c->plugins, &cry->plugins, sizeof (cry->plugins)); } @@ -70,7 +70,7 @@ R_API bool r_crypto_use(RCrypto *cry, const char *algo) { RListIter *iter; RCryptoPlugin *h; r_list_foreach (cry->plugins, iter, h) { - if (h->use (algo)) { + if (h && h->use && h->use (algo)) { cry->h = h; cry->key_len = h->get_key_size (cry); cry->key = calloc (1, cry->key_len); @@ -98,12 +98,12 @@ R_API int r_crypto_set_iv(RCrypto *cry, const ut8 *iv) { } // return the number of bytes written in the output buffer -R_API int r_crypto_update(RCrypto *cry, ut8 *buf, int len) { +R_API int r_crypto_update(RCrypto *cry, const ut8 *buf, int len) { return (cry && cry->h && cry->h->update)? cry->h->update (cry, buf, len): 0; } -R_API int r_crypto_final(RCrypto *cry, ut8 *buf, int len) { +R_API int r_crypto_final(RCrypto *cry, const ut8 *buf, int len) { return (cry && cry->h && cry->h->final)? cry->h->final (cry, buf, len): 0; } diff --git a/libr/crypto/p/crypto_rc4.c b/libr/crypto/p/crypto_rc4.c index 86ef668f9e..22ac84bc17 100644 --- a/libr/crypto/p/crypto_rc4.c +++ b/libr/crypto/p/crypto_rc4.c @@ -24,10 +24,13 @@ static __inline void swap_bytes(ut8 *a, ut8 *b) { * which can have arbitrary length. */ -static void rc4_init(struct rc4_state *const state, const ut8 *key, int keylen) { +static bool rc4_init(struct rc4_state *const state, const ut8 *key, int keylen) { ut8 j; int i; + if (!state || !key || keylen < 1) { + return false; + } state->key_size = keylen; /* Initialize state with identity permutation */ for (i = 0; i < 256; i++) @@ -40,6 +43,7 @@ static void rc4_init(struct rc4_state *const state, const ut8 *key, int keylen) j += state->perm[i] + key[i % keylen]; swap_bytes (&state->perm[i], &state->perm[j]); } + return true; } /* @@ -70,8 +74,7 @@ static void rc4_crypt(struct rc4_state *const state, const ut8 *inbuf, ut8 *outb static struct rc4_state st; static int rc4_set_key(RCrypto *cry, const ut8 *key, int keylen, int mode, int direction) { - rc4_init (&st, key, keylen); - return true; + return rc4_init (&st, key, keylen); } static int rc4_get_key_size(RCrypto *cry) { diff --git a/libr/include/r_crypto.h b/libr/include/r_crypto.h index b4d7de1150..384f73d425 100644 --- a/libr/include/r_crypto.h +++ b/libr/include/r_crypto.h @@ -54,8 +54,8 @@ R_API RCrypto *r_crypto_free(RCrypto *cry); R_API bool r_crypto_use(RCrypto *cry, const char *algo); R_API int r_crypto_set_key(RCrypto *cry, const ut8* key, int keylen, int mode, int direction); R_API int r_crypto_set_iv(RCrypto *cry, const ut8 *iv); -R_API int r_crypto_update(RCrypto *cry, ut8 *buf, int len); -R_API int r_crypto_final(RCrypto *cry, ut8 *buf, int len); +R_API int r_crypto_update(RCrypto *cry, const ut8 *buf, int len); +R_API int r_crypto_final(RCrypto *cry, const ut8 *buf, int len); R_API int r_crypto_append(RCrypto *cry, const ut8 *buf, int len); R_API ut8 *r_crypto_get_output(RCrypto *cry, int *size); #endif diff --git a/man/rahash2.1 b/man/rahash2.1 index 4098ce3b6b..fa93e31aed 100644 --- a/man/rahash2.1 +++ b/man/rahash2.1 @@ -8,6 +8,7 @@ .Op Fl BdDehjrkv .Op Fl a Ar algorithm .Op Fl b Ar size +.Op Fl E Ar algo .Op Fl s Ar string .Op Fl i Ar iterations .Op Fl S Ar seed @@ -39,6 +40,8 @@ encoDe base64 string or file Decode base64 string or file .It Fl e Use little endian to display checksums +.It Fl E Ar algo +Encrypt instead of hash using the given algorithm (rc4, aes) .It Fl i Ar iters Apply the hash Iters times to itself+seed .It Fl j