You are on page 1of 4


Encrypting data with the Blowfish

by Bill Gatliff upgrade, or anything else that
Consultant, can be represented as a stream
Gdbstubs Library of bits. The process of encryption
converts that plaintext message
Modern embedded systems into ciphertext, and decryption
need data security more than converts the ciphertext back into
ever before. Our PDAs store per- plaintext.
sonal e-mail and contact lists; GPS Generally speaking, encryp-
receivers and, soon, cell phones tion algorithms come in two
keep logs of our movements;[1] flavours, symmetric and public
and our automobiles record our key. Symmetric algorithms, such
driving habits.[2] On top of that, as Blowfish, use the same key for
users demand products that can encryption and decryption. Like a
be reprogrammed during normal password, you have to keep the
use, enabling them to eliminate key secret from everyone except
bugs and add new features as the sender and receiver of the
firmware upgrades become avail- message.
able. Public key encryption algo-
Data security helps keep pri- rithms use two keys, one for en-
vate data private. Secure data cryption and another for decryp-
transmissions prevent contact tion. The key used for encryption,
lists and personal e-mail from the “public key” need not be kept
being read by someone other secret. The sender of the message
than the intended recipient, uses that public key to encrypt
keep firmware upgrades out of their message, and the recipient
devices they don’t belong in, and uses their secret decryption key,
verify that the sender of a piece of or “private key”, to read it. In a
information is who he says he is. sense, the public key “locks” the
The sensibility of data security is message, and the private key
even mandated by law in certain “unlocks” it: once encrypted with
applications: in the U.S. elec- the public key, nobody except
tronic devices cannot exchange the holder of the private key can
personal medical data without decrypt the message. RSA is a Figure 1: Blowfish algorithm
encrypting it first, and electronic popular public key encryption
engine controllers must not algorithm. Encryption algorithms can Data security in practice
permit tampering with the data Most credible encryption be used for several kinds of data Let’s say an embedded system
tables used to control engine algorithms are published and security. Sometimes you want wants to establish a secure data-
emissions and performance. freely available for analysis, be- data integrity, the assurance exchange session with a laptop,
Data security techniques have cause it’s the security of the key that the recipient received the perhaps over a wireless medium.
a reputation for being compu- that actually makes the algo- same message you sent. Encryp- At the start of the session, both
tationally intensive, mysterious, rithm secure. A good encryption tion algorithms can also provide the embedded system and lap-
and fraught with intellectual algorithm is like a good bank authentication, the assurance top compute a private Blowfish
property concerns. While some of vault: even with complete plans that a message came from whom key and public and private RSA
this is true, straightforward public for the vault, the best tools, and it says it came from. Some en- keys. The embedded system
domain techniques that are both example vaults to practice on, cryption algorithms can even and laptop exchange the public
robust and lightweight do exist. you won’t get inside the real provide nonrepudiation, a way RSA keys and use them to en-
One such technique, an algo- thing without the key. to prove beyond a doubt (say, crypt and exchange their private
rithm called Blowfish, is perfect Sometimes an encryption in a courtroom) that a particular Blowfish keys. The two machines
for use in embedded systems. algorithm is restricted, meaning sender was the originator of a then encrypt the remainder of
that the algorithm itself is kept se- message. And of course, most their communications using
Terminology cret. But then you can never know encryption algorithms can also Blowfish. When the communica-
In cryptographic circles, plaintext for sure just how weak a restricted assure data privacy, a way to tions session is over, all the keys
is the message you’re trying to algorithm really is, because the prevent someone other than the are discarded.
transmit. That message could be developer doesn’t give anyone a intended recipient from reading In this example, it doesn’t mat-
a medical test report, a firmware chance to analyse it. the message. ter if someone is eavesdropping | August 2003 | EE Times-India

on the entire conversation. With- The Blowfish algorithm    y = ctx->S[0][a] + ctx->S[1][b];    temp = Xl;
out the private RSA keys, which Blowfish is a symmetric encryp-    y = y ^ ctx->S[2][c];    Xl = Xr;
never go over the airwaves, the tion algorithm, meaning that    y = y + ctx->S[3][d];    Xr = temp;
eavesdropper can’t obtain the it uses the same secret key to
Blowfish keys and, therefore, can’t both encrypt and decrypt mes-    return y;    Xr = Xr ^ ctx->P[1];
decrypt the messages passed sages. Blowfish is also a block }    Xl = Xl ^ ctx->P[0];
between the two machines. This cipher, meaning that it divides void
example is similar to how the a message up into fixed length Blowfish_Encrypt(BLOWFISH_    *xl = Xl;
OpenSSH command shell works blocks during encryption and CTX *ctx, uint32_t *xl, uint32_t    *xr = Xr;
(although OpenSSH takes addi- decryption. The block length *xr) }
tional steps to prevent the public for Blowfish is 64 bits; messages {
keys from being tampered with that aren’t a multiple of eight    uint32_t Xl; void
during transit). bytes in size must be padded.    uint32_t Xr; Blowfish_Init(BLOWFISH_CTX
Now let’s say that a server Blowfish is public domain, and    uint32_t temp; *ctx, uint16_t *key, int KeyLen)
wants to send a firmware up- was designed by Bruce Schneier    int   ii; {
grade to a device and wants expressly for use in performance-    uint32_t Xl;
to be sure that the code isn’t constrained environments such    Xl = *xl; {
intercepted and modified dur- as embedded systems.[3] It has    Xr = *xr;    int i, j, k;
ing transit. The firmware up- been extensively analysed and    uint32_t data, datal, datar;
grade may be delivered over a deemed “reasonably secure” by    for (i = 0; i < N; ++i)
network connection, but could the cryptographic community.    {    for (i = 0; i < 4; i++)
just as easily be delivered via Implementation examples are          Xl = Xl ^ ctx->P[i];    {
a CD-ROM. In any case, the available from several sources,          Xr = F(ctx, Xl) ^ Xr;          for (j = 0; j < 256; j++) ctx-
server first encrypts the firm- including the one by Paul Kocher >S[i][j] = ORIG_S[i][j];
ware upgrade with its private that’s excerpted in this article as          temp = Xl;    }
RSA key, and then sends it to          Xl = Xr;
the device. The recipient de- Listing 1.          Xr = temp;    j = 0;
crypts the message with the (The complete code is    }    for (i = 0; i < N + 2; ++i)
server’s public key, which was available for download at    {
perhaps programmed into the    temp = Xl;          data = 0x00000000;
device during manufacture. If pub/2003/08blowfish.)    Xl = Xr;          for (k = 0; k < 4; ++k)
the firmware upgrade is suc-    Xr = temp;          {
cessfully decrypted, in other /*              data = (data << 8) | key[j];
words a checksum of the im-   Blowfish algorithm. Written    Xr = Xr ^ ctx->P[N];              j = j + 1;
age equals a known value, or 1997 by Paul Kocher (paul@    Xl = Xl ^ ctx->P[N + 1];              if (j >= keyLen) j = 0;
the machine instructions look          }
valid, the firmware upgrade is   This code and the algorithm are      ctx->P[i] = ORIG_P[i] ^ data;
considered authentic. in the0 public domain.    *xl = Xl;    }
The RSA algorithm is compu- */    *xr = Xr;
tationally expensive, although }    datal = 0x00000000;
not unreasonably so for the level #define MAXKEYBYTES 56    /*    datar = 0x00000000;
of functionality and security it 448 bits */ void
provides. A lighter-weight ap- #define N   16 Blowfish_Decrypt(BLOWFISH_    for (i = 0; i < N + 2; i += 2)
proach to firmware exchange CTX *ctx, uint32_t *xl, uint32_t    {
with an embedded system typedef struct { *xr)          Blowfish_Encrypt(ctx,
would be to encrypt the image    uint32_t P[16 + 2]; { &datal, &datar);
with Blowfish, instead of RSA.    uint32_t S[4][256];    uint32_t Xl;          ctx->P[i] = datal;
The downside to this approach is } BLOWFISH_CTX;    uint32_t Xr;          ctx->P[i + 1] = datar;
that the Blowfish key in the em-    uint32_t temp;    }
bedded system has to be kept unsigned long    int   ii;
secret, which can be difficult to F(BLOWFISH_CTX *ctx, uint32_t    for (i = 0; i < 4; ++i)
achieve for a truly determined x)    Xl = *xl;    {
attacker with hardware skills. {    Xr = *xr;          for (j = 0; j < 256; j += 2)
In less extreme cases, however,    uint16_t a, b, c, d;          {
Blowfish is probably fine since    uint32_t y;    for (i = N + 1; i > 1; --i)              Blowfish_Encrypt(ctx,
an attacker with such intimate    { &datal, &datar);
knowledge of the target system    d = x & 0x00FF;          Xl = Xl ^ ctx->P[i];              ctx->S[i][j] = datal;
and environment will likely find    x >>= 8;          Xr = F(ctx, Xl) ^ Xr;              ctx->S[i][j + 1] = datar;
another way into the device    c = x & 0x00FF;          }
anyway (in other words, simply    x >>= 8;          temp = Xl;    }
snatching the firmware upgrade    b = x & 0x00FF;          Xl = Xr; }
from flash memory once it’s    x >>= 8;          Xr = temp;
decrypted).    a = x & 0x00FF;    } int | August 2003 | EE Times-India

Blowfish_Test(BLOWFISH_CTX is plaintext; for decryption, the Using the example code    uint32_t message_right;
*ctx) input is ciphertext. Of course, firmware upgrades    int block_len;
{ The P-array and S-array val- and data logs are seldom exactly    
   uint32_t L = 1, R = 2; ues used by Blowfish are pre- 64 bits in length. To encrypt long #if 1
computed based on the user’s strings of data using Blowfish,    /* sanity test, encrypts a known
   Blowfish_Init(ctx, (unsigned key. In effect, the user’s key is carve the message up into 64-bit message */
char*)”TESTKEY”, 7); transformed into the P-array and blocks, encrypt each block and    n = Blowfish_Test(&ctx);
   Blowfish_Encrypt(ctx, &L, &R); S-array; the key itself may be dis- save the results. Pad the message    printf(“Blowfish_Test returned:
   if (L != 0xDF333FD2L || R != carded after the transformation. with a value of your choosing to %d.%s\n”, n, n ? “ Abort.” : “”);
0x30A71BB4L) return (-1); The P-array and S-array need not end on a 64-bit boundary. The    if (n) return n;
be recomputed (as long as the code in the main() of Listing 2 #endif
   Blowfish_Decrypt(ctx, &L, &R); key doesn’t change), but must does exactly this.
   if (L != 1 || R != 2) return (-1); remain secret.    Blowfish_Init(&ctx, key, keylen);
return (0); I’ll refer you to the source code Listing 2:
} for computing the P and S arrays Example of Blowfish use    printf(“Plaintext message string
and only briefly summarise the #include <stdio.h> is: %s\n”, plaintext_string);
Blowfish requires about 5KB of procedure as follows: #include <string.h>
memory. A careful implementa-     int    /* encrypt the plaintext mes-
tion on a 32-bit processor can en- • P is an array of eighteen 32-bit main (void) sage string */
crypt or decrypt a 64-bit message integers.        {    printf(“Encrypted message
in approximately 12 clock cycles. • S is a two-dimensional array    BLOWFISH_CTX ctx; string is: “);
(Not-so-careful implementations, of 32-bit integer of dimension    int n;
like Kocher, don’t increase that 4x256.        while (plaintext_len)
time by much.) Longer messages • Both arrays are initialised with    /* must be less than 56 bytes */    {
increase computation time in a constants, which happen to    char *key = “a random number      message_left = message_
linear fashion; for example, a 128- be the hexadecimal digits of string would be a better key”; right = 0UL;
bit message takes about (2 x 12) π (a pretty decent random    int keylen = strlen(key);
clocks. Blowfish works with keys number source).        /* crack the message string
up to 448 bits in length. • The key is divided up into 32-    uint8_t *plaintext_string = “this into a 64-bit block (ok, really two
A graphical representation of bit blocks and XORed with the is our message”; 32-bit blocks); pad with zeros if
the Blowfish algorithm appears initial elements of the P and S    int plaintext_len = necessary */
in Figure 1. In this description, arrays. The results are written strlen(plaintext_string);      for (block_len = 0; block_len <
a 64-bit plaintext message is first back into the array.     4; block_len++)
divided into 32 bits. The “left” 32 • A message of all zeros is    uint8_t ciphertext_buffer[256];      {
bits are XORed with the first ele- encrypted; the results of the    uint8_t *ciphertext_string =        message_left = message_left
ment of a P-array to create a value encryption are written back &ciphertext_buffer[0]; << 8;
I’ll call P’, run through a transfor- to the P and S arrays. The P    int ciphertext_len = 0;        if (plaintext_len)
mation function called F, then and S arrays are now ready        {
XORed with the “right” 32 bits of for use.    uint32_t message_left;            message_left += *plain-
the message to produce a new
value I’ll call F’. F’ then replaces
the “left” half of the message and
P’ replaces the “right” half, and
the process is repeated 15 more
times with successive members
of the P-array. The resulting P’ and
F’ are then XORed with the last
two entries in the P-array (entries
17 and 18), and recombined to
produce the 64-bit ciphertext.
A graphical representation
of F appears in Figure 2. The
function divides a 32-bit input
into four bytes and uses those
as indices into an S-array. The
lookup results are then added
and XORed together to produce
the output.
Because Blowfish is a symmet-
ric algorithm, the same procedure
is used for decryption as well as
encryption. The only difference is
that the input to the encryption Figure 2: Graphic representation of F | August 2003 | EE Times-India

text_string++; (uint8_t)(message_right >> 24); text_string++; End notes:   
           plaintext_len--;      *ciphertext_string++ =            if (ciphertext_len) 1. Not an actual log per se, but
       } (uint8_t)(message_right >> 16);            ciphertext_len--; so-called ephemerides infor-
       else message_left += 0;      *ciphertext_string++ =         } mation that allows the device
     } (uint8_t)(message_right >> 8); to find GPS transmitters with-
     for (block_len = 0; block_len <      *ciphertext_string++ =         Blowfish_Decrypt(&ctx, out doing a time-consuming
4; block_len++) (uint8_t)message_right; &message_left, &message_right); search of the entire GPS spec-
     {      ciphertext_len += 8; trum. Such information can
       message_right = mes- printf(“\n”);    /* if plaintext message string also be used to pinpoint the
sage_right << 8; padded, extra zeros here */ receiver’s location at a previ-
       if (plaintext_len)    /* reverse the process */ ous point in time. Because of
       {      printf(“Decrypted message         printf(“%c%c%c%c%c%c% this capability, GPS receivers
           message_right += *plain- string is: “); c%c”, are routinely collected and
text_string++;         (int)(message_left >> 24), analysed during searches by
           plaintext_len--;      ciphertext_string = &cipher- (int)(message_left >> 16), law enforcement. A digital
       } text_buffer[0];         (int)(message_left >> 8), signature would authenticate
       else message_right += 0;      while(ciphertext_len) (int)(message_left), the ephimeride, verifying
     }      {         (int)(message_right >> 24), that it hadn’t been tampered
   /* encrypt and print the         message_left = mes- (int)(message_right >> 16), with or rendered invalid be-
results */ sage_right = 0UL;         (int)(message_right >> 8), fore being used as evidence.
     Blowfish_Encrypt(&ctx, (int)(message_right)); Back    
&message_left, &message_         for (block_len = 0; block_len } 2. In the U.S., commercial auto-
right); < 4; block_len++) motive systems do this to pre-
     printf(“%lx%lx”, message_left,         { printf(“\n”); vent warranty claims for user-
message_right);           message_left = mes- damaged hardware; in Eu-
sage_left << 8; return 0; rope, it’s to prevent speeding.
   /* save the results for decryp-           message_left += *cipher- } Back    
tion below */ text_string++; 3. Schneier, Bruce. Applied Cryp-
     *ciphertext_string++ =           if (ciphertext_len) Now is a good time to start tography: Protocols, Algo-
(uint8_t)(message_left >> 24);            ciphertext_len--; thinking about adding data in- rithms, and Source Code in
     *ciphertext_string++ =         } tegrity and privacy capabilities C, Second Edition. New York,
(uint8_t)(message_left >> 16);         for (block_len = 0; block_len to your embedded system. The NY: John Wiley & Sons, 1995.
     *ciphertext_string++ = < 4; block_len++) Blowfish algorithm is an excel- Back
(uint8_t)(message_left >> 8);         { lent choice for encryption, since
     *ciphertext_string++ =            message_right = mes- it’s lightweight, public domain,
(uint8_t)message_left; sage_right << 8; and considered secure even after
     *ciphertext_string++ =            message_right += *cipher- extensive analysis. Email   Send inquiry | August 2003 | EE Times-India