Disoriented Canadian moose after drinking two Belgian beers


The mysterious Linotype table

Upon close inspection of some truetype and opentype fonts made by Linotype, we found that the most recent implementations had an extra table not listed in the specs. It is simply called LINO.

We have long ago speculated that fontmakers would put information on buyers or serial numbers inside fonts, and this may well be (and probably is) an example of such practice. It is not inconceivable that one day, some applications may attempt to send information contained in the fonts that are used or merely stored back to the factory via the internet, together with, say, an IP number.

This page explains how to detect these tables (warning: for hackers only!), and how to deal with them (if you do not want the intrusion of privacy).

The LINO table is not to be confused with the standard DSIG or digital signature table, which basically serves the following purpose (taken from the Microsoft document): Operating systems and browsing applications can identify the source and integrity of font files before using them. Font developers can specify embedding restrictions in OpenType fonts, and these restrictions cannot be altered in a font signed by the developer. [...] Windows will soon require installed software components, including fonts, to be signed. Internet browsers will also give users and administrators the ability to screen out unsigned objects obtained on-line, including web pages, fonts, graphics, and software components. The DSIG table is usually the last one in a font, so it too can be dealt with quite easily.



With the aid of a hexadecimal dumper or a binary file reader, one can inspect the contents of a raw truetype or opentype file. On UNIX/Linux, I use hexdump -C, a free utility, to create human-readable versions of binary files. There are others. Below are selected lines from the top and the body of several Linotype fonts.



First font (opentype)

00000000  4f 54 54 4f 00 0d 00 80  00 03 00 50 43 46 46 20  |OTTO.......PCFF |
00000010  b4 e0 99 0d 00 00 00 dc  00 00 75 cb 44 53 49 47  |..........u.DSIG|
00000020  7e fa cb f0 00 00 fe 04  00 00 16 f8 47 50 4f 53  |~...........GPOS|
00000030  96 a2 b7 ec 00 00 76 a8  00 00 3c 28 47 53 55 42  |......v...<(GSUB|
00000040  c7 11 45 b7 00 00 b2 d0  00 00 1c ac 4c 49 4e 4f  |..E.........LINO|
00000050  10 cf 12 94 00 00 cf 7c  00 00 01 08 4f 53 2f 32  |.......|....OS/2|
00000060  87 21 4a cf 00 00 d0 84  00 00 00 60 63 6d 61 70  |.!J........`cmap|
00000070  ed bf 19 1d 00 00 d0 e4  00 00 03 94 68 65 61 64  |............head|
00000080  e2 cf 6b 1b 00 00 d4 78  00 00 00 36 68 68 65 61  |..k....x...6hhea|
00000090  06 c1 04 5a 00 00 d4 b0  00 00 00 24 68 6d 74 78  |...Z.......$hmtx|
000000a0  71 2d 6a be 00 00 d4 d4  00 00 08 a8 6d 61 78 70  |q-j.........maxp|
000000b0  02 2a 50 00 00 00 dd 7c  00 00 00 06 6e 61 6d 65  |.*P....|....name|
000000c0  04 9d 5f 11 00 00 dd 84  00 00 20 5e 70 6f 73 74  |.._....... ^post|
...
0000cf70  01 8f 01 93 01 9b 01 fb  01 fd 02 23 00 e0 33 35  |...........#..35|
0000cf80  33 37 33 30 33 32 32 64  33 33 33 35 33 33 33 33  |3730322d33353333|
0000cf90  33 37 33 33 33 36 32 64  33 31 33 33 33 35 33 30  |3733362d31333530|
0000cfa0  33 33 32 64 33 32 33 34  33 31 33 32 20 20 20 20  |332d32343132    |
0000cfb0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
...
0000d050  20 20 20 20 20 20 20 20  20 20 20 20 20 20 00 24  |              .$|
0000d060  34 31 35 44 44 35 34 34  43 36 43 42 42 41 45 31  |415DD544C6CBBAE1|
0000d070  41 42 39 30 41 45 42 38  37 37 46 33 39 39 31 42  |AB90AEB877F3991B|
0000d080  46 39 44 33 00 02 02 0d  01 90 00 05 00 04 02 8a  |F9D3............|

Second font (truetype)

00000000  00 01 00 00 00 13 01 00  00 04 00 30 4c 49 4e 4f  |...........0LINO|
00000010  f3 16 e2 50 00 00 01 3c  00 00 01 08 4c 54 53 48  |...P...<....LTSH|
00000020  2b 83 98 9e 00 00 02 44  00 00 00 eb 4f 53 2f 32  |+......D....OS/2|
00000030  61 13 d6 36 00 00 03 30  00 00 00 56 56 44 4d 58  |a..6...0...VVDMX|
00000040  72 6c 79 e9 00 00 03 88  00 00 05 e0 63 6d 61 70  |rly.........cmap|
00000050  6b 71 0f 37 00 00 09 68  00 00 03 3a 63 76 74 20  |kq.7...h...:cvt |
00000060  01 77 0a 5f 00 00 0c a4  00 00 00 26 66 70 67 6d  |.w._.......&fpgm|
00000070  32 4d 73 66 00 00 0c cc  00 00 01 62 67 61 73 70  |2Msf.......bgasp|
00000080  00 17 00 09 00 00 0e 30  00 00 00 10 67 6c 79 66  |.......0....glyf|
00000090  b1 f7 7d 0e 00 00 0e 40  00 00 98 10 68 64 6d 78  |..}....@....hdmx|
000000a0  78 ca f2 ea 00 00 a6 50  00 00 15 3c 68 65 61 64  |x......P....head|
000000b0  d3 8a 3e 94 00 00 bb 8c  00 00 00 36 68 68 65 61  |..>........6hhea|
000000c0  03 92 04 bd 00 00 bb c4  00 00 00 24 68 6d 74 78  |...........$hmtx|
000000d0  ee e6 1b 09 00 00 bb e8  00 00 03 9c 6b 65 72 6e  |............kern|
000000e0  0a 58 0a 22 00 00 bf 84  00 00 02 58 6c 6f 63 61  |.X.".......Xloca|
000000f0  02 98 29 09 00 00 c1 dc  00 00 01 d0 6d 61 78 70  |..).........maxp|
00000100  02 ff 02 98 00 00 c3 ac  00 00 00 20 6e 61 6d 65  |........... name|
00000110  4f 95 7f cf 00 00 c3 cc  00 00 2a 90 70 6f 73 74  |O.........*.post|
00000120  da 50 af 54 00 00 ee 5c  00 00 02 0b 70 72 65 70  |.P.T...\....prep|
00000130  71 0e 68 30 00 00 f0 68  00 00 00 68 00 e0 33 35  |q.h0...h...h..35|
00000140  33 37 33 30 33 32 32 64  33 31 33 33 33 38 33 34  |3730322d31333834|
00000150  33 33 33 38 33 36 32 64  33 35 33 31 33 32 33 30  |3338362d35313230|
00000160  32 64 33 31 33 33 33 30  33 32 20 20 20 20 20 20  |2d31333032      |
00000170  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
...
00000210  20 20 20 20 20 20 20 20  20 20 20 20 20 20 00 24  |              .$|
00000220  37 46 34 35 36 43 32 44  42 35 35 45 32 31 44 31  |7F456C2DB55E21D1|
00000230  42 32 44 35 43 42 33 38  38 36 36 33 46 44 44 36  |B2D5CB388663FDD6|
00000240  34 45 39 39 00 00 00 e7  01 44 01 01 4c 4c 01 37  |4E99.....D..LL.7|

Third font (truetype)

00000000  00 01 00 00 00 12 01 00  00 04 00 20 4c 49 4e 4f  |........... LINO|
00000010  c6 ab d6 65 00 00 01 2c  00 00 00 e2 4c 54 53 48  |...e...,....LTSH|
00000020  8d 2e 61 ef 00 00 02 10  00 00 00 eb 4f 53 2f 32  |..a.........OS/2|
00000030  60 11 f3 0b 00 00 02 fc  00 00 00 56 63 6d 61 70  |`..........Vcmap|
00000040  5f 47 13 aa 00 00 03 54  00 00 03 2e 63 76 74 20  |_G.....T....cvt |
00000050  01 12 09 16 00 00 06 84  00 00 00 22 66 70 67 6d  |..........."fpgm|
00000060  32 4d 73 66 00 00 06 a8  00 00 01 62 67 61 73 70  |2Msf.......bgasp|
00000070  00 07 00 07 00 00 08 0c  00 00 00 0c 67 6c 79 66  |............glyf|
00000080  4f 7a 67 96 00 00 08 18  00 00 f5 bc 68 64 6d 78  |Ozg.........hdmx|
00000090  b1 58 80 41 00 00 fd d4  00 00 15 3c 68 65 61 64  |.X.A........head|
000000a0  96 7f de be 00 01 13 10  00 00 00 36 68 68 65 61  |...........6hhea|
000000b0  07 22 03 30 00 01 13 48  00 00 00 24 68 6d 74 78  |.".0...H...$hmtx|
000000c0  a2 67 26 b3 00 01 13 6c  00 00 03 9c 6b 65 72 6e  |.g&....l....kern|
000000d0  0a 6b 0a 1d 00 01 17 08  00 00 02 16 6c 6f 63 61  |.k..........loca|
000000e0  b3 af f3 12 00 01 19 20  00 00 01 d0 6d 61 78 70  |....... ....maxp|
000000f0  02 f9 03 13 00 01 1a f0  00 00 00 20 6e 61 6d 65  |........... name|
00000100  ac 97 49 32 00 01 1b 10  00 00 0e d8 70 6f 73 74  |..I2........post|
00000110  d9 b3 b0 9c 00 01 29 e8  00 00 02 0b 70 72 65 70  |......).....prep|
00000120  ff 0f 3e 2f 00 01 2b f4  00 00 00 68 00 e0 33 35  |..>/..+....h..35|
00000130  33 37 33 30 33 32 32 64  33 32 33 34 33 37 33 32  |3730322d32343732|
00000140  33 30 33 36 33 36 32 64  33 34 33 35 33 34 33 32  |3036362d34353432|
00000150  33 34 32 64 33 30 33 31  20 20 20 20 20 20 20 20  |342d3031        |
00000160  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
...
00000200  20 20 20 20 20 20 20 20  20 20 20 20 20 20 00 00  |              ..|

Fourth font (opentype)

00000000  4f 54 54 4f 00 0d 00 80  00 03 00 50 43 46 46 20  |OTTO.......PCFF |
00000010  2e 52 51 87 00 00 00 dc  00 00 6b 28 44 53 49 47  |.RQ.......k(DSIG|
00000020  e7 da 31 af 00 00 92 bc  00 00 14 c0 47 50 4f 53  |..1.........GPOS|
00000030  31 0c 40 a1 00 00 6c 04  00 00 0f d2 47 53 55 42  |1.@...l.....GSUB|
00000040  fe 14 00 62 00 00 7b d8  00 00 03 7a 4c 49 4e 4f  |...b..{....zLINO|
00000050  de e7 d2 1c 00 00 7f 54  00 00 00 48 4f 53 2f 32  |.......T...HOS/2|
00000060  86 16 36 c8 00 00 7f 9c  00 00 00 60 63 6d 61 70  |..6........`cmap|
00000070  04 c2 5e 5c 00 00 7f fc  00 00 02 f8 68 65 61 64  |..^\........head|
00000080  da 57 75 f1 00 00 82 f4  00 00 00 36 68 68 65 61  |.Wu........6hhea|
00000090  05 6f 05 64 00 00 83 2c  00 00 00 24 68 6d 74 78  |.o.d...,...$hmtx|
000000a0  1b 2b fd ef 00 00 83 50  00 00 03 b4 6d 61 78 70  |.+.....P....maxp|
000000b0  00 ed 50 00 00 00 87 04  00 00 00 06 6e 61 6d 65  |..P.........name|
000000c0  c5 12 6c cc 00 00 87 0c  00 00 0b 8d 70 6f 73 74  |..l.........post|
...
00007f50  00 dd 00 00 00 00 00 44  32 30 37 36 38 36 34 34  |.......D20768644|
00007f60  33 45 36 46 41 39 39 32  37 39 43 39 46 34 30 35  |3E6FA99279C9F405|
00007f70  45 46 39 38 37 31 36 36  41 44 30 37 42 31 41 33  |EF987166AD07B1A3|
00007f80  42 38 43 42 34 35 34 34  38 42 39 34 38 34 34 45  |B8CB45448B94844E|
00007f90  37 39 43 39 31 46 39 44  33 45 41 44 00 02 01 31  |79C91F9D3EAD...1|

The leftmost column refers to the place in the file in hexadecimal notation, a byte count from the start of the file. The rightmost column has a text interpretation of the bytes in the file, if this makes sense. In each example, the tables of the ttf or otf files are listed near the top of the file. One recognizes the common names such as cmap, head, hhea, glyf, hmtx, name, post, maxp, GSUB, GPOS, kern, and gasp. But there is also a Linotype-specific table, LINO. For example, in the last font, LINO is found in the line starting with 00000040. Now go to the next line and read bytes numbers 5 through 8, in this case, 00 00 7f 54, or without spaces, 00007f54. That is the address of the LINO table.

Proceed to that line in the file, and locate the start of the table at that address. We find the bytes starting with 00 00 00 44 32 30 37 36 38 36 34 34 and this continues until the next table which starts at position 00007f9c. The text found there thus is


            00 00 00 44  32 30 37 36 38 36 34 34  |.......D20768644|
33 45 36 46 41 39 39 32  37 39 43 39 46 34 30 35  |3E6FA99279C9F405|
45 46 39 38 37 31 36 36  41 44 30 37 42 31 41 33  |EF987166AD07B1A3|
42 38 43 42 34 35 34 34  38 42 39 34 38 34 34 45  |B8CB45448B94844E|
37 39 43 39 31 46 39 44  33 45 41 44              |79C91F9D3EAD...1|

The string hidden in the table is


D207686443E6FA99279C9F405EF987166AD07B1A3B8CB45448B94844E79C91F9D3EAD

Using a similar method, one can easily find the strings in the other fonts as well (an exercise!).



There are essentially three measures to protect your privacy.

  • (The easiest.) Rename the table to something else, so it becomes unrecognizable. That is, replace the word LINO in the listing of the tables by a 4-letter word of your choice (but not the name of a standard table). You could name it JOHN, JACK or JILL. Most of you know even better words of four letters. Use a standard text editor for this.
  • (The meanest.) Keep the table but erase the information in it. You will need a binary file editor and a cool head. Try setting all the bytes in the table to 00 or 20. In the example above, this would yield something like
    
                00 00 00 00  00 00 00 00 00 00 00 00  |................|
    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    00 00 00 00 00 00 00 00  00 00 00 00              |...............1|
    
  • (The toughest.) Get rid of the table altogether. This can be done in a font editor such as FontForge or FontLab, but beware: importing a font into an editor and then exporting it cleans the font of unrecognized tables and, unfortunately, of some other tables as well. Old versions of FontForge, for example, remove the kerning table. To do this cleanly, one should write a program that disassembles the font into its component tables and then reassembles all of them without the LINO table. Perl would be a good language for such an undertaking. Just Van Rossum's program TTX can be used for this purpose.

In all of the above solutions, the checksum in the head table may become incorrect. Most applications do not care, but some might. In that case, additional coding will be required.

And finally, remember that altering fonts is not allowed in most licenses!



Contact

Luc Devroye
School of Computer Science
McGill University
Montreal, Canada H3A 2K6
luc@cs.mcgill.ca
http://luc.devroye.org/index.html