MOD License LV2 Extension

http://moddevices.com/ns/ext/license

Overview

The MOD License extension defines a lightweight protocol for LV2 plugin copy-protection and trial mode. It describes how a host communicates license file contents to a plugin, and how the plugin reports its licensed status back to the host.

This extension is designed so that the host carries no cryptographic logic. The host only knows where license files are stored and how to pass their contents to the plugin. All verification is performed inside the plugin binary using libmodla, the reference implementation library distributed by MOD Audio to plugin developers.

Current version: v1.3.2

URIs

URI Role Used by
http://moddevices.com/ns/ext/license#feature LV2 feature the host provides to the plugin at instantiate time. Carries the license file retrieval function. Host → Plugin
http://moddevices.com/ns/ext/license#interface LV2 extension data interface the plugin exposes. Allows the host to query license status and licensee name. Plugin → Host

License File Format

A license file is a plain text file. Its filename is the SHA-1 hash of the plugin URI it applies to. The file contains six lines:

John Doe
http://example.com/my-plugin
0F1E2D3C48796A5B4C3D2E1F0B5A6978
obiYTZ0hW/eEkUi4ZZCDaxWiezrATf+yeH4dPMT+Eul2ypPGYqFqstbNjA2UBuJx
jwEH705c07jvyF/d3Id+0DPCk012nDUd0WxqNXrKH7ZXycyu0IXWxxONp7DDpj1z
ht2vvZgk42DW3k5U942SUN4TRjdPEK5HY/sBOslqBO0=

Lines 1–3 are the plaintext payload: licensee name, plugin URI, and device hardware unique ID. Lines 4–6 are the RSA/SHA-1 signature of lines 1–3, base64-encoded, signed with MOD Audio's private key.

If any of the first three lines are altered, the signature will no longer match and the plugin will run in trial mode. The private key never leaves MOD Audio's infrastructure.

License files are issued by MOD Audio's cloud service. To obtain license issuance for your platform, see mod.audio/licensing.

Host Implementation

A host that supports this extension must provide the MOD_LICENSE__feature LV2 feature to plugins at instantiate time. This feature carries a MOD_License_Feature struct with two function pointers:

typedef struct _MOD_License_Feature {
    MOD_License_Handle handle;

    /* Returns the contents of the license file for license_uri,
       or NULL if no license exists. Caller must free() the result. */
    char* (*license)(MOD_License_Handle handle, const char* license_uri);

    /* Frees the data returned by license(). */
    void  (*free)(MOD_License_Handle handle, char* license);
} MOD_License_Feature;

The host is responsible for knowing where license files are stored on the device (by default /root/keys/, configurable via the MOD_KEYS_PATH environment variable). The host reads the file and returns its raw contents. It performs no validation.

The host may also query a loaded plugin instance for its license status by calling extension_data(MOD_LICENSE__interface), which returns a MOD_License_Interface struct:

typedef struct _MOD_License_Interface {
    /* Returns MOD_License_Status for the plugin instance. */
    int   (*status)(LV2_Handle instance);

    /* Returns the licensee name, or NULL if unlicensed.
       Caller must free() the result. */
    char* (*licensee)(LV2_Handle instance);
} MOD_License_Interface;

Status Codes

ConstantValueMeaning
MOD_LICENSE_SUCCESS 0 Plugin is licensed and running normally.
MOD_LICENSE_ERR_UNKNOWN 1 License check failed for an unspecified reason.
MOD_LICENSE_ERR_UNLICENSED 2 No valid license found. Plugin runs in trial mode — audio output is silenced after ~37 seconds.
MOD_LICENSE_ERR_UNSUPPORTED 3 Host does not support this extension. Plugin runs without restriction.

Trial Mode

When no valid license is found, the plugin runs in trial mode. Audio output is passed through normally for approximately 37 seconds, after which the plugin begins injecting silence into all audio output buffers. This behaviour is implemented inside the plugin binary via libmodla and requires no action from the host.

Trial mode is the default state for any plugin that links libmodla and has not yet been purchased. Every plugin on a MOD-powered marketplace is freely triable without account creation or time limits on the trial period itself.

Plugin TTL Declaration

A plugin that supports this extension must declare it in its LV2 .ttl metadata:

Required in your plugin's manifest.ttl or plugin .ttl file:
<http://example.com/your-plugin>
    a lv2:Plugin ;
    lv2:extensionData <http://moddevices.com/ns/ext/license#interface> ;
    lv2:requiredFeature <http://moddevices.com/ns/ext/license#feature> .

Plugin Developer Quick Start

Plugin developers receive a redistribution package from MOD Audio (via their hardware partner) containing the pre-compiled libmodla.a static library, this header, and an example plugin. Integration requires four steps:

/* 1. Include the header */
#include <libmodla.h>

/* 2. Add run_count to your plugin struct, initialized to 0 */
uint32_t run_count;

/* 3. Call at instantiate() — once per license URI */
mod_license_check(features, "http://example.com/your-plugin");

/* 4. Call at the start of run() */
run_count = mod_license_run_begin(run_count, n_samples);

/* 5. Call at the end of run() for each audio output buffer */
mod_license_run_silence(run_count, audio_out[i], n_samples, i);

/* 6. Return from extension_data() */
return mod_license_interface(uri);

See the example plugin included in the redistribution package for a complete working implementation. For access to the redistribution package, contact your hardware platform provider or sales@mod.audio.

Copyright

This extension and its reference implementation are developed and owned by MOD Audio.

The extension specification (mod-license.h) is released under the ISC licence. The reference implementation (libmodla) is proprietary and distributed separately under agreement with MOD Audio.