Rizin
unix-like reverse engineering framework and cli tools
crypto.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2017 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_crypto.h>
5 #include "config.h"
6 #include <rz_util.h>
7 
8 #define RZ_CRYPTO_OUTPUT_SIZE 4096
9 
10 RZ_LIB_VERSION(rz_crypto);
11 
13 
14 static const struct {
15  const char *name;
17 } crypto_name_bytes[] = {
18  { "all", UT64_MAX },
19  { "rc2", RZ_CRYPTO_RC2 },
20  { "rc4", RZ_CRYPTO_RC4 },
21  { "rc6", RZ_CRYPTO_RC6 },
22  { "aes-ecb", RZ_CRYPTO_AES_ECB },
23  { "aes-cbc", RZ_CRYPTO_AES_CBC },
24  { "ror", RZ_CRYPTO_ROR },
25  { "rol", RZ_CRYPTO_ROL },
26  { "rot", RZ_CRYPTO_ROT },
27  { "blowfish", RZ_CRYPTO_BLOWFISH },
28  { "cps2", RZ_CRYPTO_CPS2 },
29  { "des-ecb", RZ_CRYPTO_DES_ECB },
30  { "xor", RZ_CRYPTO_XOR },
31  { "serpent-ecb", RZ_CRYPTO_SERPENT },
32 };
33 
34 static const struct {
35  const char *name;
37 } codec_name_bytes[] = {
38  { "all", UT64_MAX },
39  { "base64", RZ_CODEC_B64 },
40  { "base91", RZ_CODEC_B91 },
41  { "punycode", RZ_CODEC_PUNYCODE },
42 };
43 
45  size_t i;
46  for (i = 1; i < RZ_ARRAY_SIZE(crypto_name_bytes); i++) {
47  if (bit == crypto_name_bytes[i].bit) {
48  return crypto_name_bytes[i].name;
49  }
50  }
51  return "";
52 }
53 
55  size_t i;
56  for (i = 1; i < RZ_ARRAY_SIZE(codec_name_bytes); i++) {
57  if (bit == codec_name_bytes[i].bit) {
58  return codec_name_bytes[i].name;
59  }
60  }
61  return "";
62 }
63 
66  if (index >= size) {
67  return NULL;
68  }
69  return crypto_static_plugins[index];
70 }
71 
73  // add a check ?
74  rz_list_append(cry->plugins, h);
75  return true;
76 }
77 
80  return true;
81 }
82 
84  RzCrypto *cry = RZ_NEW0(RzCrypto);
85  if (!cry) {
86  goto rz_crypto_new_bad;
87  }
88 
91  if (!cry->output) {
92  goto rz_crypto_new_bad;
93  }
94 
96  if (!cry->plugins) {
97  goto rz_crypto_new_bad;
98  }
99 
100  for (ut32 i = 0; i < RZ_ARRAY_SIZE(crypto_static_plugins); i++) {
102  if (!p) {
103  goto rz_crypto_new_bad;
104  }
106  rz_crypto_add(cry, p);
107  }
108  return cry;
109 
110 rz_crypto_new_bad:
111  RZ_LOG_ERROR("[!] crypto: failed to allocate\n");
112  rz_crypto_free(cry);
113  return NULL;
114 }
115 
117  if (!cry) {
118  return;
119  }
120  if (cry->h && cry->h->fini && !cry->h->fini(cry)) {
121  RZ_LOG_ERROR("[!] crypto: error terminating '%s' plugin\n", cry->h->name);
122  }
123  rz_list_free(cry->plugins);
124  free(cry->output);
125  free(cry->key);
126  free(cry->iv);
127  free(cry);
128 }
129 
130 RZ_API bool rz_crypto_use(RzCrypto *cry, const char *algo) {
131  RzListIter *iter;
132  RzCryptoPlugin *h;
133  if (cry->h && cry->h->fini && !cry->h->fini(cry)) {
134  RZ_LOG_ERROR("[!] crypto: error terminating '%s' plugin\n", cry->h->name);
135  }
136  rz_list_foreach (cry->plugins, iter, h) {
137  rz_warn_if_fail(h && h->use);
138  if (h && h->use(algo)) {
139  if (h->init && !h->init(cry)) {
140  RZ_LOG_ERROR("[!] crypto: error initializing '%s' plugin\n", cry->h->name);
141  return false;
142  }
143 
144  cry->h = h;
145  return true;
146  }
147  }
148  return false;
149 }
150 
151 RZ_API bool rz_crypto_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
152  if (keylen < 0) {
153  keylen = strlen((const char *)key);
154  }
155  if (!cry || !cry->h || !cry->h->set_key) {
156  return false;
157  }
158  return cry->h->set_key(cry, key, keylen, mode, direction);
159 }
160 
161 RZ_API bool rz_crypto_set_iv(RzCrypto *cry, const ut8 *iv, int ivlen) {
162  return (cry && cry->h && cry->h->set_iv) ? cry->h->set_iv(cry, iv, ivlen) : 0;
163 }
164 
165 // return the number of bytes written in the output buffer
166 RZ_API int rz_crypto_update(RzCrypto *cry, const ut8 *buf, int len) {
167  return (cry && cry->h && cry->h->update) ? cry->h->update(cry, buf, len) : 0;
168 }
169 
170 RZ_API int rz_crypto_final(RzCrypto *cry, const ut8 *buf, int len) {
171  return (cry && cry->h && cry->h->final) ? cry->h->final(cry, buf, len) : 0;
172 }
173 
174 // TODO: internal api?? used from plugins? TODO: use rz_buf here
175 RZ_API int rz_crypto_append(RzCrypto *cry, const ut8 *buf, int len) {
176  if (!cry || !buf) {
177  return -1;
178  }
179  if (cry->output_len + len > cry->output_size) {
180  cry->output_size += 4096 + len;
181  cry->output = realloc(cry->output, cry->output_size);
182  }
183  if (!cry->output) {
185  cry->output_size = 0;
186  return 0;
187  }
188  memcpy(cry->output + cry->output_len, buf, len);
189  cry->output_len += len;
190  return cry->output_len;
191 }
192 
194  if (cry->output_size < 1 || !cry->output) {
195  if (size) {
196  *size = 0;
197  }
198  return NULL;
199  }
200  if (size) {
201  *size = cry->output_len;
202  }
203  return cry->output;
204 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define RZ_CRYPTO_STATIC_PLUGINS
Definition: config.h:27
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API int rz_crypto_update(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto.c:166
static const struct @228 codec_name_bytes[]
RzCryptoSelector bit
Definition: crypto.c:16
static const struct @227 crypto_name_bytes[]
RZ_API bool rz_crypto_set_iv(RzCrypto *cry, const ut8 *iv, int ivlen)
Definition: crypto.c:161
RZ_API int rz_crypto_final(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto.c:170
RZ_API int rz_crypto_del(RzCrypto *cry, RzCryptoPlugin *h)
Definition: crypto.c:78
RZ_API int rz_crypto_add(RzCrypto *cry, RzCryptoPlugin *h)
Definition: crypto.c:72
const char * name
Definition: crypto.c:15
RZ_API const char * rz_crypto_codec_name(const RzCryptoSelector bit)
Definition: crypto.c:54
RZ_API const ut8 * rz_crypto_get_output(RzCrypto *cry, int *size)
Definition: crypto.c:193
RZ_API const char * rz_crypto_name(const RzCryptoSelector bit)
Definition: crypto.c:44
RZ_LIB_VERSION(rz_crypto)
#define RZ_CRYPTO_OUTPUT_SIZE
Definition: crypto.c:8
RZ_API bool rz_crypto_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction)
Definition: crypto.c:151
RZ_API void rz_crypto_free(RzCrypto *cry)
Definition: crypto.c:116
RZ_API RzCrypto * rz_crypto_new(void)
Definition: crypto.c:83
RZ_API const RzCryptoPlugin * rz_crypto_plugin_by_index(size_t index)
Definition: crypto.c:64
RZ_API bool rz_crypto_use(RzCrypto *cry, const char *algo)
Definition: crypto.c:130
static RzCryptoPlugin * crypto_static_plugins[]
Definition: crypto.c:12
RZ_API int rz_crypto_append(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto.c:175
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 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
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API bool rz_list_delete_data(RZ_NONNULL RzList *list, void *ptr)
Deletes an entry in the list by searching for a pointer.
Definition: list.c:148
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35
#define RZ_CRYPTO_XOR
Definition: rz_crypto.h:102
#define RZ_CRYPTO_RC2
Definition: rz_crypto.h:91
#define RZ_CRYPTO_RC4
Definition: rz_crypto.h:92
#define RZ_CRYPTO_ROR
Definition: rz_crypto.h:96
#define RZ_CRYPTO_ROT
Definition: rz_crypto.h:98
#define RZ_CRYPTO_BLOWFISH
Definition: rz_crypto.h:99
#define RZ_CRYPTO_CPS2
Definition: rz_crypto.h:100
#define RZ_CRYPTO_DES_ECB
Definition: rz_crypto.h:101
#define RZ_CODEC_B64
Definition: rz_crypto.h:107
#define RZ_CRYPTO_ROL
Definition: rz_crypto.h:97
#define RZ_CRYPTO_AES_ECB
Definition: rz_crypto.h:94
#define RZ_CODEC_PUNYCODE
Definition: rz_crypto.h:109
#define RZ_CRYPTO_RC6
Definition: rz_crypto.h:93
#define RZ_CRYPTO_AES_CBC
Definition: rz_crypto.h:95
#define RZ_CRYPTO_SERPENT
Definition: rz_crypto.h:103
#define RZ_CODEC_B91
Definition: rz_crypto.h:108
ut64 RzCryptoSelector
Definition: rz_crypto.h:54
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define UT64_MAX
Definition: rz_types_base.h:86
#define h(i)
Definition: sha256.c:48
bool(* update)(RzCrypto *cry, const ut8 *buf, int len)
Definition: rz_crypto.h:47
const char * name
Definition: rz_crypto.h:41
bool(* set_key)(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction)
Definition: rz_crypto.h:46
bool(* set_iv)(RzCrypto *cry, const ut8 *iv, int ivlen)
Definition: rz_crypto.h:45
bool(* final)(RzCrypto *cry, const ut8 *buf, int len)
Definition: rz_crypto.h:48
bool(* fini)(RzCrypto *cry)
Definition: rz_crypto.h:51
struct rz_crypto_plugin_t * h
Definition: rz_crypto.h:28
ut8 * iv
Definition: rz_crypto.h:30
ut8 * output
Definition: rz_crypto.h:32
RzList * plugins
Definition: rz_crypto.h:37
ut8 * key
Definition: rz_crypto.h:29
int output_len
Definition: rz_crypto.h:33
int output_size
Definition: rz_crypto.h:34