Provided by: radare2_6.0.7+ds-1_amd64 bug

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

       r_hash(3)

Debian                                         September 20, 2025                                      R_MUTA(3)