rizin/librz/include/rz_crypto.h
Ahmed Mohamed Ibrahim 38a530dbe3
librz/util: base64, base85, base36, base32, base16 support and refactor (#5216) (#5271)
* Rename librz/util/ubase64.c into librz/util/base64.c for consistency #5216

* Add Doxygen documentation to function in librz/util/base85.c #5216

* Add unit-tests for librz/util/base85.c #5216

* Refactor base85 API and internal functions #5216

base85 was using a FILE as an input and it used to print its result to
STDOUT, which was very bad for having unit-testing or to use it to
extend rz-hash functionality, since the solution I really had was
through using pipes which isn't ideal as much as the refactoring one.

* Extend rz-hash with base85 #5126

* Fix formatting #5216

* Extract base36 decoding function from subprojects/rzwinkd/iob_net.c to librz/util/base36.c #5216

- Also, added Doxygen docs to rz_base36_decode function

* Added rz_base36_encode_dyn #5216

- this function encode a u64 value to it's char[13+1] base36 counterpart
- later, it will be helpful in expanding the funcitionality of rz-hash
- added its Doxygen docs

* Expand rz-hash with base36 encoding/decoding #5216

* Refactor rz_base36_decode to return a suitable error code like -1 #5216

- that should help testing it later for valid and invalid decodings
- keeping the original behaviour as it was in
subprojects/rzwinkd/iob_net.c

* Add unit-tests for base36 encoding & decoding functions #5216

* Fix formatting #5216

* Fix base36.h header file guards #5216

* Add base32 encoding & decoding #5216

added their Doxygen Docs as well

* Add base32 encoding and decoding unti-tests #5216

* Expand rz-hash with base32 encoding/decoding functionality #5216

* Fix formatting #5216

* Fix add base32 to codec_name_bytes #5216

* Fix base32 docs #5216

* Add base16 encoding/decoding functions #5216

- added their Doxygen docs as well.

* Add base16 unit-tests #5216

* Fix test_base85 conversions warnings #5216

* Expand rz-hash with base16 encoding/decoding functionality #5216

* Fix formatting #5216

* Fix doxygen docs #5216

* Restore subprojects/rizin-shell-parser/parser.c to match origin/dev

* Fix the order by baseXX

* Fix base16 - invert the logic in calculate_src_length

* Fix base16 - intialize variables in rz_base16_encode

* Fix base16 - null terminate the output buffer of rz_base16_encode_dyn

* Fix base16 - get rid of unnecessary else in rz_base16_decode

* Fix base16 - use `len & 1` instead of `(len % 2) != 0`

* Fix base32 - invert the logic in calculate_src_length

* Fix base32 - compress two return statments by using `rz_return_val_if_fail(src && dest, 0);`

* Fix base32 - null terminate the output of rz_base32_encode

* Fix base32 - get rid of unnecessary else in rz_base32_decode

add more parentheses to split addition from mult for better clarity

* Fix base32 - intialize variables in rz_base32_encode_dyn

* Fix base36 - intialize `tmp` variable in rz_base36_encode_dyn

* Fix base36 - use RZ_LOG_ERROR instead of eprintf

* Fix base36 - use RZ_NULLABLE for the API interface

* Fix base85 - use RZ_OUT & RZ_NULLABLE for the API interface

* Fix base85 - use RZ_LOG_ERROR instead of eprintf

* Fix base85 - use size_t instead of int for decode_tuple_buf

* Fix base85 - remove unused varaible, `out_len`, in rz_base85_encode_dyn

* Fix base85 - correct decode buffer size calculation

The previous rz_base85_dec_buflen() underestimated the worst‑case output
size (3 bytes per 4 input chars), causing overflows when using ‘z’/’y’
abbreviations. Update it to allocate 4 bytes per input character plus
one for the NUL terminator, eliminating heap-buffer-overflow errors.

* Fix formatting

* Fix base85-test - use `newlines` variable to make sure line breaks were inserted as expected

* Fix base85-test - remove unnecessary includes

* Fix rz-hash test - updated rz-hash -L expected result

* Fix crypto_base36 - use RZ_LOG_ERROR instead of eprintf

* Fix base16 - compress rz_return_val_if_fail statements and move before locals

* Update base16 - use hex.c existing encoding/decoding logic

- base16.c encoding/decoding functions are now wrappers for hex.c
  `rz_hex_bin2str` and `rz_hex_str2bin` functions
- updated related base16 unit testing and documentation
- updated the integraion with rz-hash binary (or crypto_base16)

* Fix formatting

* Add documentation to rz_hex_bin2str

* Fix base85 - add missing `reutrn` docs to rz_base85_encode function

* Fix base85 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE

* Fix base36 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE

* Fix base16 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE

* Fix base32 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE

* Fix base16 - add missig checks for invalid inputs in rz_base16_encode & rz_base16_encode_dyn

* Fix base32 - add missing checks for bad encoding

* Fix - add missing SPDX

* Fix Formatting

* Add rz_base36_encode & rz_base36_decode_dyn functions to base36 API
2025-08-17 15:26:25 +08:00

121 lines
3.7 KiB
C

#ifndef RZ_CRYPTO_H
#define RZ_CRYPTO_H
#include <rz_types.h>
#include <rz_util/ht_sp.h>
#include <rz_crypto/rz_des.h>
#include <rz_util/rz_str.h>
#ifdef __cplusplus
extern "C" {
#endif
RZ_LIB_VERSION_HEADER(rz_crypto);
enum {
RZ_CRYPTO_MODE_ECB,
RZ_CRYPTO_MODE_CBC,
RZ_CRYPTO_MODE_OFB,
RZ_CRYPTO_MODE_CFB,
};
/* Defines in which direction the set_key methods needs to run */
enum {
RZ_CRYPTO_DIR_ENCRYPT = 0,
RZ_CRYPTO_DIR_DECRYPT,
};
typedef struct rz_crypto_t {
struct rz_crypto_plugin_t *h;
ut8 *key;
ut8 *iv;
int key_len;
ut8 *output;
int output_len;
int output_size;
int dir;
void *user;
HtSP /*<RzCryptoPlugin *>*/ *plugins;
} RzCrypto;
typedef struct rz_crypto_plugin_t {
const char *name;
const char *license;
const char *author;
const char *description;
int (*get_key_size)(RzCrypto *cry);
bool (*set_iv)(RzCrypto *cry, const ut8 *iv, int ivlen);
bool (*set_key)(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction);
bool (*update)(RzCrypto *cry, const ut8 *buf, int len);
bool (*final)(RzCrypto *cry, const ut8 *buf, int len);
bool (*use)(const char *algo);
bool (*init)(RzCrypto *cry);
bool (*fini)(RzCrypto *cry);
} RzCryptoPlugin;
typedef ut64 RzCryptoSelector;
/**
* \brief Compare plugins by name (via strcmp).
*/
static inline int rz_crypto_plugin_cmp(RZ_NULLABLE const RzCryptoPlugin *a, RZ_NULLABLE const RzCryptoPlugin *b) {
if (!a && !b) {
return 0;
} else if (!a) {
return -1;
} else if (!b) {
return 1;
}
return rz_str_cmp(a->name, b->name, -1);
}
#ifdef RZ_API
RZ_API bool rz_crypto_plugin_add(RZ_NONNULL RzCrypto *cry, RZ_NONNULL RzCryptoPlugin *h);
RZ_API bool rz_crypto_plugin_del(RZ_NONNULL RzCrypto *cry, RZ_NONNULL RzCryptoPlugin *h);
RZ_API RZ_OWN RzCrypto *rz_crypto_new(void);
RZ_API void rz_crypto_free(RZ_NULLABLE RzCrypto *cry);
RZ_API void rz_crypto_reset(RZ_NONNULL RzCrypto *cry);
RZ_API bool rz_crypto_use(RZ_NONNULL RzCrypto *cry, RZ_NONNULL const char *algo);
RZ_API bool rz_crypto_set_key(RZ_NULLABLE RzCrypto *cry, RZ_NULLABLE const ut8 *key, int keylen, int mode, int direction);
RZ_API bool rz_crypto_set_iv(RZ_NULLABLE RzCrypto *cry, RZ_NULLABLE const ut8 *iv, int ivlen);
RZ_API int rz_crypto_update(RZ_NULLABLE RzCrypto *cry, RZ_NULLABLE const ut8 *buf, int len);
RZ_API int rz_crypto_final(RZ_NULLABLE RzCrypto *cry, RZ_NULLABLE const ut8 *buf, int len);
RZ_API int rz_crypto_append(RZ_NONNULL RzCrypto *cry, RZ_NONNULL const ut8 *buf, int len);
RZ_API RZ_BORROW const ut8 *rz_crypto_get_output(RZ_NONNULL RzCrypto *cry, RZ_NULLABLE int *size);
RZ_API RZ_BORROW const char *rz_crypto_name(const RzCryptoSelector bit);
RZ_API RZ_BORROW const char *rz_crypto_codec_name(const RzCryptoSelector bit);
RZ_API RZ_BORROW const RzCryptoPlugin *rz_crypto_plugin_by_index(RZ_NONNULL RzCrypto *cry, size_t index);
#endif
#define RZ_CRYPTO_NONE 0ULL
#define RZ_CRYPTO_RC2 1ULL
#define RZ_CRYPTO_RC4 1ULL << 1
#define RZ_CRYPTO_RC6 1ULL << 2
#define RZ_CRYPTO_AES_ECB 1ULL << 3
#define RZ_CRYPTO_AES_CBC 1ULL << 4
#define RZ_CRYPTO_ROR 1ULL << 5
#define RZ_CRYPTO_ROL 1ULL << 6
#define RZ_CRYPTO_ROT 1ULL << 7
#define RZ_CRYPTO_BLOWFISH 1ULL << 8
#define RZ_CRYPTO_CPS2 1ULL << 9
#define RZ_CRYPTO_DES_ECB 1ULL << 10
#define RZ_CRYPTO_XOR 1ULL << 11
#define RZ_CRYPTO_SERPENT 1ULL << 12
#define RZ_CRYPTO_SM4_ECB 1ULL << 13
#define RZ_CRYPTO_ALL 0xFFFF
#define RZ_CODEC_NONE 0ULL
#define RZ_CODEC_B64 1ULL
#define RZ_CODEC_B91 1ULL << 1
#define RZ_CODEC_PUNYCODE 1ULL << 2
#define RZ_CODEC_B85 1ULL << 3
#define RZ_CODEC_B36 1ULL << 4
#define RZ_CODEC_B32 1ULL << 5
#define RZ_CODEC_B16 1ULL << 6
#define RZ_CODEC_ALL 0xFFFF
#ifdef __cplusplus
}
#endif
#endif