Monday, December 14, 2020

The cleverest floppy disc protection ever? Western Security Ltd.

Introduction

I've been on a bit of a floppy disc protection odyssey recently. This will probably be the last floppy disc related post for some time, so how better to end things than describe a stroke of genius I came across during my research of BBC Micro disc protection?

In my previous posts, we've already covered (directly or tangentially) some interesting floppy disc protection schemes:

  • Weak bits. [link: Weak bits floppy disc protection: an alternate origins story on 8-bit]. "Weak bits" protection is where a patch of disc surface is left empty of magnetic flux transitions. Absent a signal, the floppy disc drive itself will turn up the gain on its amplifier and see noise, which manifests as non-deterministic digital reads from the disc.
  • Fuzzy bits. [link: Technical Documentation - Dungeon Master and Chaos Strikes Back - Detailed analysis of Atari ST Floppy Disks]. "Fuzzy bits" protection is where magnetic flux transitions are recorded at intervals that are out-of-spec with regards to timing expectations (e.g. MFM). By using intervals right in the middle of a pair of expected values (e.g. 5us instead of the expected 4us or 6us), it's possible to cause the disc controller to return non-deterministic digital reads.
  • Long / short tracks. [link: Turning a £400 BBC Micro (1981) into a $40,000 disc writer (1987)] [see the "Capabilities Unlocked" section]. Long track protection is where flux transitions are written a little bit faster than they should be. This could be the whole track or just part of a track. In either case, the track will appear to contain more bytes than a track normally should. This works because the floppy disc controller usually has a broad tolerance of bitrate, to cater for disc drives naturally spinning at different speeds.
Now, we're going to cover something else entirely, with some unique properties that I think are clever.

Western who, now?


It's not readily possible to find any "Western Security, Ltd." company associated with the BBC Micro. So how do we know such a thing exists? Two reasons. Firstly, when developing my beebjit [link] emulator, I made numerous mistakes and had tons of bugs. While grappling with accurate floppy disc emulation -- in order to load original protected disc images -- I hit this:

Jolly Jack Tar by Sherston Software

Of course, the original author here missed out an amusing case. Either the disc is faulty (no), it's an illegal copy (not really?).... or a buggy emulator. Here's another error screen. Perhaps an earlier version of the protection scheme? The message uses "disk" instead of "disc" and does not entertain the fact the disc may be at fault:

Phantom Combat by Doctor Soft

(At the risk of digressing heavily, here's another screenshot. This is unrelated to Western Security Ltd., but follows the pattern of a dedicated screen for when the disc protected loader fails. This case is interesting because there's an entire decent image hidden from normal view!)

Disc Duplicator 3, if it thinks it's a copy

The second reason we know the name Western is from disc duplicator markers. A disc duplicator marker is a special track written by some commercial disc duplication solutions. It is typically one track after the end of the normal disc, i.e. the 41st track or 81st track of the disc. Despite being "out of bounds", most disc drives will seek at least one track out of bounds. On the track, you'll typically find a single sector header, and a sector body with a CRC error. This is an unusual construction and it sticks out, for example when my discbeast program [link] looks at the Jolly Jack Tar disc:

Discbeast's view of Jolly Jack Tar

There's a date and a text string or two embedded in the duplicator marker. The Jolly Jack Tar instance is:

86 07 01 (1986, July 1st)
523-037E        WESTERN NM,10/256 PROT DUP 5"-48/40 1S SD SS
32173-2Aw

There's one other less common duplicator marker string we see associated with Western security, for example Tens and Units by Sherston Software. It appears to be an earlier prototype version:

85 10 31 (1985, October 31st)
523-037C        BBC NM,10/256 WESTERN SEC. PROTO1 DUP 5"-48/40 1
70422-00w

A recap of disc protection fundamentals

Before diving in to how the Western Security protection works, let's recap the fundamentals of disc protection. The specifics are nuanced but the general principle is pleasantly simple:

  • The disc is easy to read but hard to write.
The disc has to be relatively easy to read. If the disc couldn't be read by standard disc controllers, you couldn't sell the disc because customers would not be able to load it!

And the correct way to make a disc hard to write is to carefully understand consumer disc controller chips and disc drives and make the disc impossible to write with standard kit.

The BBC Micro disc protection journey did not follow this route -- the earlier discs, and many of the later discs, were exotic but not particularly hard to create with the standard disc controller. But you did need a special program. The software companies had their special mastering program and the customers did not, so in a sense the disc was "hard" to write. But then, general copying programs such as Disc Duplicator 3 appeared and suddenly the discs were "easy" to write, if you or a friend had the advanced disc copying program.

However, a few BBC Micro pioneers did write discs that "can't" be written with the standard disc controller, most notably:
  • Simon Hosler's weak bits scheme, as linked above. (And here: [link].) [1]
  • Many discs, such as The Sentinel by Firebird, hid data between sectors. [2]
[1] One of a disc controller's main jobs is to write precise disc surfaces, i.e. to never write weak bits. However in the modern era I did find a way to trick the Intel 8271 controller into writing weak bits. Best I know, this technique was not discovered or used back in the day.
[2] With a bit of clever programming, I believe data between sectors could be written with standard disc controllers. It would involve writing to a track multiple times and resetting the disc controller at critical timing junctures. I've not seen any historic disc copying program that attempts to copy such discs, though.

Analyzing the Western Security Ltd. protected loader

This version of The Wizard's Revenge by Sherston Software features Western Security Ltd. disc protection.

Here's a gratuitous screenshot of the game.

And here's what discbeast makes of the disc:

There's nothing too unusual here. The red block at the end denotes a track with 1 sector that has a CRC error. It's not part of the disc protection; it's the duplicator marker. The green color represents a standard sector layout with nothing particularly exotic present. The "D" indicates the presence of deleted sectors. This is disc protection, but not exotic or hard to copy. However, loading the disc in my beebjit emulator, using the Western Digital WD1770 floppy disc controller and -log disc:commands, yields something highly unusual:

info:disc:1770: command $E4 tr 1 sr 3 dr 1 cr $29 ptrk 1 hpos 1884

Command $E4 is "read track". It is not used in the normal operation of disc loading, or indeed in any other known protected loaders.
It's time to walk through the loader a little to see what is going on. The goal of this post is not to give a detailed walk through of all the gnarly corners of the loader. Like many protected loaders, it is "encrypted" or more accurately, obfuscated. It de-obfuscates itself using many layers of self-modification. At PC $0657, a disc call is set up to load a bit more of the loader from deleted sectors in track 9. This could easily be confused as being the extent of the protection, but it is not. Later, at PC $3CF7, there is a loop:

[ITRP] 3CF7: JSR $3D16
[ITRP] 3CFA: LDA $75
[ITRP] 3CFC: SEC
[ITRP] 3CFD: SBC $3F4E
[ITRP] 3D00: TAX
[ITRP] 3D01: LDA $86
[ITRP] 3D03: STA $3F71,X
[ITRP] 3D06: INC $75
[ITRP] 3D08: LDA $3F4F
[ITRP] 3D0B: CMP $75
[ITRP] 3D0D: BCS $3CF7

It's not expected to be clear from this fragment alone (without all the subroutines), but what is going on here is a loop across tracks 1-8 inclusive. For each track, it is read fully and the length of the track is stored in a table at $3F71. Later, at PC $3CB6, these lengths are checked against a table located at $3D9B. The check is particularly interesting. For the copy protection to pass, a count is taken of each track length that falls within +-1 of the expectation, and this count must be 7 or 8. Immediately we see that this protection is not a precise technology. This is to be expected: discs are analog storage mediums underneath it all and there will be a bit of noise at the beginning or end of the track. From read-to-read, the same disc, drive and controller can and does see slight variations of track length. Looking at the load in beebjit, here are the encountered vs. expected lengths. (0x4A == 3122 bytes.)

My captured disc
3F71: 4A 4D 4B 4A 4B 4D 4D 4A
Expectations
3D9B: 4A 4C 4B 4A 4B 4D 4C 4A

As can be seen, my disc reads almost exactly to expectations except track 2, which was 3125 bytes instead of the expected 3124. That's within the +-1 range so all 8 tracks pass the check (7 or more are required).

To spell it out, the protected loader expects the track length (in FM encoded bytes) for tracks 1-8 inclusive to be 3122, 3124, 3123, 3122, 3123, 3124, 3123, 3122. That's an incredible level of precision and accuracy of writing for 1985 technology. Each byte covers about 64us on a spinning disc, but disc drives of the era would often specify running RPM variation of "less than +-1.5%". At 300rpm, +-1.5% is +-3ms per rotation! In my experience, drives are much much better than that but still! How did 1985 technology cope??

One further note, on the WD1770 vs. Intel 8271 disc controllers. We've focused our analysis on the protection as seen by the WD1770. This disc also loads fine with an Intel 8271 controller. It uses a completely different code path to indirectly calculate track length in this case. It works because the padding bytes up to the end of the track are all 0x00 instead of the usual 0xFF. An "over-read" past the final sector on the track is used, and track length is detected by the change from reading 0x00 to 0xFF.

The genius twist

And then we realize the genius of this scheme. What if they didn't write the tracks with extreme precision, because the technology wasn't there? What if they just wrote the track any-old-how and then examined the result? I think this what they did:

  • Format the disc. (That's it. Just format the disc normally and you've created a fiendishly protected disc.)
  • Read the lengths of tracks 1-8 of the disc you just wrote.
  • On a per-disc basis, generate, obfuscate and write the required table of expected track lengths into the loader on track 9.
What a trick! These discs are savagely hard to copy, even with dedicated hardware of the era. In fact, this trick is so clever that it requires us to revisit the fundamentals of disc protection. Here's our earlier statement:

  • The disc is easy to read but hard to write.
But the Western Security Ltd. protection is quite easy to write -- you just format a disc. So perhaps we should say:
  • The disc is easy to read but hard to recreate.
The Western Security protection is easy to write, easy to read but very hard to copy. One of the advantages of such a protection is that you could use a home computer to write it cheaply if the economics worked for you. That said, many discs I've seen appear to have duplicator markers typically found with expensive disc duplicating machines.

How can we support our theory? One way is to find a second disc of the same title, The Wizard's Revenge, and see if it differs at all. I did find one, and it does. My disc as per above:

Track 0 sectors 10 length 3124 fixups 1 CRC32 2E6B86E9
Track 1 sectors 10 length 3122 fixups 0 CRC32 37E30EC8
Track 2 sectors 10 length 3125 fixups 1 CRC32 F7BDE89B
Track 3 sectors 10 length 3123 fixups 0 CRC32 BB1E32C3
Track 4 sectors 10 length 3122 fixups 1 CRC32 2EC84AF1
Track 5 sectors 10 length 3123 fixups 0 CRC32 58FD732B
Track 6 sectors 10 length 3125 fixups 0 CRC32 43416F5A
Track 7 sectors 10 length 3125 fixups 1 CRC32 B3D8AB10
Track 8 sectors 10 length 3122 fixups 1 CRC32 8D02AC32
Track 9 sectors 10 length 3125 fixups 1 CRC32 75B1F57B
Track 10 sectors 10 length 3123 fixups 1 CRC32 D2B0A1EF
[...]

Additional captured disc:

Track 0 sectors 10 length 3126 fixups 1 CRC32 2E6B86E9
Track 1 sectors 10 length 3129 fixups 1 CRC32 37E30EC8
Track 2 sectors 10 length 3127 fixups 1 CRC32 F7BDE89B
Track 3 sectors 10 length 3127 fixups 1 CRC32 BB1E32C3
Track 4 sectors 10 length 3127 fixups 1 CRC32 2EC84AF1
Track 5 sectors 10 length 3129 fixups 1 CRC32 58FD732B
Track 6 sectors 10 length 3129 fixups 1 CRC32 43416F5A
Track 7 sectors 10 length 3128 fixups 1 CRC32 B3D8AB10
Track 8 sectors 10 length 3128 fixups 1 CRC32 8D02AC32
Track 9 sectors 10 length 3127 fixups 1 CRC32 1F5ABD44
Track 10 sectors 10 length 3128 fixups 0 CRC32 D2B0A1EF
[...]

As can be seen, the sector data (covered by the CRC32s) of the discs is the same except for track 9, which is where the table of expected track lengths resides. And the track lengths themselves are different. In both cases there's track length wobble and in the case of the latter discs, the tracks are all a little longer. This means that the drive that formatted the disc was running at a slightly slower RPM, enabling more bytes to be written in a single revolution.

And there's a second way to support the theory. I just asked Simon Hosler, who wrote a lot of Sherston Software games back in the 1980s, if he remembered anything. He recalls,

"Western Security –  this wasn’t my system but I think it worked like this... It works because each disk drive runs at slightly different speeds. So when a drive creates a track on the disk – after it has added all of the headers and sectors etc, it has a bit of space to fill up, so adds a few extra ‘fill in’ bits that do nothing. The number of fill in bits will depend on the exact speed of the original formatting drive. So will be different if it was copied. I remember this system became a pain because disk drives were changing (?) all the time. [...] the system was called 'Fingerprinting'"

There remains the mystery of how a commercial duplicator could handle making these discs. One thing I've come across is references to a "Freeform" script [link], used in conjunction with Trace duplicators. I haven't been able to find a manual for this scripting language. There are some strange fragments in the memory of the loader after de-obfuscation; could it be related?

3F80: 54 70 00 41 44 44 20 20 20 20 20 72 00 4D 4F 56  Tp.ADD     r.MOV
3F90: 45 54 4F 20 20 74 00 55 4E 49 54 20 20 20 20 75  ETO  t.UNIT    u
3FA0: 00 54 52 41 43 4B 20 20 20 76 00 53 45 43 54 4F  .TRACK   v.SECTO
3FB0: 52 20 20 77 00 54 4F 50 54 52 41 43 4B 78 00 55  R  w.TOPTRACKx.U

Recreating Western Security style protected discs

I happen to have a couple of very different disc drives, so I thought I'd try them out. I formatted a disc in each drive, then had a look at the track lengths (in bytes) read back by a WD1772 disc controller in a real BBC Micro model B.

Contender #1: my Chinon F-051MD drive. It is older, 40 track and single-sided only. The pinch-to-close style door mechanism later fell out of fashion (was it less reliable?). Another way to date this is the large DIP-style main chip, a NEC D8048 which is an Intel 8048 clone! (There's a ROM here to extract one day!)

Contender #2: not my Mitsuibish MF504C, but pretty similar. A much newer drive, 80 track and double sided. Notice the newer chips, cleaner wiring and simpler clamp mechanism. Not visible, but it also has a smaller (next gen?) stepper motor.

Track lengths from Chinon F-051MD:

[...]
Track 1 sectors 10 length 3137 fixups 1 CRC32 67F0950E
Track 2 sectors 10 length 3138 fixups 1 CRC32 67F0950E
Track 3 sectors 10 length 3138 fixups 1 CRC32 67F0950E
Track 4 sectors 10 length 3139 fixups 1 CRC32 67F0950E
Track 5 sectors 10 length 3138 fixups 1 CRC32 67F0950E
Track 6 sectors 10 length 3140 fixups 1 CRC32 67F0950E
Track 7 sectors 10 length 3140 fixups 1 CRC32 67F0950E
Track 8 sectors 10 length 3139 fixups 1 CRC32 67F0950E
Track 9 sectors 10 length 3140 fixups 1 CRC32 67F0950E
Track 10 sectors 10 length 3140 fixups 1 CRC32 67F0950E
[...]

Track lengths from Mitsubishi MF504C:

[...]
Track 1 sectors 10 length 3119 fixups 1 CRC32 67F0950E
Track 2 sectors 10 length 3119 fixups 1 CRC32 67F0950E
Track 3 sectors 10 length 3118 fixups 0 CRC32 67F0950E
Track 4 sectors 10 length 3119 fixups 1 CRC32 67F0950E
Track 5 sectors 10 length 3119 fixups 1 CRC32 67F0950E
Track 6 sectors 10 length 3119 fixups 1 CRC32 67F0950E
Track 7 sectors 10 length 3119 fixups 1 CRC32 67F0950E
Track 8 sectors 10 length 3119 fixups 1 CRC32 67F0950E
Track 9 sectors 10 length 3118 fixups 1 CRC32 67F0950E
Track 10 sectors 10 length 3119 fixups 1 CRC32 67F0950E
[...]

These two drives definitely have unique fingerprints! The older drive has a bit more variance / wobble in individual track lengths. In fact, it seems to fit more bytes per track on the later sectors -- most of the latter tracks are length 3142. The older drive also generally fits 20 or so more bytes per track. This means it is spinning a little slower. By contrast, the newer drive runs like clockwork with minimal track-to-track variance. This might make it a little less suitable for generating varied per-disc fingerprints, but copying the disc on home computing hardware would still be tricky -- the machine used would need to have a similarly precise drive, and the drive would also need to be running at the exact same speed as the drive that made the original disc.

One last look at track lengths, this time from a Phantom Combat game disc, by Doctor Soft. This disc uses Western Security Ltd. protection:

Nothing quite says "we overcooked the disc protection" like a warning sticker about compatibility (left, middle). The sticker states that only Acorn disc ROMs are supported. Unfortunately, non-Acorn disc ROMs were extremely common.

[...]
Track 1 sectors 10 length 3152 fixups 0 CRC32 67F0950E
Track 2 sectors 10 length 3152 fixups 1 CRC32 67F0950E
Track 3 sectors 10 length 3152 fixups 0 CRC32 67F0950E
Track 4 sectors 10 length 3152 fixups 1 CRC32 67F0950E
Track 5 sectors 10 length 3151 fixups 0 CRC32 67F0950E
Track 6 sectors 10 length 3152 fixups 0 CRC32 67F0950E
Track 7 sectors 10 length 3150 fixups 0 CRC32 67F0950E
Track 8 sectors 10 length 3151 fixups 0 CRC32 67F0950E
[...]

This is disc protection hidden in plain sight. These 8 protected tracks are in fact 100% default format tracks (CRC32 67F0950E). There's the correct number of sectors and there are no deleted sectors. discbeast would show these tracks as plain green, aka. move on, nothing to see here!
There's a bit of track length wobble from track to track, but the tracks are also unusually long (the ideal is 3125 bytes). It is not clear whether the tracks were deliberately laid down a little long, but it definitely helps the disc protection. Any disc drive used to attempt to re-create these tracks is unlikely to be spinning at that speed because it is 0.8% slow and the disc drive motor technology is generally better than that. It's interesting to note that simple long track protection is just another variant in the Western Security scheme.
This disc was probably written from a BBC Micro itself, rather than a fancy duplication machine, as evidenced by the lack of a duplicator marker and by the fact the game data sectors show evidence of being written sector-at-a-time, not track-at-a-time. Who knows, maybe there was a deliberate attempt to find a slow drive; some older drives even have a twiddleable variable resistor to vary motor speed.

Conclusion


We've reviewed the most powerful BBC Micro model B disc protection scheme I found, across an audit of most of the copy protected discs released for the machine. It's clever in that you don't need specialized hardware to create the disc, or read the disc. But you're going to struggle to duplicate the disc.
My suspicion is that even modern hardware -- a Greaseweazle perhaps -- might struggle to hit byte-perfect precision, unless it is paired with a high quality disc drive that rotates very consistently (such as my Mitsubishi MF504C).
Talking again to Simon, as far as he's aware, this was the work of George Keeling, who I'd love to contact if only to tell him I think this work was awesome.