- unstable 6.0.4+dfsg-1
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 small plugin-based framework for data transformations used across radare2. It exposes a thin, consistent API to list available plugins (hashers, encoders, ciphers, small transforms), 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.
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_new_session
(RMuta
*mu, const char *algo,
RMutaOptions *opt)
Like `r_muta_use`, but accepts an `RMutaOptions` structure to provide plugin-specific options during session creation.
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).
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.
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.
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.
PLUGINS¶
The context can be extended with plugins or inspected to enumerate
supported algorithms. Plugins implement a small vtable of callbacks
(set_key, update, end, etc.). bool
r_muta_add
(RMuta
*cry, RMutaPlugin *h)
Registers a plugin into the context. Plugins provided in the tree are automatically added by `r_muta_init` called from `r_muta_new`.
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 returned string must be freed by the caller.
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 number of built-in plugins are available (AES, DES, Blowfish, RC2/4/6, XOR, ROT/ROL/ROR, base64/base91, bech32, punycode, ed25519, entropy, various hash algorithms). Use `r_muta_list()` to discover what is available in the running build.
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 in `r_hash_tostring` (see `libr/muta/hash/hash.c`).
/* 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. The pattern is taken from `libr/muta/p/muta_aes.c` and how sessions are consumed by callers.
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);
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`.
SEE ALSO¶
September 20, 2025 | Debian |