BLOFSH

Added to A-Shell, August 2016

xcall BLOFSH, opcode(=1), impure, key

xcall BLOFSH, opcode(=2), impure, cleartext, ciphertext

xcall BLOFSH, opcode(=3), impure, ciphertext, cleartext

BLOFSH.SBR implements the Blowfish encryption algorithm. It is used to encrypt or decrypt data in memory using a variable length key of 32 to 448 bits.

Blowfish is a symmetric-key block cipher, designed in 1993 by Bruce Schneier and made available to the world for royalty-free use. See the Blowfish entry at Wikipedia for more information.

Parameters

opcode  (Num)  [in]

1 to load the key, 2 to encrypt, 3 to decrypt

impure  (Raw, 4168)  [in/out]

A block of 4168 bytes which must be provide to the subroutine for its use as a work area. Do not modify it between calls.

key  (Raw)  [in]

A variable containing your encryption key. The mapped size of key determines the length of the encryption key, which can be from 4 to 56 bytes—i.e. 32 to 448 bits. Note being a symmetric cipher, the same key is used for encryption and decryption. Obviously you should generate an unpredictable key and store it securely.

cleartext  (Raw)  [in/out]

An area containing or overlaying the clear data. For opcode 2 (encrypt), this is the source; for opcode 3 (decrypt), it is the destination. The size in bytes must be divisible by 4, and must match the ciphertext size. You can use an overlay or an assignment to up-size your actual clear text field. For example, to encrypt a string 29 bytes long, you might map it as follows:

map1 cleartext$,s,29

map1 cleartext,x,32,@cleartext$

 

ciphertext  (Raw)  [in/out]

An area containing or overlaying the encrypted data. Restrictions and comments given for cleartext apply here as well.

Example

MAP1 X,I,2

MAP1 BF'IMPURE,X,4168    ! internal work area

MAP1 BF'KEY              ! (4 to 56 bytes, divisible by 4)

    MAP2 BF'KEY(4),B,4   ! 16 bytes (128 bits) 

 

MAP1 SECRETS

    MAP2 NAME,S,36

    MAP2 CODE,F,6

 

MAP1 CLEARTEXT,X,48,@SECRETS   ! must be divisible by 8

MAP1 CIPHERTEXT,X,48           ! must be same size as CLEARTEXT

 

X = SRND2(0,0,&hFFFFFFFF)  ! randomize, set 32 bit range

for X = 1 to 4            ! generate 4 32-bit random values for key

    BF'KEY(X) = RND2()

next X

open #1, "BLOTST.KEY", output    ! save the key

? #1, BF'KEY;

close #1

 

xcall BLOFSH, 1, BF'IMPURE, BF'KEY      !  init cipher from key

 

NAME = "James Bond"

CODE = 0.007

 

xcall BLOFSH, 2, BF'IMPURE, CLEARTEXT, CIPHERTEXT   ! encrypt

 

open #2, "BLOTST.DAT", OUTPUT

? #2, CIPHERTEXT;               ! write encrypted data to file

close #2

 

! later, to decrypt...

open #1, "BLOTST.KEY", input         ! retrieve the saved key

input raw #1, BF'KEY

close #1

 

xcall BLOFSH, 1, BF'IMPURE, BF'KEY   !  re-init cipher from key

 

open #2, "BLOTST.DAT", input

input raw #2, CIPHERTEXT             ! read encrypted data

close #2

 

xcall BLOFSH, 3, BF'IMPURE, CIPHERTEXT, CLEARTEXT   ! decrypt

 

? "NAME = ";NAME;", CODE = ";CODE

 

end

 

Comments

When encrypting string fields, you can copy to/from the original (S format) field and the cleartext / ciphertext (X format) fields. But when encrypting numeric fields or structures, you must use the overlay method shown above. In all cases, you must save the entire ciphertext variable, not just the number of bytes in the actual data. In the example above, the actual data is only 43 bytes but the encrypted data is 48 bytes long, i.e rounded up to the next multiple of 8 bytes.

To generate truly unpredictable keys, see Random Number Generators. To avoid saving the key, you may be able to use some fixed function based on inputs unique to the situation—file #, customer #, ppn, etc.—to produce the seed from which you then can generate and later regenerate a pseudo-random sequence.

If you are exporting your application which encrypts or contains encrypted data, you may want to check your country's regulations. The US has loosened its requirements but there are still situations where Blowfish encryption with keys longer than 56 bits may be restricted.

 

See Also

•   CRYPTO.SBR

•   MX_PWCRYPT