Rizin
unix-like reverse engineering framework and cli tools
crypto_rc4.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_lib.h>
5 #include <rz_crypto.h>
6 #include <rz_util.h>
7 
8 struct rc4_state {
9  ut8 perm[256];
12  int key_size;
13 };
14 
15 static __inline void swap_bytes(ut8 *a, ut8 *b) {
16  if (a != b) {
17  ut8 temp = *a;
18  *a = *b;
19  *b = temp;
20  }
21 }
22 
23 /*
24  * Initialize an RC4 state buffer using the supplied key,
25  * which can have arbitrary length.
26  */
27 
28 static bool rc4_init_state(struct rc4_state *const state, const ut8 *key, int keylen) {
29  ut8 j;
30  int i;
31 
32  if (!state || !key || keylen < 1) {
33  return false;
34  }
35  state->key_size = keylen;
36  /* Initialize state with identity permutation */
37  for (i = 0; i < 256; i++) {
38  state->perm[i] = (ut8)i;
39  }
40  state->index1 = 0;
41  state->index2 = 0;
42 
43  /* Randomize the permutation using key data */
44  for (j = i = 0; i < 256; i++) {
45  j += state->perm[i] + key[i % keylen];
46  swap_bytes(&state->perm[i], &state->perm[j]);
47  }
48  return true;
49 }
50 
51 /*
52  * Encrypt some data using the supplied RC4 state buffer.
53  * The input and output buffers may be the same buffer.
54  * Since RC4 is a stream cypher, this function is used
55  * for both encryption and decryption.
56  */
57 static void rc4_crypt(struct rc4_state *const state, const ut8 *inbuf, ut8 *outbuf, int buflen) {
58  int i;
59  ut8 j;
60 
61  for (i = 0; i < buflen; i++) {
62  /* Update modification indices */
63  state->index1++;
64  state->index2 += state->perm[state->index1];
65  /* Modify permutation */
66  swap_bytes(&state->perm[state->index1],
67  &state->perm[state->index2]);
68  /* Encrypt/decrypt next byte */
69  j = state->perm[state->index1] + state->perm[state->index2];
70  outbuf[i] = inbuf[i] ^ state->perm[j];
71  }
72 }
73 
75 
76 static bool rc4_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
77  rz_return_val_if_fail(cry->user && key, false);
78  struct rc4_state *st = (struct rc4_state *)cry->user;
79 
80  return rc4_init_state(st, key, keylen);
81 }
82 
83 static int rc4_get_key_size(RzCrypto *cry) {
84  rz_return_val_if_fail(cry->user, 0);
85  struct rc4_state *st = (struct rc4_state *)cry->user;
86 
87  return st->key_size;
88 }
89 
90 static bool rc4_use(const char *algo) {
91  return !strcmp(algo, "rc4");
92 }
93 
94 static bool update(RzCrypto *cry, const ut8 *buf, int len) {
95  rz_return_val_if_fail(cry->user, false);
96  struct rc4_state *st = (struct rc4_state *)cry->user;
97 
98  ut8 *obuf = calloc(1, len);
99  if (!obuf) {
100  return false;
101  }
102  rc4_crypt(st, buf, obuf, len);
103  rz_crypto_append(cry, obuf, len);
104  free(obuf);
105  return false;
106 }
107 
108 static bool final(RzCrypto *cry, const ut8 *buf, int len) {
109  return update(cry, buf, len);
110 }
111 
112 static bool rc4_init(RzCrypto *cry) {
113  rz_return_val_if_fail(cry, false);
114 
115  cry->user = RZ_NEW0(struct rc4_state);
116  return cry->user != NULL;
117 }
118 
119 static bool rc4_fini(RzCrypto *cry) {
120  rz_return_val_if_fail(cry, false);
121 
122  free(cry->user);
123  return true;
124 }
125 
127  .name = "rc4",
128  .author = "pancake",
129  .license = "LGPL-3",
130  .set_key = rc4_set_key,
131  .get_key_size = rc4_get_key_size,
132  .use = rc4_use,
133  .update = update,
134  .final = final,
135  .init = rc4_init,
136  .fini = rc4_fini,
137 };
138 
139 #ifndef RZ_PLUGIN_INCORE
142  .data = &rz_crypto_plugin_rc4,
143  .version = RZ_VERSION
144 };
145 #endif
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API int rz_crypto_append(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto.c:175
static void rc4_crypt(struct rc4_state *const state, const ut8 *inbuf, ut8 *outbuf, int buflen)
Definition: crypto_rc4.c:57
static bool rc4_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction)
Definition: crypto_rc4.c:76
static bool update(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto_rc4.c:94
static int rc4_get_key_size(RzCrypto *cry)
Definition: crypto_rc4.c:83
RZ_API RzLibStruct rizin_plugin
Definition: crypto_rc4.c:140
static bool rc4_use(const char *algo)
Definition: crypto_rc4.c:90
static __inline void swap_bytes(ut8 *a, ut8 *b)
Definition: crypto_rc4.c:15
static bool rc4_fini(RzCrypto *cry)
Definition: crypto_rc4.c:119
static bool rc4_init_state(struct rc4_state *const state, const ut8 *key, int keylen)
Definition: crypto_rc4.c:28
RzCryptoPlugin rz_crypto_plugin_rc4
Definition: crypto_rc4.c:126
static bool rc4_init(RzCrypto *cry)
Definition: crypto_rc4.c:112
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
#define ut8
Definition: dcpu16.h:8
unsigned char outbuf[SIZE]
Definition: gun.c:162
unsigned char inbuf[SIZE]
Definition: gun.c:161
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_LIB_TYPE_CRYPTO
Definition: rz_lib.h:81
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_VERSION
Definition: rz_version.h:8
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
int key_size
Definition: crypto_rc4.c:12
ut8 index2
Definition: crypto_rc4.c:11
ut8 perm[256]
Definition: crypto_rc4.c:9
ut8 index1
Definition: crypto_rc4.c:10
const char * name
Definition: rz_crypto.h:41
void * user
Definition: rz_crypto.h:36
Definition: dis.h:43
ut64 buflen
Definition: core.c:76
static unsigned char * obuf
Definition: z80asm.c:36