User Tools

Site Tools

ruth:hud:encryption

Ruth HUD Encryption

HUD Protocol

An encrypted mode has been proposed by Fred Beckhusen using XTEA.lsl. Currently configuration (key) is via notecard but this is not a long-term solution, eventually the key will need to be in a no-mod script. It adds an integer to the listen protocol.

Fred's solution was to take the XTEA implementation library and add a small link_message wrapper that enables both encryption and decryption via link messages. A channel is supplied with the encryption requests so the cipher text can be sent to that channel via llRegionsSay().

An extension is to return the cipher text via link_message if no channel number is supplied.

The code Fred has in Control is very similar to that in the XTEA LSL <-> PHP section of that wiki page. The proposed implementation differs from Fred's:

  • The XTEA functions are taken directly from the wiki page. This clarifies the license as that code is specifically stated to be public domain while Fred's code has a BSD license on it.
  • The wrapper code is simplified to just hard-code the secret rather than read it from a notecard. As with Fred's version, which this is based on, that code is licensed as CC-0, which is effectively public domain in most of the world.

These changes allow this script to be distributed in-world as no-modify/no-transfer and not violate any GPL/AGPL requirements. There is still a weakness in this scheme in that the script can be copied into other objects and used to decrypt intercepted communications.

Control Code

// The name of the XTEA script
string XTEA_NAME = "r2-xtea";

// Set to encrypt 'message' and re-send on channel 'id'
integer XTEAENCRYPT = 13475896;

// Set in the reply to a received XTEAENCRYPT if the passed channel is 0 or ""
integer XTEAENCRYPTED = 8303877;

// Set to decrypt 'message' and reply vi llMessageLinked()
integer XTEADECRYPT = 4690862;

// Set in the reply to a received XTEADECRYPT
integer XTEADECRYPTED = 3450924;

integer haz_xtea = FALSE;

integer can_haz_xtea() {
    // See if the XTEA script is present in object inventory
    integer count = llGetInventoryNumber(INVENTORY_SCRIPT);
    while (count--) {
        if (llGetInventoryName(INVENTORY_SCRIPT, count) == XTEA_NAME) {
            llOwnerSay("Found XTEA script");
            return TRUE;
        }
    }
    return FALSE;
}

send(string msg) {
    if (haz_xtea) {
        llMessageLinked(LINK_THIS, XTEAENCRYPT, msg, (string)r2channel);
    } else {
        llSay(r2channel, msg);
    }
    if (VERBOSE == 1) {
        llOwnerSay("S: " + msg);
    }
}

// ...

default {
    state_entry() {
        haz_xtea = can_haz_xtea();
        // ...
    }

    link_message(integer sender_number, integer number, string message, key id) {
        if (number == XTEAENCRYPTED) {
            llOwnerSay("Ciphertext: " + message);
        }
    }
}

Receiver Code

// The name of the XTEA script
string XTEA_NAME = "r2-xtea";

// Set to encrypt 'message' and re-send on channel 'id'
integer XTEAENCRYPT = 13475896;

// Set in the reply to a received XTEAENCRYPT if the passed channel is 0 or ""
integer XTEAENCRYPTED = 8303877;

// Set to decrypt 'message' and reply vi llMessageLinked()
integer XTEADECRYPT = 4690862;

// Set in the reply to a received XTEADECRYPT
integer XTEADECRYPTED = 3450924;

integer haz_xtea = FALSE;

integer can_haz_xtea() {
    // See if the XTEA script is present in object inventory
    integer count = llGetInventoryNumber(INVENTORY_SCRIPT);
    while (count--) {
        if (llGetInventoryName(INVENTORY_SCRIPT, count) == XTEA_NAME) {
            llOwnerSay("Found XTEA script");
            return TRUE;
        }
    }
    return FALSE;
}

// ...

default {
    state_entry() {
        haz_xtea = can_haz_xtea();
        // ...
    }


    listen(integer channel, string name, key id, string message) {
        if (llGetOwnerKey(id) == llGetOwner()) {
            if (channel == r2channel) {

            // Check if message received is cleartext and handle
            // ...

            else {
                if (haz_xtea) {
                    llMessageLinked(LINK_THIS, XTEADECRYPT, message, "");
                }
            }
        }
    }

    link_message(integer sender_number, integer number, string message, key id) {
        if (number == XTEADECRYPTED) {
            list cmdargs = llCSV2List(message);
            string command = llToUpper(llList2String(cmdargs, 0));

            // handle decrypted message
            // ...
        }
    }
}

Page Tools





oeffentlich