MD5LIB is a small library (about 5400 bytes) containing an

advertisement
MD5LIB is a small library (about 5400 bytes) containing an
implementation of the MD5 message-digest algorithm and Luby-Rackoff
encryption based on MD5. It encrypts at up to 180 bytes/sec on my HP
48SX, and should work at up to 260 bytes/sec on a G or GX. The library
is implemented entirely in system RPL and machine language.
The functions in the library are:
LRE (Luby-Rackoff Encrypt string)
Input:
2: plaintext (string)
1: key (string)
Output:
1: ciphertext (string)
LRD (Luby-Rackoff Decrypt string)
Input: same as LRE
Output:
2: plaintext (string)
1: 1 (decryption was successful) or 0 (wrong key)
LRE and LRD encrypt/decrypt arbitrary HP 48 strings. Strings up to
about half the size of available memory can be encrypted/decrypted. The
key may be any length; keys of 32 bytes or longer are recommended for
better security. To improve encryption security, the MD5 sum of the
plaintext string given to LRE is prepended before encryption, and this
is compared with the MD5 sum of the string decrypted by LRD. Because
Luby-Rackoff encryption works on blocks of 32 bytes, the string is also
padded to a multiple of 32 bytes; the total output of LRE is always at
least 17 bytes and at most 48 bytes longer than the input.
A convenient way to encrypt/decrypt arbitrary HP 48 objects is to use
LRE and LRD in conjunction with the BZ compression program, which
returns its result as an HP 48 string; since BZ compresses faster than
LRE encrypts, this may also improve encryption speed with
well-compressible objects. The BZLRE and BZLRD programs below
accomplish this:
BZLRE: \<< CLLCD SWAP BZ 0 CHR + 3 OVER SIZE SUB SWAP LRE \>>
BZLRD: \<< CLLCD IF LRD THEN "BZ" SWAP + UBZ END \>>
Because BZ may return "abnormal" string objects that are not an integral
number of bytes in length, BZLRE appends a 0 CHR and "normalizes" the
string to an integral length using SUB. This does not interfere with
the operation of UBZ.
LREB (Luby-Rackoff Encrypt Block)
Input:
3: key left (string)
2: key right (string)
1: block (32-byte string)
Output:
3: key left (string)
2: key right (string)
1: encrypted block (32-byte string)
LRDB (Luby-Rackoff Decrypt Block)
Input: same as LREB
Output: same as LREB, except level 1 is decrypted
LREB and LRDB provide a block-level interface to the Luby-Rackoff
encryption algorithm for your own applications.
MD5 (MD5 sum of string data)
Input:
1: string
Output:
1: MD5 sum (16-byte string)
MD5 computes the MD5 sum of the input string. Since the MD5 sum is 128
bits, it is returned as a 16-byte string because HP 48 hex strings in
user RPL are limited to 64 bits. To view the hexadecimal representation
of the sum, use the $\->HEX function described below.
OBJMD5 (MD5 sum of arbitrary HP 48 object)
Input:
1: object
Output:
1: MD5 sum (16-byte string)
OBJMD5 computes the MD5 sum of an arbitrary HP 48 object. This can be a
much better way of verifying the integrity of an object than the CRC
checksum returned by BYTES, since the much greater length of an MD5 sum
makes it far harder to find a different object with the same sum. Note
that the OBJMD5 sum of a string will not be the same as the MD5 sum,
because OBJMD5 includes the string prolog and length in the sum; MD5
sums the just the nibbles 16 in the string "a", while OBJMD5 sums the
nibbles c2a207000016.
SKEYMD5 (MD5-based S/KEY function)
Input:
2: seed/secret string
1: sequence number
Output:
1: result (64-bit hex string)
SKEYMD5 computes the one-way function used by the S/KEY password system.
It is primarily provided as a convenience to users of the S/KEY package
I wrote for the HP 48. If you are using that package, you can replace
the MD5 object in the SKEY directory with the program \<< SKEYMD5 \>> to
save memory if you have both SKEY and MD5LIB installed on your
calculator. If you are writing your own S/KEY application, note that
the sequence number you should give to SKEYMD5 is one more than the
sequence number used in the S/KEY challenge -- the extra iteration
accomplishes the initial "key crunch".
$\->HEX (output hexadecimal representation of string data)
Input:
1: string
Output:
1: string bytes represented in hexadecimal
$\->HEX lets you view MD5 sums (or other string data) as hexadecimal
digits, particularly useful for manual verification of MD5 sums.
Security:
The Luby-Rackoff algorithm is conjectured to be as secure as the
underlying hash function used. MD5 has so far resisted full
cryptanalysis, but several components of the algorithm have been
cryptanalyzed. Should MD5 be cryptanalyzed, this may substantially
weaken the encryption used in MD5LIB. However, because Luby-Rackoff can
use arbitrary-length keys, and the maximum useful key length in this
implementation is probably around 32 bytes (256 bits), substantial
progress in cryptanalysis of MD5 would have to be made to badly weaken
the algorithm; a key length of 256 bits is at least twice as long as
keys used in other algorithms.
Probably the biggest threat to the security of your data encrypted with
MD5LIB is that HP 48 RPL memory management and object handling will
scatter pieces of the plaintext and your key throughout memory. Someone
who gets ahold of your calculator immediately after an encryption could
extract some or all of the plaintext or your keys by scanning memory.
Disabling LASTARG before an encryption or decryption will remove the
most obvious threat, which is that a key could be recovered simply by
using LASTARG immediately after LRE or LRD.
References:
You can get everything you need to know about the techniques used in
this program from Bruce Schneier's _Applied Cryptography_ (John Wiley &
Sons, 1994, ISBN 0-471-59756-2), which covers the Luby-Rackoff algorithm
(p. 270, beware of typos), MD5 (p. 329), and CBC mode for block
encryption algorithms, as used in LRE and LRD (p. 157).
Download