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. | |
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:
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.