This documents the current implementation of checksums in psyced. This is not final, not a standard, and you may have a thousand suggestions to improve this. This might even re-invent some wheels.

Checksums can currently be introduced both on MMP and PSYC level, defining two different scopes of purpose for the checksums being either circuit or end-to-end entity.

There are checksums for the purpose of checking integrity and others for checking integrity and additionally enabling trust. The naming convention is actually wrong, as trust is a special case of integrity, so should this ever go into a spec it should be called _check vs _check_trust instead.

Checksums are mostly useful to protect from UDP spoofing, but you can also apply it to TCP circuits. Should you want one single checksum to be used to raise the general trust level of a circuit, you can do so by sending a _request_circuit_trust to the circuit (the psyc://host uniform without resource). Should this packet contain a valid checksum, the trust level of that checksum will be memorized for all packets coming over this circuit. This is necessary for remote control, for example.

Checksum of what you ask? Well the checksum is computed on all subsequent bytes following the declaration of the _check variable on the stream (including newlines) until the end of the packet. The order of the sender is thus used, no need to organize variables alphabetically or anything like that. Should you want to forward the checksum, you will have to forward the packet as is.

Integrity checks

A SHA1 hash of the rest of the packet as explained above is given in a variable called _check_integrity_SHA1. When present, psyced will check if the information is correct. Should the packet have been tampered with, it will be rejected and an _error_invalid_integrity is returned.

Trust & integrity checks

They are transmitted in a variable called _check_SHA256, which is to contain the checksum (there are also others, but may they remain undocumented for now).

_check_SHA256 is computed as

hmac(TLS_HASH_SHA256, hash(TLS_HASH_SHA256, <secret>), checksum)

The secret should be a shared secret between the two hosts to be specified by the /config command, but in fact it is currently specified by #define SYSTEM_SECRET and also used for XMPP dialback, so be careful who you pass this on.

Once a checksum is seen as being correct, the trust for this packet is raised to 8 which is almost being oneself.

All of this is subject to change, but I said that before.

Here's an example using the not to be recommended _check_MD5:

>> .
>> =_source     psyc://
>> :_target_peer        psyc://localhost:-35384/
>> :_implementation     psyced/0.99 LDMUD/3.3.714 Linux/2.6 i686
>> :_page_description
>> _notice_circuit_established
>> Hello [_target_peer].
>> Circuit to [_source] running [_implementation] established.
>> .
:_check_MD5     7d6e1df734838b911e9bccee5aa0eeaf

I want to gain your trust.
>> :_available_characters       ISO-8859-1;ISO-8859-15;UTF-8
>> :_available_protocols        PSYC/0.9 TCP IP/4;PSYC/0.9 UDP IP/4;IRC/2;XMPP/1                                                                                                                      .0;Chatlet;Telnet;HTTP/1.0;WAP
>> :_understand_modules _context;_encrypt
>> :_using_characters   UTF-8
>> :_using_protocols    PSYC/0.9 TCP IP/4
>> :_using_modules      _context
>> _status_circuit
>> Available protocols: [_available_protocols].
>> .
>> _echo_circuit_trust
>> You have gained my trust.
>> .

The script that does this trick, then enters the storage sync and finally commands a remote controlled /set is in of perlpsyc.

See also Identification for more uses of crypto hashes in PSYC.