| R_MUTA(3) | Library Functions Manual | R_MUTA(3) |
NAME
r_muta — radare2
mutation/cryptography library
SYNOPSIS
#include
<r_muta.h>
DESCRIPTION
The r_muta facility implements a comprehensive plugin-based framework for data transformations used across radare2. It exposes a thin, consistent API to list available plugins (hashers, encoders, ciphers, charset conversions, signature algorithms), create sessions, configure keys/IVs and stream data through plugins to produce outputs. The design focuses on reusability from other core libraries (for example, the hashing helper in `libr/muta/hash/hash.c`) so callers can treat most algorithms uniformly.
INITIALIZATION
The context object represents the global registry of available
mutation plugins. Allocate it once when you need to query or create plugin
sessions, and free it after all sessions are released. RMuta
*
r_muta_new(void)
Creates and returns a new mutation context with bundled plugins registered.
void
r_muta_free(RMuta
*cry)
Releases the context and all internal resources. Do not use a session after its parent context has been freed.
bool
r_muta_add(RMuta
*cry, RMutaPlugin *h)
Registers a plugin into the context. Plugins provided in the tree are automatically added during context creation by `r_muta_new`.
bool
r_muta_del(RMuta
*cry, RMutaPlugin *h)
Removes a plugin from the context's plugin list.
void
r_muta_bind(RMuta
*cry, RMutaBind *bnd)
Binds RMuta functions to a RMutaBind structure for language bindings.
PLUGIN DISCOVERY
The context provides functions to discover and query available
plugins. RMutaPlugin *
r_muta_find(RMuta
*cry, const char *algo)
Finds a plugin by algorithm name, supports both exact name matching and implements field checking. Returns NULL if not found.
RMutaType
r_muta_algo_type(RMuta
*cry, const char *algo)
Returns the type (hash, crypto, charset, etc.) of a specific algorithm.
bool
r_muta_algo_supports(RMuta
*cry, const char *algo,
RMutaType type)
Checks if an algorithm supports a specific type.
char *
r_muta_list(RMuta
*cry, RMutaType type, int
mode)
Returns a new string listing available plugins of `type` (for example `R_MUTA_TYPE_CRYPTO` or `R_MUTA_TYPE_HASH`). The `mode` parameter controls output format: 'j' for JSON, 'J' for JSON array, 'q' for quiet, default for verbose. The returned string must be freed by the caller.
SESSIONS
Plugins are used via sessions. A session is an instance of a
plugin (for example, an AES or a hash) and keeps per-operation state.
Typical lifecycle: create session -> set key/iv (if applicable) ->
update() -> end() -> get_output() -> free session.
RMutaSession *
r_muta_use(RMuta
*cry, const char *algo)
Creates a session for a plugin selected by name (example names: "aes-ecb", "aes-cbc", "base64", "xor", "sha1"). Returns NULL if the plugin is not found.
RMutaSession *
r_muta_session_new(RMuta
*cry, RMutaPlugin *cp)
Creates a new session for a specific plugin instance.
void
r_muta_session_free(RMutaSession
*cj)
Frees session state. Always call this when finished with a session to avoid leaks.
KEY AND IV SETUP
Most symmetric ciphers require a key and many block-based modes
require an IV. Set these on the session before streaming data.
bool
r_muta_session_set_key(RMutaSession
*cj, const ut8 *key, int
keylen, int mode, int
direction)
Configures the cryptographic key and direction (encrypt/decrypt) for the session. Return value indicates whether the plugin accepted the key (for example invalid key size will fail).
int
r_muta_session_get_key_size(RMutaSession
*cj)
Returns the key size required by the current algorithm.
bool
r_muta_session_set_iv(RMutaSession
*cj, const ut8 *iv, int
ivlen)
Sets the initialization vector used by block cipher modes such as CBC.
bool
r_muta_session_set_subtype(RMutaSession
*cj, const char *subtype)
Sets a subtype for the session (used for algorithm variants).
PROCESSING
Streaming APIs allow sending data in chunks. Use
`r_muta_session_update` for intermediate chunks and `r_muta_session_end` for
the last chunk; some plugins treat `end` as a way to finalize padding or
state. bool
r_muta_session_update(RMutaSession
*cj, const ut8 *buf, int
len)
Feeds `len` bytes from `buf` into the session for processing. Returns true on success.
bool
r_muta_session_end(RMutaSession
*cj, const ut8 *buf, int
len)
Finalizes processing. Can accept a final chunk (or `NULL, 0`) to finish and flush internal buffers.
int
r_muta_session_append(RMutaSession
*cj, const ut8 *buf, int
len)
Internal helper used by plugins to append produced bytes to the session output buffer. Callers usually do not need to use this directly.
ut8 *
r_muta_session_decode_string(RMutaSession
*cj, const ut8 *input, int
len, RMutaDecodeCallback decode_fn,
void *decode_ctx)
Decodes a string using a custom decode callback function.
OUTPUT
After the session ends (or at any point the plugin exposes
output), retrieve the produced bytes with `r_muta_session_get_output`. The
returned buffer is heap allocated and must be freed by the caller.
ut8 *
r_muta_session_get_output(RMutaSession
*cj, int *size)
Returns a newly allocated buffer containing the processed output and sets `*size` to the buffer length. The caller is responsible for `free()`ing it.
HIGH-LEVEL PROCESSING
For simple use cases, the library provides unified processing
functions that handle session creation and cleanup automatically.
RMutaResult
r_muta_process(RMuta
*cry, const char *algo, const
ut8 *data, int len, const ut8
*key, int key_len, const ut8
*iv, int iv_len, int
direction)
Unified processing function for all operations (hash, crypto, encode/decode). Returns an RMutaResult structure containing the output and metadata.
RMutaResult
r_muta_process_simple(RMuta
*cry, const char *algo, const
ut8 *data, int len)
Simple wrapper for hash and entropy operations without keys/IVs.
void
r_muta_result_free(RMutaResult
*res)
Frees resources allocated in an RMutaResult structure.
CHARSET FUNCTIONS
The library provides specialized functions for charset encoding
and decoding operations. int
r_muta_charset_parse_default(const
char *str, const char *end, char
*token, int token_max)
Default parser for charset tokens, handles escape sequences, UTF-8, and special tokens.
ut8 *
r_muta_charset_decode(const
ut8 *in, int in_len, int
*out_len, const RMutaCharsetMap *table,
const char *unknown_fmt)
Decodes binary data to UTF-8 using a charset mapping table.
ut8 *
r_muta_charset_encode(const
ut8 *in, int in_len, int
*out_len, const RMutaCharsetMap *table,
RMutaCharsetParserFn parser)
Encodes UTF-8 data to binary using a charset mapping table.
ut8 *
r_muta_charset_encode_ex(const
ut8 *in, int in_len, int
*out_len, const RMutaCharsetMap *table,
RMutaCharsetParserFn parser, ut8
unknown_byte)
Extended version of charset encode with custom unknown byte handling.
bool
r_muta_charset_stub_update(RMutaSession
*cj, const ut8 *b, int
l)
Stub update function that simply appends data to output.
bool
r_muta_charset_stub_end(RMutaSession
*cj, const ut8 *b, int
l)
Stub end function that calls the stub update function.
bool
r_muta_charset_tr_update(RMutaSession
*cj, const ut8 *buf, int
len, const ut8 tr[256])
Translation table update function for simple charset transformations.
CRYPTOGRAPHIC FUNCTIONS
Specialized cryptographic functions for specific algorithms.
void
r_muta_ed25519_keypair(const
ut8 *seed, ut8 *privkey, ut8
*pubkey)
Generates Ed25519 keypair from a 32-byte seed.
DATA STRUCTURES
RMutaType Enum
Enumeration of plugin types:
- R_MUTA_TYPE_HASH
- Hash algorithms (MD5, SHA family, CRC, etc.)
- R_MUTA_TYPE_BASE
- Base encoding algorithms (Base64, Base91, Bech32)
- R_MUTA_TYPE_CRYPTO
- Symmetric ciphers (AES, DES, Blowfish, etc.)
- R_MUTA_TYPE_SIGN
- Signature algorithms (Ed25519)
- R_MUTA_TYPE_CHARSET
- Charset conversions (ASCII, international charsets)
- R_MUTA_TYPE_ALL
- Special value to match all plugin types
RMutaResult Structure
Result structure returned by high-level processing functions:
typedef struct r_muta_result_t {
ut8 *output; // binary output
int output_len; // length of output
int output_size; // allocated size of output buffer
double entropy; // entropy value
char *hex; // hex-encoded output
bool success; // operation succeeded
bool text_output; // output is text, not binary
} RMutaResult;
Operation Constants
- R_MUTA_OP_NONE
- No operation specified
- R_MUTA_OP_HASH
- Hash operation
- R_MUTA_OP_DECRYPT
- Decryption operation
- R_MUTA_OP_ENCRYPT
- Encryption operation
MODES AND DIRECTIONS
Plugins accept modes and directions to control behavior; common values are `R_CRYPTO_DIR_ENCRYPT` and `R_CRYPTO_DIR_DECRYPT`. Modes cover block cipher modes such as ECB, CBC, OFB, and CFB. Choose the direction consistently when calling `r_muta_session_set_key`.
ALGORITHMS
A comprehensive set of built-in plugins is available:
- Hash
- MD5, SHA family (SHA1, SHA224, SHA256, SHA384, SHA512), CRC variants, entropy calculations, ssdeep, strhash, fletcher
- Crypto
- AES (ECB, CBC, WRAP), DES, Blowfish, Serpent, SM4, XOR, RC algorithms
- Base Encoding
- Base64, Base91, Bech32, punycode
- Signature
- Ed25519 digital signatures
- Charset
- ASCII, various international charsets (Arabic ISO/Windows, Cyrillic ISO/Windows, Greek ISO/Windows, Hebrew ISO/Windows, Asian charsets like JIS7, Hiragana, Katakana), gaming charsets (Pokemon, Pokemon Red)
- Transformations
- ROT, ROL, ROR, ADD, translation tables
EXAMPLES
This section shows idiomatic, real-world usages of the API. The first example demonstrates how `libr/muta/hash/hash.c` uses r_muta to implement algorithm-agnostic hashing.
/* Example: computing a hash using a plugin when available
* See: libr/muta/hash/hash.c
*/
RMuta *cry = r_muta_new();
RMutaSession *cj = r_muta_use (cry, name); // name like "sha1" or "md5"
int digest_size = 0;
if (cj && cj->h->type == R_MUTA_TYPE_HASH) {
r_muta_session_update (cj, data, len);
ut8 *result = r_muta_session_get_output (cj, &digest_size);
if (result) {
memcpy (ctx->digest, result, digest_size);
free (result);
}
} else {
/* fallback to internal r_hash implementation */
}
r_muta_session_free (cj);
r_muta_free (cry);
The AES example below follows the lifecycle for a cipher plugin, showing key and IV setup, streaming update and finalization.
RMuta *cry = r_muta_new();
RMutaSession *s = r_muta_use (cry, "aes-cbc");
if (!s) { /* handle error */ }
// Set a 128/192/256-bit key; direction is R_CRYPTO_DIR_ENCRYPT
ut8 key[16] = { /* ... */ };
ut8 iv[16] = { /* ... */ };
if (!r_muta_session_set_key (s, key, sizeof key, R_CRYPTO_MODE_CBC, R_CRYPTO_DIR_ENCRYPT)) {
/* invalid key or plugin refused */
}
if (!r_muta_session_set_iv (s, iv, sizeof iv)) {
/* invalid iv */
}
// Stream plaintext
r_muta_session_update (s, plaintext, plaintext_len);
// Finalize and flush
r_muta_session_end (s, NULL, 0);
int outlen = 0;
ut8 *cipher = r_muta_session_get_output (s, &outlen);
// use cipher, then free
free (cipher);
r_muta_session_free (s);
r_muta_free (cry);
Simpler transformations, such as base64 or xor, follow the same session API; set_key may be a no-op for stateless encoders. The XOR plugin demonstrates setting a small repeating key and streaming the buffer.
RMuta *cry = r_muta_new();
RMutaSession *s = r_muta_use (cry, "xor");
ut8 key[4] = {0x41, 0x42, 0x43, 0x44};
r_muta_session_set_key (s, key, 4, 0, R_CRYPTO_DIR_ENCRYPT);
r_muta_session_update (s, data, len);
r_muta_session_end (s, NULL, 0);
int outlen = 0;
ut8 *out = r_muta_session_get_output (s, &outlen);
free (out);
r_muta_session_free (s);
r_muta_free (cry);
For simple one-shot operations, the high-level processing functions provide a more convenient API:
RMuta *cry = r_muta_new();
RMutaResult result = r_muta_process_simple (cry, "sha256", data, len);
if (result.success) {
printf("Hash: %s\n", result.hex);
free (result.output);
free (result.hex);
}
r_muta_free (cry);
Charset encoding example for converting UTF-8 to a specific charset:
RMuta *cry = r_muta_new();
RMutaSession *s = r_muta_use (cry, "charset-ascii");
if (s) {
r_muta_session_update (s, utf8_text, utf8_len);
r_muta_session_end (s, NULL, 0);
int outlen = 0;
ut8 *ascii = r_muta_session_get_output (s, &outlen);
// use ascii output
free (ascii);
r_muta_session_free (s);
}
r_muta_free (cry);
NOTES
Plugins follow a vtable pattern: `RMutaPlugin` exposes callbacks such as `set_key`, `update`, `end` and `get_key_size`. Callers should: - Create a single `RMuta` context per scope and reuse it for multiple sessions. - Always call `r_muta_session_free` after finishing with a session. - Free the buffer returned by `r_muta_session_get_output`. - For high-level one-shot operations, prefer `r_muta_process()` or `r_muta_process_simple()` over manual session management. - The library supports a wide variety of algorithms including modern ciphers (AES, Serpent, SM4), classical ciphers (DES, Blowfish), hash functions (SHA family, MD5, CRC), base encodings (Base64, Base91, Bech32), signature algorithms (Ed25519), and extensive charset support including international and gaming charsets.
SEE ALSO
| January 14, 2026 | Linux 6.19.10-arch1-1 |