9

I just reverse engineered the file protection on the Amstrad CPC, which uses two sequences of rotating bytes taken straight out of the AMSDOS ROM to XOR each byte of the file.

If you have SEQa of 13 bytes and SEQb of 11 bytes, the first byte of the file is XOR'd with SEQa[0] and SEQb[0], the next byte with SEQa[1] and SEQb[1] and so on. When each sequence ends, it starts at the beginning again, e.g.:

10: SEQa[10] XOR SEQb[10]
11: SEQa[11] XOR SEQb[0]
12: SEQa[12] XOR SEQb[1]
13: SEQa[0] XOR SEQb[2]

There are a number of obvious problems, such as the same process both encoding and decoding the input, the way ROT13 is self-reversible. The pattern is truncated at 128 bytes instead of using the full 143 bytes of the pattern. The same XOR mask is used every 128 bytes, making it easy to naïvely decode it with a 128 byte pattern without needing knowledge of the underlying method.

If it wasn't so easy to reverse engineer and the bytes were unknown instead of being taken from the AMSDOS ROM, would this scheme be considered secure in 1985? How does this compare to using a single sequence of 143 bytes or a largish prime number?

  • Is that the file protection of a particular program? Otherwise it sounds like a Viginere cypher? – Tommy Jul 30 '17 at 13:07
  • 1
    @Tommy It is the file protection of AMSDOS. When you load a protected file, it will run once and then delete itself from memory, preventing you from viewing its contents or editing it. – CJ Dennis Jul 30 '17 at 13:08
  • 4
    @Tommy It was mostly used for BASIC programs which were tokenised in memory. You could probably do frequency analysis to work out that maybe the token for "PRINT" was more common than most other tokens, etc. Each line is zero terminated, so that could be another weakness, especially if you know the average line length after tokenisation. – CJ Dennis Jul 30 '17 at 13:51
  • 2
    The fact that the same algorithm can be used for both encryption and decryption is not a weakness in the algorithm. Most stream ciphers work that way. The weakness is that "pseudo-random sequence" generated from the key and XORed with the plaintext/ciphertext is always the same. (A bigger weakness though is that key is stored in ROM and easily obtainable. Even an otherwise properly used modern and secure cipher like ChaCha would be vulnerable to a gaping hole like this.) – Ross Ridge Jul 30 '17 at 17:57
  • 1
    Enigma is way more secure than that... – mimo Aug 12 '17 at 23:15
11

Secure? No, but much more so than protected BASIC programmes on tape, which merely had a single field set in the tape header that triggered the run once then NEW behaviour. It would definitely have slowed down most bedroom crackers, but if you had a sector editor, a printer and a good eye for detail, you could probably work it out quite quickly. As Ken has said, you only need the byte sequence, you don't need to know the source.

As a quick demo of how one might retrieve the key, consider the following BASIC programme:

10 REM 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
20 REM 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
30 END

(that is, several lines of REM statements of maximum length, all holding the same byte value)

The first 512 bytes of this programme when saved look like:

00000000: 0050 524f 542d 4220 2042 4153 0000 0000  .PROT-B  BAS....
00000010: 0000 0000 0070 0100 0602 0000 0000 0000  .....p..........
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0602 004b 031e 0098 0000 001a 4220 2024  ...K........B  $
00000050: 2424 ff00 ff00 0000 0000 0000 0000 0000  $$..............
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: ff00 0a00 c520 3030 3030 3030 3030 3030  ..... 0000000000
00000090: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000000a0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000000b0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000000c0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000000d0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000000e0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000000f0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000100: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000110: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000120: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000130: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000140: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000150: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000160: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000170: 3030 3030 3030 3030 3030 3030 3030 00ff  00000000000000..
00000180: 0014 00c5 2030 3030 3030 3030 3030 3030  .... 00000000000
00000190: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000001a0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000001b0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000001c0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000001d0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000001e0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
000001f0: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000

When saved via SAVE "PROT-P.BAS",P they look like:

00000000: 0050 524f 542d 5020 2042 4153 0000 0000  .PROT-P  BAS....
00000010: 0000 0100 0070 0100 0602 0000 0000 0000  .....p..........
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0602 005a 03b5 2c75 ea6c 3725 3030 3030  ...Z..,u.l7%0000
00000050: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000060: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000070: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000080: 542c e7ea a917 0fdc abef 4a3c 0be4 5dc5  T,........J<..].
00000090: 3474 3321 ef69 bf11 434a fcb3 ed00 5a00  4t3!.i..CJ....Z.
000000a0: e3bf 32c0 505b a4d4 87c3 3398 50b8 c073  ..2.P[....3.P..s
000000b0: d8be 7390 fab4 0163 c32f f9d8 9df0 8a5d  ..s....c./.....]
000000c0: a338 e45a 1c82 3717 f0a9 deb9 9ff3 639b  .8.Z..7.......c.
000000d0: 1b04 6c1f 23de 9a1c e9c4 8c22 83f5 2c58  ..l.#......"..,X
000000e0: 3110 1cca 4796 8594 ccab c102 6bf3 4047  1...G.......k.@G
000000f0: b506 8e6b bcf8 85f2 c03b a83f 06ad e8a6  ...k.....;.?....
00000100: 9b1c ddda 5c07 0fdc abef 4a3c 0be4 5dc5  ....\.....J<..].
00000110: 3474 3321 ef69 bf11 434a fcb3 ed00 5a00  4t3!.i..CJ....Z.
00000120: e3bf 32c0 505b a4d4 87c3 3398 50b8 c073  ..2.P[....3.P..s
00000130: d8be 7390 fab4 0163 c32f f9d8 9df0 8a5d  ..s....c./.....]
00000140: a338 e45a 1c82 3717 f0a9 deb9 9ff3 639b  .8.Z..7.......c.
00000150: 1b04 6c1f 23de 9a1c e9c4 8c22 83f5 2c58  ..l.#......"..,X
00000160: 3110 1cca 4796 8594 ccab c102 6bf3 4047  1...G.......k.@G
00000170: b506 8e6b bcf8 85f2 c03b a83f 06ad d869  ...k.....;.?...i
00000180: ab38 ed2f 4c07 0fdc abef 4a3c 0be4 5dc5  .8./L.....J<..].
00000190: 3474 3321 ef69 bf11 434a fcb3 ed00 5a00  4t3!.i..CJ....Z.
000001a0: e3bf 32c0 505b a4d4 87c3 3398 50b8 c073  ..2.P[....3.P..s
000001b0: d8be 7390 fab4 0163 c32f f9d8 9df0 8a5d  ..s....c./.....]
000001c0: a338 e45a 1c82 3717 f0a9 deb9 9ff3 639b  .8.Z..7.......c.
000001d0: 1b04 6c1f 23de 9a1c e9c4 8c22 83f5 2c58  ..l.#......"..,X
000001e0: 3110 1cca 4796 8594 ccab c102 6bf3 4047  1...G.......k.@G
000001f0: b506 8e6b bcf8 85f2 c03b a83f 06ad e8a6  ...k.....;.?....

Very quickly, you can see repeat patterns: look at the sequences at &110 and &190 where the ASCII representation shows 4t3!… Realizing that most of the bytes in the source file are &30, XORing the result with &30 would be a good guess for recovering the key:

          …
00000080: 641c d7da 9927 3fec 9bdf 7a0c 3bd4 6df5  d....'?...z.;.m.
00000090: 0444 0311 df59 8f21 737a cc83 dd30 6a30  .D...Y.!sz...0j0
000000a0: d38f 02f0 606b 94e4 b7f3 03a8 6088 f043  ....`k......`..C
000000b0: e88e 43a0 ca84 3153 f31f c9e8 adc0 ba6d  ..C...1S.......m
000000c0: 9308 d46a 2cb2 0727 c099 ee89 afc3 53ab  ...j,..'......S.
000000d0: 2b34 5c2f 13ee aa2c d9f4 bc12 b3c5 1c68  +4\/...,.......h
000000e0: 0120 2cfa 77a6 b5a4 fc9b f132 5bc3 7077  . ,.w......2[.pw
000000f0: 8536 be5b 8cc8 b5c2 f00b 980f 369d d896  .6.[........6...
00000100: ab2c edea 6c37 3fec 9bdf 7a0c 3bd4 6df5  .,..l7?...z.;.m.
00000110: 0444 0311 df59 8f21 737a cc83 dd30 6a30  .D...Y.!sz...0j0
00000120: d38f 02f0 606b 94e4 b7f3 03a8 6088 f043  ....`k......`..C
00000130: e88e 43a0 ca84 3153 f31f c9e8 adc0 ba6d  ..C...1S.......m
00000140: 9308 d46a 2cb2 0727 c099 ee89 afc3 53ab  ...j,..'......S.
00000150: 2b34 5c2f 13ee aa2c d9f4 bc12 b3c5 1c68  +4\/...,.......h
00000160: 0120 2cfa 77a6 b5a4 fc9b f132 5bc3 7077  . ,.w......2[.pw
00000170: 8536 be5b 8cc8 b5c2 f00b 980f 369d e859  .6.[........6..Y
00000180: 9b08 dd1f 7c37 3fec 9bdf 7a0c 3bd4 6df5  ....|7?...z.;.m.
00000190: 0444 0311 df59 8f21 737a cc83 dd30 6a30  .D...Y.!sz...0j0
000001a0: d38f 02f0 606b 94e4 b7f3 03a8 6088 f043  ....`k......`..C
000001b0: e88e 43a0 ca84 3153 f31f c9e8 adc0 ba6d  ..C...1S.......m
000001c0: 9308 d46a 2cb2 0727 c099 ee89 afc3 53ab  ...j,..'......S.
000001d0: 2b34 5c2f 13ee aa2c d9f4 bc12 b3c5 1c68  +4\/...,.......h
000001e0: 0120 2cfa 77a6 b5a4 fc9b f132 5bc3 7077  . ,.w......2[.pw
000001f0: 8536 be5b 8cc8 b5c2 f00b 980f 369d d896  .6.[........6...
00000200: ab2c edea 6c37 3fec 9bdf 7a0c 3bd4 6df5  .,..l7?...z.;.m.
00000210: 0444 0311 df59 8f21 737a cc83 dd30 6a30  .D...Y.!sz...0j0
00000220: d38f 02f0 606b 94e4 b7f3 03a8 6088 f043  ....`k......`..C
          …

And there it is, the start of the key at &100 and again at &200, beginning with the byte sequence:

    &ab, &2c, &ed, &ea, &6c, &37, &3f, &ec,
    &9b, &df, &7a, &0c, &3b, &d4, &6d, &f5, …

Since the 255 byte maximum line length may kibosh pulling the key out in one piece, you might need a longer sample programme to extract the key. The above bytes match the key used in the ManageDSK source, as listed in this other forum thread: Unprotecting Programs - CPCWiki Forum.

The above is an example of a known-plaintext attack (KPA).

  • 2
    I used a similar method, 5 PRINT"    " but with as many spaces as would fill the line. By using a one digit line number I was able to include an extra space! I actually entered it as 5?"    … to get the longest string of spaces possible, minus the optional close quote. – CJ Dennis Jul 31 '17 at 0:10
  • 2
    This cracking method is straight out of any modern "cryptography 101" course, but if the typical CPC computer user considered cryptography "technology that was sufficiently advanced to be indistinguishable from magic" (to quote Arthur C Clarke) it was good enough for its time. – alephzero Aug 2 '17 at 19:45
  • yup, @alephzero - I added a reference to KPA, as this is very much a known plaintext – scruss Nov 14 '18 at 13:57
6

I'm not familiar with that system, but if users had the ability to protect their own files, then no it was not secure.

If you can protect your own files (with known contents) then you have easy access to both the protected and unprotected file. XOR has always been a very common encryption method, so it would have been natural for a curious individual to try XORing the protected and the unprotected file. Once you've done that it will be apparent that the XOR pattern repeats after 128 bytes and the security of the protection pretty much falls apart at that point.

It's not necessary to figure out how the 128-byte key is generated, you just need to know the result.

4

No, it wasn't considered really secure. In fact several programs existed at the time, including small "type-ins" available in magazines for removing that exact protection. There are some of them listed in the CPCWiki, which are no longer than 3 lines of BASIC (well, sort of) code.

I'm not entirely sure when the first such program appeared on a magazine, but it definitely didn't take long; after all, there were ways to unlock for far more advanced protection schemes (including disk and tape "locking").

  • 1
    Note that the programs on the wiki don't remove the encryption. They let the BASIC loader do the work of decrypting the file, and just disable the "delete after run" behavior. – Mark Nov 9 '17 at 18:51
2

Something to consider is the length of the keys. 13 plus 11 bytes gives 192 bits, while 128 bytes is 1024 bits, so this scheme isn't even one fifth as secure as using 128 unrelated bytes.

If someone had access only to the encrypted files, the repeating nature of the keys would give an advantage as it adds a pattern that can be detected.

The entropy of the keys is actually reduced by 8, since XORing the bytes with each each other X XOR Y is the same as (X XOR Z) XOR (Y XOR Z).

So, if the format of the file is known in advance (a tokenised BASIC listing), it would be easy to guess enough source bytes to make the decryption easier. This is not a particularly secure encoding, even if it was not possible to construct as many encoded files as you want for analysis, or without access to the source code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.