Rizin
unix-like reverse engineering framework and cli tools
crypto_rc6.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016 rakholiyajenish.07 <rakholiyajenish.07@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 // Implemented AES version of RC6. keylen = 16, 23, or 32 bytes; w = 32; and r = 20.
5 #include <rz_lib.h>
6 #include <rz_crypto.h>
7 #include <rz_util.h>
8 
9 #define Pw 0xb7e15163
10 #define Qw 0x9e3779b9
11 #define BLOCK_SIZE 16
12 #define r 20
13 #define w 32
14 #define ROTL(x, y) (((x) << ((y) & (w - 1))) | ((x) >> (w - ((y) & (w - 1)))))
15 #define ROTR(x, y) (((x) >> ((y) & (w - 1))) | ((x) << (w - ((y) & (w - 1)))))
16 
17 struct rc6_state {
18  ut32 S[2 * r + 4];
19  int key_size;
20 };
21 
22 static bool rc6_init_state(struct rc6_state *const state, const ut8 *key, int keylen) {
23  if (keylen != 128 / 8 && keylen != 192 / 8 && keylen != 256 / 8) {
24  return false;
25  }
26 
27  int u = w / 8;
28  int c = keylen / u;
29  int t = 2 * r + 4;
30 
31  ut32 *L = RZ_NEWS(ut32, c);
32  if (!L) {
34  return false;
35  }
36 
37  ut32 A = 0, B = 0, k = 0, j = 0;
38  ut32 v = 3 * t; // originally v = 2 * ((c > t) ? c : t);
39 
40  int i;
41 
42  for (i = 0; i < c; i++) {
43  L[i] = rz_read_at_le32(key, i * 4);
44  }
45 
46  (state->S)[0] = Pw;
47  for (i = 1; i < t; i++) {
48  (state->S)[i] = (state->S)[i - 1] + Qw;
49  }
50 
51  for (i = 0; i < v; i++) {
52  A = (state->S)[k] = ROTL(((state->S)[k] + A + B), 3);
53  B = L[j] = ROTL((L[j] + A + B), (A + B));
54  k = (k + 1) % t;
55  j = (j + 1) % c;
56  }
57 
58  state->key_size = keylen / 8;
59 
60  free(L);
61  return true;
62 }
63 
64 static void rc6_encrypt(struct rc6_state *const state, const ut8 *inbuf, ut8 *outbuf) {
65  ut32 t, u;
66  ut32 aux;
67  ut32 data[BLOCK_SIZE / 4];
68  int i;
69  for (i = 0; i < BLOCK_SIZE / 4; i++) {
70  data[i] = rz_read_at_le32(inbuf, i * 4);
71  }
72 
73  ut32 A = data[0], B = data[1], C = data[2], D = data[3];
74 
75  // S is key
76  B = B + (state->S)[0];
77  D = D + (state->S)[1];
78 
79  for (i = 1; i <= r; i++) {
80  t = ROTL(B * (2 * B + 1), 5); // lgw == 5
81  u = ROTL(D * (2 * D + 1), 5);
82  A = ROTL(A ^ t, u) + (state->S)[2 * i];
83  C = ROTL(C ^ u, t) + (state->S)[2 * i + 1];
84 
85  aux = A;
86  A = B;
87  B = C;
88  C = D;
89  D = aux;
90  }
91 
92  A = A + (state->S)[2 * (r + 1)];
93  C = C + (state->S)[2 * (r + 1) + 1];
94  data[0] = A;
95  data[1] = B;
96  data[2] = C;
97  data[3] = D;
98 
99  for (i = 0; i < BLOCK_SIZE; i++) {
100  outbuf[i] = (ut8)((data[i / 4] >> (i % 4) * 8) & 0xff);
101  }
102 }
103 
104 static void rc6_decrypt(struct rc6_state *const state, const ut8 *inbuf, ut8 *outbuf) {
105  ut32 t, u;
106  ut32 aux;
107  ut32 data[BLOCK_SIZE / 4];
108  int i;
109  int off = 0;
110 
111  for (i = 0; i < BLOCK_SIZE / 4; i++) {
112  data[i] = (inbuf[off++] & 0xff);
113  data[i] |= ((inbuf[off++] & 0xff) << 8);
114  data[i] |= ((inbuf[off++] & 0xff) << 16);
115  data[i] |= ((inbuf[off++] & 0xff) << 24);
116  }
117 
118  ut32 A = data[0], B = data[1], C = data[2], D = data[3];
119 
120  C = C - (state->S)[2 * (r + 1) + 1];
121  A = A - (state->S)[2 * (r + 1)];
122 
123  for (i = r; i >= 1; i--) {
124  aux = D;
125  D = C;
126  C = B;
127  B = A;
128  A = aux;
129 
130  u = ROTL(D * (2 * D + 1), 5);
131  t = ROTL(B * (2 * B + 1), 5);
132  C = ROTR(C - (state->S)[2 * i + 1], t) ^ u;
133  A = ROTR(A - (state->S)[2 * i], u) ^ t;
134  }
135 
136  D = D - (state->S)[1];
137  B = B - (state->S)[0];
138 
139  data[0] = A;
140  data[1] = B;
141  data[2] = C;
142  data[3] = D;
143 
144  for (i = 0; i < BLOCK_SIZE; i++) {
145  outbuf[i] = (ut8)((data[i / 4] >> (i % 4) * 8) & 0xff);
146  }
147 }
148 
149 static bool rc6_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
150  rz_return_val_if_fail(cry->user && key, false);
151  struct rc6_state *st = (struct rc6_state *)cry->user;
152 
153  cry->dir = direction;
154 
155  return rc6_init_state(st, key, keylen);
156 }
157 
158 static int rc6_get_key_size(RzCrypto *cry) {
159  rz_return_val_if_fail(cry->user, 0);
160  struct rc6_state *st = (struct rc6_state *)cry->user;
161 
162  return st->key_size;
163 }
164 
165 static bool rc6_use(const char *algo) {
166  return !strcmp(algo, "rc6");
167 }
168 
169 static bool update(RzCrypto *cry, const ut8 *buf, int len) {
170  rz_return_val_if_fail(cry->user, false);
171  struct rc6_state *st = (struct rc6_state *)cry->user;
172 
173  if (len % BLOCK_SIZE != 0) { // let user handle with with pad.
174  eprintf("Input should be multiple of 128bit.\n");
175  return false;
176  }
177 
178  const int blocks = len / BLOCK_SIZE;
179 
180  ut8 *obuf = calloc(1, len);
181  if (!obuf) {
182  return false;
183  }
184 
185  int i;
186  if (cry->dir == RZ_CRYPTO_DIR_DECRYPT) {
187  for (i = 0; i < blocks; i++) {
188  rc6_decrypt(st, buf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
189  }
190  } else {
191  for (i = 0; i < blocks; i++) {
192  rc6_encrypt(st, buf + BLOCK_SIZE * i, obuf + BLOCK_SIZE * i);
193  }
194  }
195 
196  rz_crypto_append(cry, obuf, len);
197  free(obuf);
198  return true;
199 }
200 
201 static bool final(RzCrypto *cry, const ut8 *buf, int len) {
202  return update(cry, buf, len);
203 }
204 
205 static bool rc6_init(RzCrypto *cry) {
206  rz_return_val_if_fail(cry, false);
207 
208  cry->user = RZ_NEW0(struct rc6_state);
209  return cry->user != NULL;
210 }
211 
212 static bool rc6_fini(RzCrypto *cry) {
213  rz_return_val_if_fail(cry, false);
214 
215  free(cry->user);
216  return true;
217 }
218 
220  .name = "rc6",
221  .author = "rakholiyajenish.07",
222  .license = "LGPL-3",
223  .set_key = rc6_set_key,
224  .get_key_size = rc6_get_key_size,
225  .use = rc6_use,
226  .update = update,
227  .final = final,
228  .init = rc6_init,
229  .fini = rc6_fini,
230 };
231 
232 #ifndef RZ_PLUGIN_INCORE
235  .data = &rz_crypto_plugin_rc6,
236  .version = RZ_VERSION
237 };
238 #endif
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define A(x)
Definition: arc.h:165
#define B(x)
Definition: arc.h:166
#define C(x)
Definition: arc.h:167
#define D
Definition: block.c:38
#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 bool rc6_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction)
Definition: crypto_rc6.c:149
static void rc6_decrypt(struct rc6_state *const state, const ut8 *inbuf, ut8 *outbuf)
Definition: crypto_rc6.c:104
#define ROTL(x, y)
Definition: crypto_rc6.c:14
static bool rc6_fini(RzCrypto *cry)
Definition: crypto_rc6.c:212
static bool update(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto_rc6.c:169
#define r
Definition: crypto_rc6.c:12
static void rc6_encrypt(struct rc6_state *const state, const ut8 *inbuf, ut8 *outbuf)
Definition: crypto_rc6.c:64
#define w
Definition: crypto_rc6.c:13
#define ROTR(x, y)
Definition: crypto_rc6.c:15
RZ_API RzLibStruct rizin_plugin
Definition: crypto_rc6.c:233
static bool rc6_use(const char *algo)
Definition: crypto_rc6.c:165
RzCryptoPlugin rz_crypto_plugin_rc6
Definition: crypto_rc6.c:219
static bool rc6_init(RzCrypto *cry)
Definition: crypto_rc6.c:205
#define Pw
Definition: crypto_rc6.c:9
static bool rc6_init_state(struct rc6_state *const state, const ut8 *key, int keylen)
Definition: crypto_rc6.c:22
#define Qw
Definition: crypto_rc6.c:10
static int rc6_get_key_size(RzCrypto *cry)
Definition: crypto_rc6.c:158
#define BLOCK_SIZE
Definition: crypto_rc6.c:11
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
uint32_t ut32
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
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
int off
Definition: pal.c:13
#define eprintf(x, y...)
Definition: rlcc.c:7
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_CRYPTO_DIR_DECRYPT
Definition: rz_crypto.h:24
static ut32 rz_read_at_le32(const void *src, size_t offset)
Definition: rz_endian.h:248
@ RZ_LIB_TYPE_CRYPTO
Definition: rz_lib.h:81
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_VERSION
Definition: rz_version.h:8
#define c(i)
Definition: sha256.c:43
ut32 S[2 *r+4]
Definition: crypto_rc6.c:18
int key_size
Definition: crypto_rc6.c:19
const char * name
Definition: rz_crypto.h:41
void * user
Definition: rz_crypto.h:36
Definition: dis.h:43
uint64_t blocks
Definition: list.c:104
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
static unsigned char * obuf
Definition: z80asm.c:36
#define L
Definition: zip_err_str.c:7