Rizin
unix-like reverse engineering framework and cli tools
crypto_des.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017 deroad <wargio@libero.it>
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 des_state {
9  ut32 keylo[16]; // round key low
10  ut32 keyhi[16]; // round key hi
11  ut32 buflo; // buf low
12  ut32 bufhi; // buf hi
13  int key_size;
14  int rounds;
15  int i;
16 };
17 
18 static ut32 be32(const ut8 *buf4) {
19  ut32 val = buf4[0] << 8;
20  val |= buf4[1];
21  val <<= 8;
22  val |= buf4[2];
23  val <<= 8;
24  val |= buf4[3];
25  return val;
26 }
27 
28 static void wbe32(ut8 *buf4, ut32 val) {
29  buf4[0] = (val >> 24);
30  buf4[1] = (val >> 16) & 0xFF;
31  buf4[2] = (val >> 8) & 0xFF;
32  buf4[3] = val & 0xFF;
33 }
34 
35 static int des_encrypt(struct des_state *st, const ut8 *input, ut8 *output) {
36  if (!st || !input || !output) {
37  return false;
38  }
39  st->buflo = be32(input + 0);
40  st->bufhi = be32(input + 4);
41 
42  // first permutation
43  rz_des_permute_block0(&st->buflo, &st->bufhi);
44 
45  for (st->i = 0; st->i < 16; st->i++) {
46  rz_des_round(&st->buflo, &st->bufhi, &st->keylo[st->i], &st->keyhi[st->i]);
47  }
48  // last permutation
49  rz_des_permute_block1(&st->bufhi, &st->buflo);
50 
51  // result
52  wbe32(output + 0, st->bufhi);
53  wbe32(output + 4, st->buflo);
54 
55  return true;
56 }
57 
58 static int des_decrypt(struct des_state *st, const ut8 *input, ut8 *output) {
59  if (!st || !input || !output) {
60  return false;
61  }
62  st->buflo = be32(input + 0);
63  st->bufhi = be32(input + 4);
64  // first permutation
65  rz_des_permute_block0(&st->buflo, &st->bufhi);
66 
67  for (st->i = 0; st->i < 16; st->i++) {
68  rz_des_round(&st->buflo, &st->bufhi, &st->keylo[15 - st->i], &st->keyhi[15 - st->i]);
69  }
70 
71  // last permutation
72  rz_des_permute_block1(&st->bufhi, &st->buflo);
73  // result
74  wbe32(output + 0, st->bufhi);
75  wbe32(output + 4, st->buflo);
76  return true;
77 }
78 
79 static bool des_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
80  rz_return_val_if_fail(cry->user && key, 0);
81  struct des_state *st = (struct des_state *)cry->user;
82 
83  ut32 keylo, keyhi, i;
84  if (keylen != DES_KEY_SIZE) {
85  return false;
86  }
87  // splitting the key in hi & lo
88  keylo = be32(key);
89  keyhi = be32(key + 4);
90 
91  st->key_size = DES_KEY_SIZE;
92  st->rounds = 16;
93  cry->dir = direction;
94  // key permutation to derive round keys
96 
97  for (i = 0; i < 16; i++) {
98  // filling round keys space
99  rz_des_round_key(i, &st->keylo[i], &st->keyhi[i], &keylo, &keyhi);
100  }
101 
102  return true;
103 }
104 
105 static int des_get_key_size(RzCrypto *cry) {
106  rz_return_val_if_fail(cry->user, 0);
107  struct des_state *st = (struct des_state *)cry->user;
108  return st->key_size;
109 }
110 
111 static bool des_use(const char *algo) {
112  return algo && !strcmp(algo, "des-ecb");
113 }
114 
115 static bool update(RzCrypto *cry, const ut8 *buf, int len) {
116  rz_return_val_if_fail(cry->user, false);
117  struct des_state *st = (struct des_state *)cry->user;
118 
119  if (len <= 0) {
120  return false;
121  }
122 
123  // Pad to the block size, do not append dummy block
124  const int diff = (DES_BLOCK_SIZE - (len % DES_BLOCK_SIZE)) % DES_BLOCK_SIZE;
125  const int size = len + diff;
126  const int blocks = size / DES_BLOCK_SIZE;
127 
128  ut8 *const obuf = calloc(1, size);
129  if (!obuf) {
130  return false;
131  }
132 
133  ut8 *const ibuf = calloc(1, size);
134  if (!ibuf) {
135  free(obuf);
136  return false;
137  }
138 
139  memset(ibuf + len, 0, (size - len));
140  memcpy(ibuf, buf, len);
141  // got it from AES, should be changed??
142  // Padding should start like 100000...
143  // if (diff) {
144  // ibuf[len] = 8; //0b1000;
145  // }
146 
147  int i;
148  if (cry->dir == RZ_CRYPTO_DIR_DECRYPT) {
149  for (i = 0; i < blocks; i++) {
150  ut32 next = (DES_BLOCK_SIZE * i);
151  des_decrypt(st, ibuf + next, obuf + next);
152  }
153  } else {
154  for (i = 0; i < blocks; i++) {
155  ut32 next = (DES_BLOCK_SIZE * i);
156  des_encrypt(st, ibuf + next, obuf + next);
157  }
158  }
159 
160  rz_crypto_append(cry, obuf, size);
161  free(obuf);
162  free(ibuf);
163  return 0;
164 }
165 
166 static bool final(RzCrypto *cry, const ut8 *buf, int len) {
167  return update(cry, buf, len);
168 }
169 
170 static bool des_init(RzCrypto *cry) {
171  rz_return_val_if_fail(cry, false);
172  cry->user = RZ_NEW0(struct des_state);
173  return cry->user != NULL;
174 }
175 
176 static bool des_fini(RzCrypto *cry) {
177  rz_return_val_if_fail(cry, false);
178 
179  free(cry->user);
180  return true;
181 }
182 
184  .name = "des-ecb",
185  .author = "deroad",
186  .license = "LGPL-3",
187  .set_key = des_set_key,
188  .get_key_size = des_get_key_size,
189  .use = des_use,
190  .update = update,
191  .final = final,
192  .init = des_init,
193  .fini = des_fini,
194 };
195 
196 #ifndef RZ_PLUGIN_INCORE
199  .data = &rz_crypto_plugin_des,
200  .version = RZ_VERSION
201 };
202 #endif
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
#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 int des_encrypt(struct des_state *st, const ut8 *input, ut8 *output)
Definition: crypto_des.c:35
static void wbe32(ut8 *buf4, ut32 val)
Definition: crypto_des.c:28
static bool des_fini(RzCrypto *cry)
Definition: crypto_des.c:176
static bool des_use(const char *algo)
Definition: crypto_des.c:111
static bool update(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto_des.c:115
static int des_get_key_size(RzCrypto *cry)
Definition: crypto_des.c:105
static bool des_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction)
Definition: crypto_des.c:79
static bool des_init(RzCrypto *cry)
Definition: crypto_des.c:170
RZ_API RzLibStruct rizin_plugin
Definition: crypto_des.c:197
static int des_decrypt(struct des_state *st, const ut8 *input, ut8 *output)
Definition: crypto_des.c:58
static ut32 be32(const ut8 *buf4)
Definition: crypto_des.c:18
RzCryptoPlugin rz_crypto_plugin_des
Definition: crypto_des.c:183
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
uint32_t ut32
RZ_API void rz_des_permute_key(ut32 *keylo, ut32 *keyhi)
Apply PC-1.
Definition: des.c:115
RZ_API void rz_des_round_key(int i, RZ_OUT ut32 *keylo, RZ_OUT ut32 *keyhi, RZ_INOUT ut32 *deskeylo, RZ_INOUT ut32 *deskeyhi)
Calculate the final key to be used in a given round.
Definition: des.c:285
RZ_API void rz_des_permute_block1(ut32 *blocklo, ut32 *blockhi)
last permutation of the block
Definition: des.c:195
RZ_API void rz_des_round(RZ_OUT ut32 *buflo, RZ_OUT ut32 *bufhi, RZ_IN ut32 *roundkeylo, RZ_IN ut32 *roundkeyhi)
Apply the cipher function (f)
Definition: des.c:292
RZ_API void rz_des_permute_block0(ut32 *blocklo, ut32 *blockhi)
first permutation of the input block
Definition: des.c:171
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
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_CRYPTO_DIR_DECRYPT
Definition: rz_crypto.h:24
#define DES_BLOCK_SIZE
Definition: rz_des.h:7
#define DES_KEY_SIZE
Definition: rz_des.h:6
@ 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
ut32 buflo
Definition: crypto_des.c:11
int rounds
Definition: crypto_des.c:14
ut32 keylo[16]
Definition: crypto_des.c:9
int key_size
Definition: crypto_des.c:13
ut32 bufhi
Definition: crypto_des.c:12
ut32 keyhi[16]
Definition: crypto_des.c:10
const char * name
Definition: rz_crypto.h:41
void * user
Definition: rz_crypto.h:36
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
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
diff_output_t output
Definition: zipcmp.c:237