Jaap's Psion II Page

The Psion LZ Password System


The LZ has a built in security system. It allows you to set a general password to lock up the Psion completely, and also to set a password on a notepad file which is then encrypted to keep out prying eyes. This document will describe how it works, and its weaknesses.

If you just want to recover a password, use the Psion LZ Password Cracker.


  1. Password Encoding
  2. System Passwords
  3. Notepad Passwords
  4. Notepad Encryption
  5. Notepad Decryption
  6. Password Encoding Algorithm

1. Password encoding

Passwords are not stored directly in memory, otherwise a simple peek would allow someone immediate access to them. After a password has been typed in, it is encoded in a rather complicated way to give a 9 byte string, the passcode. This encoding is a little complicated to describe (see the end of this document), but not very difficult to do. It is however impossible to undo directly, so the originally typed password can't be recovered from the passcode directly.

Furthermore, the resulting passcode probably is unique to each password. This means that passwords can be checked by comparing their codes only.

2. System passwords

When a system password is given, it is encoded and the resulting 9 byte passcode is stored at $7FD7-$7FDF. It is difficult to recover the original password from these bytes directly. The only way to do this is to simply try all possible passwords until you find one that has the right code.

Such an exhaustive search is quite practical since each password character has only 59 possibilities (it is converted to upper case before encoding). Also more importantly, the encoding algorithm has a fatal flaw. By using some properties of the encoding it is possible to check whether 4 characters are most likely correct without using the other 4 characters of the password. This means that in effect the password is only 4 characters long instead of 8.

In practice however, it is either impossible or not necessary to do such a search for a system password. On a Psion with a system password set and active it is impossible to read the encoded password, so you cannot do the exhaustive search. The only way to beat an active system password is to remove the battery which of course destroys all data on A:. Note also that since external devices are not loaded during a warm boot it is not possible to intercept the password routine that way.

On the other hand, on a Psion with a password set but not active it is not necessary to do any calculating at all as it is easy to erase the password completely.

The byte at $7FD6 contains the system password state. It can contain the following values: 0 - There is no system password. (This is the default) 1 - There is a system password but it is not active. 3 - There is a system password and it is active. (Note: Actually bit 0 is set when a system password has been given, bit 1 is set when it is active.)

The instruction POKEB $7FD6,0 will erase the system password. This allows you to set a new system password without knowing the old one. Note that there is no need to clear the passcode at $7FD7-7FDF as it is simply ignored until it is overwritten at such time when a new password is typed in.

3. Notepad passwords

When a notepad is given a password, the password is encoded in exactly the same way as the system password. The 9 byte passcode is then also stored in the notepad file. Thus when it is accessed using the notepad editor, it will be password verified before viewing/editing is allowed.

To further secure the notepad text from peeking, it is also encrypted. This encryption is done in a very simple way using an 8 byte key. The same algorithm that produces the passcode from the password is used (with slight modifications) to generate the 8 byte key.

Recovering the notepad text without the password seems to be very difficult. We could try to find out the password from the passcode, and then use that to get the key and decode the text. As explained in the previous section this involves an exhaustive computer search. It is impossible to go directly from the passcode to the key without finding the password first. The information in the notepad therefore seems secure. However, the method used to encrypt the text is so simple that it is possible to decode it without knowing the password or key at all, provided the notepad contains at least about 20 characters of text.

4. Notepad encryption

There now follows a description of the encryption method. Suppose we have the following notepad file:

Testing:   This is a   test.    
and the password ABCDEFGH.

Txt:Testing:# T h i s _ i s _ a# t e s t .#
Asc: 841041051153210511532970116101115116460

Note that the end of a line is indicated by a 0 byte (denoted here by a #). The title of the notepad 'Testing:' will not be encrypted, and if like here there is a zero byte immediately following it, that byte is not encrypted either.

The encryption key is calculated from the password (see final section), and turns out to be 82,47,5,181,247,92,30,165. One of the simplest types of encryption with a key is adding the key letter by letter (or rather number by number) to the text. This is the so-called Viginère cipher. The notepads are encrypted in this way, but to further disguise the encryption another sequence is added. The sequence is generated by consecutive multiples of 163, i.e.. 163, 70 (=163+163-256), 233, 140 (233+163-256), etc. This sequence is added to the key before being added to the plaintext.

This is of course best illustrated with our example. For the first eight characters we have:

Text: T h i s _ i s _
Ascii: 84104105115 32105115 32
OldKey: 82 47 5181247 92 30165
Sequence: 163 70233140 47210117 24
NewKey: 245117238 65 38 46147189
Asc+NewKey: 73221 87180 70151 6221

Note that if a number exceeds 255, 256 is subtracted to keep it within range of a single byte.

The key that was used here is now used to calculate the key to use on the next 8 letters:

Text: a # t e s t . #
Ascii: 97 0116101115116 46 0
OldKey: 245117238 65 38 46147189
Sequence: 187 94 1164 71234141 48
NewKey: 176211239229109 24 32237
Asc+NewKey: 17211 99 74224140 78237

The complete encryption is now:

Text: T h i s _ i s _ a # t e s t . #
Encrypted: 73221 87180 70151 6221 17211 99 74224140 78237

Superficially this looks like a good encryption, especially since the key is continuously transformed causing letters to be encrypted differently depending on where they are in the text. In the next section I will show how easy it is to decode such an encrypted notepad.

5. Notepad decryption

Suppose we have an encrypted notepad file, and we want to decode it to get the original text. If we have the original password, then we can use the same method as the encryption, except that instead of adding the key bytes, we subtract them. The notepad file contains the passcode and due to its weakness the original password can be recovered. From that we can generate the encryption key and decrypt the file.

However, even without cracking the passcode it is often still possible to recover the text. The first step is to decode it as if it had a key consisting of zeroes only. This will remove the disguising sequence, and leave us with a much simpler code.

Using the same example as above, we get

Key: 0 0 0 0 0 0 0 0
Sequence: 163 70233140 47210117 24
NewKey: 163 70233140 47210117 24
Code: 73221 87180 70151 6221
Code-NewKey:166151110 40 23197145197
Key: 163 70233140 47210117 24
Sequence: 187 94 1164 71234141 48
NewKey: 94164234 48118188 2 72
Code: 17211 99 74224140 78237
Code-NewKey:179 47121 26106208 76165

If you compare the result with the original ascii values, you will see that they differ only by the original 8 byte encryption key.

This text is a little bit too short to be easily decoded, but by using a few reasonable guesses and assumptions it is nevertheless possible.

We know the last byte of a notepad is always zero. Therefore we can always immediately deduce at least an eighth of the characters in the text.
The last byte in this code is 165, so that byte of the key must have been 165 to produce it from a zero byte.

Code: 166151110 40 23197145197
179 47121 26106208 76165
Ascii: 32
0
Text: _
#

Unfortunately for us, the only other character that used that byte of the key was a Space.

We can also assume that the notepad will only contain characters that can be typed in from the Psion keyboard. On an English machine that means that ascii characters above 122 and below 32 are impossible (as are 33,35,38,39,63,64 and 91-96) The only way for the second column to have valid characters, is if the key was 47.

Code: 166151110 40 23197145197
179 47121 26106208 76165
Ascii: 104 32
0 0
Text: h _
# #

The fifth column also has very few possibilities (only 5). Assuming the characters are not punctuation marks or other non-alphabetical symbols, the column contains either a # and 'S' or ' ' and 's'. The second pair seems more plausible, especially since we already have a lower case letter.

Code: 166151110 40 23197145197
179 47121 26106208 76165
Ascii: 104 32 32
0 115 0
Text: h _ _
# s #

Assuming the last character is a full stop (since none of the 19 possibilities allow it to be a letter), we get:

Code: 166151110 40 23197145197
179 47121 26106208 76165
Ascii: 104 32 115 32
0 115 46 0
Text: h _ s _
# s . #

The easiest columns have been those where there is the largest range of numbers. There are no more of those columns left, so we must look at the context instead. A two letter word with the second letter an 's' is likely to be 'is', and a one letter word is probably 'a'. This gives:

Code: 166151110 40 23197145197
179 47121 26106208 76165
Ascii: 84104 32105115 32
97 0 115116 46 0
Text: T h _ i s _
a # s t . #

A bit of trying out and the full text becomes clear ('Thaw is a list' and 'Theo is a past' are a little nonsensical). Of course, with longer notepads it is much easier, because more columns will have wider ranges, and there is more context.

6. Password encoding algorithm

Here is a detailed description of the algorithm used to transform the password into the 9 byte code or 8 byte key. This is unlikely to be of interest unless you wish to write something like a notepad editor on a Psion machine, or undo the encoding to retrieve the password.

  1. Start with a password of between 1 and 8 characters.
  2. Capitalize the password. If its length is less than 8 characters, then repeat it as often as necessary to get an 8 character string. For example, 'abc' becomes 'ABCABCAB'. Let p0 to p7 denote the ascii characters of this string. For the final few steps let l be the length of the password and let t=(p0+p1+p2+p3+p4+p5+p6+p7) MOD 8. (Note that MOD 8 means the remainder on division by 8, so it is the same as taking the logical AND with 7.)
  3. Compute g0 to g3 using the following formulae:
    g0 = (p0+3D) * (p7+25) * CB and ignore the lowest byte
    g1 = (p1+3D) * (p6+25) * CB and ignore the lowest byte
    g2 = (p2+3D) * (p5+25) * CB and ignore the lowest byte
    g3 = (p3+3D) * (p4+25) * CB and ignore the lowest byte
    The numbers are obviously given in hexadecimal notation. Note that the multiplications result in 3-byte integer values, and only the 2 high bytes are taken to give the 2-byte unsigned integers g0...g3.
  4. Compute f0, f1 using the following formulae:
    f0 = (g1+03) * (g2+0B) * A1 and ignore the lowest byte
    f1 = (g0+03) * (g3+0B) * AD and ignore the lowest byte
    The multiplications result in 5-byte integer values, and only the 4 high bytes are taken to give the 4-byte long integers f0 and f1. (Note that the addition operations will never cause a carry, so the factors really are two-byte integers.)
  5. Swap the two high bytes with the two low bytes of f0. Similarly f1.
  6. Compute e0, e1 using the following formulae:
    e0 = f0 * CB and ignore the lowest byte
    e1 = f1 * CB and ignore the lowest byte
    Let d0 to d3 denote the 4 bytes of e0, from low to high. Similarly d4 to d7 denote the bytes of e1 from low to high.
  7. Compute the first 8 bytes of the code by the following formulae:
    c0 = p0 + d7
    c1 = p1 + d6
    .. .. ..
    c6 = p6 + d1
    c7 = p7 + d0
    Of course these are restricted to byte values, so ignore any carry that might result.
  8. Compute the final code byte by the formula c8 = d(t)+l where t and l are remembered from step 1.
  9. Now c0 to c8 is the 9 byte passcode.

To compute the 8 byte notepad encryption key, nearly the same algorithm is used. The only difference is that the eight bytes d0 to d7 are used, so steps 6 and 7 are omitted. Also, during the calculation different numbers are used:
   Step 2: 25, 3D, C5 instead of 3D, 25, CB
   Step 3: 7, 3, A9, 97 instead of 3, B, A1, AD
   Step 5: C5 instead of CB

Example: Password is 'abcdefgh'. All numbers below are in hex.

  1. p0..p7 = 41,42,43,44,45,46,47,48
    l = 8
    t = (224 mod 8) = 4
  2. g0 = (41+3D)*(48+25)*CB = 2A8A[A2]
    g1 = ... = 2A7C
    g2 = ... = 2A6C
    g3 = ... = 2A5B

    Similarly, for an encryption key we get:
    g0 = (41+25)*(48+3D)*C5 = 28C7[76]
    g1 = ... = 28DE
    g2 = ... = 28F4
    g3 = ... = 2908

  3. f0 = (2A7C+3)*(2A6C+B)*A1 =046EEAFC[A9]
    f1 = (2A8A+3)*(2A5B+B)*AD =04C32AFD[16]

    And for encryption key:
    f0 = (28DE+7)*(28F4+3)*A9 = 0451EB3C[6B]
    f1 = (28C7+7)*(2908+3)*97 = 03DBD692[96]

  4. f0 = EAFC046E
    f1 = 2AFD04C3

    And for encryption key:
    f0 = EB3C0451
    f1 = D69203DB

  5. e0= EAFC046E*CB = BA55D783[3A]
    e1= 2AFD04C3*CB = 2216A2C6[A1]

    And for encryption key:
    e0 = EB3C0451*C5 = B5052F52[55]
    e1 = D69203DB*C5 = A51E5CF7[87]

    d0..d7= 83,D7,55,BA,C6,A2,16,22

    And for encryption key:
    d0..d7= 52,2F,05,B5,F7,5C,1E,A5 or 82,47,5,181,247,92,30,165 in decimal. The encryption key is now done.

  6. p0..p7= 41, 42, 43, 44, 45, 46, 47, 48
    d7..d0= 22, 16, A2, C6, BA, 55, D7, 83
    c0..c7= 63, 58, E5, 0A, FF, 9B, 1E, CB
  7. c8= d(t)+l = d4+8 = C6+8 =CE
    so the nine byte passcode is 63, 58, E5, 0A, FF, 9B, 1E, CB, CE or 99, 88, 229, 10, 255, 155, 30, 203, 206 in decimal.

If you are desperate to search for the password belonging to a 9 byte code then there are a few shortcuts that can be taken. First of all, the password can contain only upper case characters and symbols available on the Psion keyboard, and the special keypresses MODE, arrows or Shift-Delete. This leaves only 59 possibilities per character.

Second, if you choose p0,p3,p4,p7 first, then you can calculate g0,g3 and then f1, e1, and d4..d7. Using your choice of p0,p3 you can check whether c0,c3 matches the code you want to produce. Only about once in 65000 times will you find a possible match, so you hardly ever need to choose p1,p2,p5,p6.

If you do find a match, then from d5 and d6 you immediately know what p1 and p2 would have to be to give the correct c1 and c2. Of course, these might not be valid ascii values, in which case you will have to find the next set of p0,p3,p4,p7. If they are valid, then you only need to find p5 and p6. If no possibilities are found then again a new choice for p0,p3,p4,p7 must be made.

Because of these shortcuts this search is quite practical. If a program can check only 10000 of the 59^4 possibilities for p1,p2,p5,p6 in one second, then it will take about 20 minutes to finish the complete search. It would be expected to find the password on average in about 10 minutes (or less if it tries letters before trying symbols). Modern computers are much faster than that, and even my Psion LZ Password Cracker which is written in javascript is about 10 times as fast.