Harlequin RIP SDK

Example implementation of the font decoder and encoder filter. If you wish to just test font decoding, define TEST_DECRYPTFONT instead. There are two encryption algorithms supported, to show how to implement multiple strategies. More...

#include "skinkit.h"
#include "ripthread.h"
#include "swdevice.h"
#include "skindevs.h"
#include "devutils.h"
#include <string.h>

Data Structures

struct  _fND_state
 Encapsulates the current state of the font encoder/decoder device. More...
 

Macros

#define ADLER32_BASE   65521
 Modulus for the Adler 32 algorithm.
 

Typedefs

typedef struct _fND_state FND_STATE
 Encapsulates the current state of the font encoder/decoder device.
 

Functions

static uint32 calculateAdler32 (uint8 *byteptr, int32 count, uint16 *s1, uint16 *s2)
 Calculate an Adler32 checksum, similar to the Flate standard. This is used in the path "encryption" to supply a checksum based upon the path string. See the comments above about security of the encryption filter.
 
static int32 FDread (FND_STATE *pState)
 Called from FDGetc when needs more data.
 

Variables

DEVICETYPE FontNDcrypt_Device_Type
 Encapsulates the set of entry points for the font encoder/decoder device.
 

Detailed Description

Example implementation of the font decoder and encoder filter. If you wish to just test font decoding, define TEST_DECRYPTFONT instead. There are two encryption algorithms supported, to show how to implement multiple strategies.

Implementing the encryption filter as the straight inverse of the decryption filter is not secure; it is very vulnerable to chosen plaintext attacks. The path provided by HDLT is a binary encoded userpath; the protection attribute is a combination of all of the protection methods used in constructing the path. If an unprotected path is created, and a charpath from a protected font is added to the path, the whole path will be exported using the protected font's methods. The initial parts of the binary encoded path will be known to the attacker (they are the unprotected part of the path), and this can be exploited to break the encryption method.

Do NOT implement a pass-through write_file routine here under any circumstances, it'll make your font data insecure. It must either encrypt the data it sees securely or return an error. Checking the openflags on your open call and faulting any call which is not SW_RDONLY would be best.

The encryption here is a better example of how to keep your encryption algorithm secure. It demonstrates one half of a method that works in a closed environment. The path supplied to the encryption filter should be stored by the filter, which return the results of a secure hash function applied to the path. The client code can pass the hash value to consumers, who then communicate with the font encryption filter to retrieve the path.

Note that encoded userpaths consist of two parts, the arguments and the commands, so in such a case storing two strings under one hash value would be useful.

The example "encryption" in this file actually adds a header revealing the strategy used, and then outputs a checksum of the string.

The following code is the decryption algorithm in that we're testing for:

void encrypt_string_algorithm1( slist, slen )
{
int32 xorchar = 0x00;
while ((--slen) >= 0 ) {
slist[ 0 ] ^= xorchar;
xorchar += slist[ 0 ];
slist++;
}
}
void encrypt_string_algorithm2( slist, slen )
{
int32 xorchar = 0x00;
while ((--slen) >= 0 ) {
slist[ 0 ] ^= xorchar;
xorchar += slist[ 0 ];
xorchar += 0x10;
slist++;
}
}
int32_t int32
32-bit signed integer
Definition: hqtypes.h:91

These encryptions cannot be pre-verified, so the code here will not return DeviceIOError to say "this isn't in my code," most most other features of the filter will be exercised.