1 /*
   2  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  */
   5 
   6 /*
   7  * The above Sun copyright is included due to changes made to this code
   8  * for US export control.  No changes to the algorithm implementations have
   9  * been made.
  10  */
  11 
  12 #pragma ident   "%Z%%M% %I%     %E% SMI"
  13 
  14 /* $OpenBSD: blowfish.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */
  15 /*
  16  * Blowfish block cipher for OpenBSD
  17  * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
  18  * All rights reserved.
  19  *
  20  * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
  21  *
  22  * Redistribution and use in source and binary forms, with or without
  23  * modification, are permitted provided that the following conditions
  24  * are met:
  25  * 1. Redistributions of source code must retain the above copyright
  26  *    notice, this list of conditions and the following disclaimer.
  27  * 2. Redistributions in binary form must reproduce the above copyright
  28  *    notice, this list of conditions and the following disclaimer in the
  29  *    documentation and/or other materials provided with the distribution.
  30  * 3. All advertising materials mentioning features or use of this software
  31  *    must display the following acknowledgement:
  32  *      This product includes software developed by Niels Provos.
  33  * 4. The name of the author may not be used to endorse or promote products
  34  *    derived from this software without specific prior written permission.
  35  *
  36  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  37  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  39  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  40  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  42  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  43  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  45  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46  */
  47 
  48 /*
  49  * This code is derived from section 14.3 and the given source
  50  * in section V of Applied Cryptography, second edition.
  51  * Blowfish is an unpatented fast block cipher designed by
  52  * Bruce Schneier.
  53  */
  54 
  55 #if 0
  56 #include <stdio.h>                /* used for debugging */
  57 #include <string.h>
  58 #endif
  59 
  60 #include <sys/types.h>
  61 #include <blf.h>
  62 
  63 #undef inline
  64 #ifdef __GNUC__
  65 #define inline __inline
  66 #else                           /* !__GNUC__ */
  67 #define inline
  68 #endif                          /* !__GNUC__ */
  69 
  70 /* Function for Feistel Networks */
  71 
  72 #define F(s, x) ((((s)[        (((x)>>24)&0xFF)]  \
  73                  + (s)[0x100 + (((x)>>16)&0xFF)]) \
  74                  ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
  75                  + (s)[0x300 + ( (x)     &0xFF)])
  76 
  77 #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
  78 
  79 void
  80 Blowfish_encipher(c, xl, xr)
  81         blf_ctx *c;
  82         uint32_t *xl;
  83         uint32_t *xr;
  84 {
  85         uint32_t Xl;
  86         uint32_t Xr;
  87         uint32_t *s = c->S[0];
  88         uint32_t *p = c->P;
  89 
  90         Xl = *xl;
  91         Xr = *xr;
  92 
  93         Xl ^= p[0];
  94         BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
  95         BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
  96         BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
  97         BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
  98         BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
  99         BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
 100         BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
 101         BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
 102 
 103         *xl = Xr ^ p[17];
 104         *xr = Xl;
 105 }
 106 
 107 void
 108 Blowfish_decipher(c, xl, xr)
 109         blf_ctx *c;
 110         uint32_t *xl;
 111         uint32_t *xr;
 112 {
 113         uint32_t Xl;
 114         uint32_t Xr;
 115         uint32_t *s = c->S[0];
 116         uint32_t *p = c->P;
 117 
 118         Xl = *xl;
 119         Xr = *xr;
 120 
 121         Xl ^= p[17];
 122         BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
 123         BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
 124         BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
 125         BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
 126         BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
 127         BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
 128         BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
 129         BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
 130 
 131         *xl = Xr ^ p[0];
 132         *xr = Xl;
 133 }
 134 
 135 void
 136 Blowfish_initstate(c)
 137         blf_ctx *c;
 138 {
 139 /* P-box and S-box tables initialized with digits of Pi */
 140 
 141         const blf_ctx initstate =
 142 
 143         { {
 144                 {
 145                         0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
 146                         0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
 147                         0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
 148                         0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
 149                         0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
 150                         0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
 151                         0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
 152                         0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
 153                         0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
 154                         0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
 155                         0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
 156                         0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
 157                         0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
 158                         0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
 159                         0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
 160                         0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
 161                         0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
 162                         0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
 163                         0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
 164                         0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
 165                         0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
 166                         0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
 167                         0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
 168                         0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
 169                         0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
 170                         0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
 171                         0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
 172                         0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
 173                         0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
 174                         0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
 175                         0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
 176                         0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
 177                         0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
 178                         0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
 179                         0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
 180                         0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
 181                         0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
 182                         0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
 183                         0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
 184                         0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
 185                         0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
 186                         0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
 187                         0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
 188                         0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
 189                         0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
 190                         0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
 191                         0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
 192                         0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
 193                         0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
 194                         0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
 195                         0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
 196                         0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
 197                         0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
 198                         0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
 199                         0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
 200                         0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
 201                         0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
 202                         0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
 203                         0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
 204                         0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
 205                         0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
 206                         0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
 207                         0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
 208                 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
 209                 {
 210                         0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
 211                         0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
 212                         0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
 213                         0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
 214                         0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
 215                         0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
 216                         0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
 217                         0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
 218                         0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
 219                         0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
 220                         0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
 221                         0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
 222                         0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
 223                         0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
 224                         0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
 225                         0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
 226                         0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
 227                         0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
 228                         0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
 229                         0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
 230                         0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
 231                         0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
 232                         0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
 233                         0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
 234                         0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
 235                         0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
 236                         0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
 237                         0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
 238                         0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
 239                         0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
 240                         0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
 241                         0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
 242                         0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
 243                         0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
 244                         0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
 245                         0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
 246                         0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
 247                         0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
 248                         0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
 249                         0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
 250                         0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
 251                         0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
 252                         0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
 253                         0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
 254                         0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
 255                         0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
 256                         0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
 257                         0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
 258                         0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
 259                         0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
 260                         0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
 261                         0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
 262                         0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
 263                         0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
 264                         0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
 265                         0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
 266                         0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
 267                         0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
 268                         0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
 269                         0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
 270                         0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
 271                         0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
 272                         0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
 273                 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
 274                 {
 275                         0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
 276                         0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
 277                         0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
 278                         0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
 279                         0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
 280                         0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
 281                         0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
 282                         0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
 283                         0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
 284                         0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
 285                         0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
 286                         0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
 287                         0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
 288                         0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
 289                         0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
 290                         0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
 291                         0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
 292                         0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
 293                         0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
 294                         0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
 295                         0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
 296                         0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
 297                         0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
 298                         0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
 299                         0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
 300                         0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
 301                         0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
 302                         0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
 303                         0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
 304                         0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
 305                         0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
 306                         0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
 307                         0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
 308                         0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
 309                         0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
 310                         0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
 311                         0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
 312                         0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
 313                         0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
 314                         0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
 315                         0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
 316                         0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
 317                         0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
 318                         0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
 319                         0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
 320                         0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
 321                         0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
 322                         0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
 323                         0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
 324                         0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
 325                         0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
 326                         0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
 327                         0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
 328                         0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
 329                         0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
 330                         0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
 331                         0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
 332                         0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
 333                         0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
 334                         0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
 335                         0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
 336                         0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
 337                         0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
 338                 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
 339                 {
 340                         0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
 341                         0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
 342                         0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
 343                         0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
 344                         0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
 345                         0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
 346                         0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
 347                         0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
 348                         0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
 349                         0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
 350                         0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
 351                         0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
 352                         0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
 353                         0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
 354                         0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
 355                         0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
 356                         0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
 357                         0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
 358                         0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
 359                         0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
 360                         0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
 361                         0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
 362                         0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
 363                         0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
 364                         0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
 365                         0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
 366                         0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
 367                         0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
 368                         0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
 369                         0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
 370                         0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
 371                         0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
 372                         0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
 373                         0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
 374                         0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
 375                         0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
 376                         0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
 377                         0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
 378                         0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
 379                         0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
 380                         0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
 381                         0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
 382                         0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
 383                         0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
 384                         0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
 385                         0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
 386                         0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
 387                         0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
 388                         0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
 389                         0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
 390                         0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
 391                         0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
 392                         0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
 393                         0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
 394                         0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
 395                         0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
 396                         0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
 397                         0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
 398                         0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
 399                         0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
 400                         0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
 401                         0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
 402                         0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
 403                 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
 404         },
 405         {
 406                 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
 407                 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
 408                 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
 409                 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
 410                 0x9216d5d9, 0x8979fb1b
 411         } };
 412 
 413         *c = initstate;
 414 }
 415 
 416 uint32_t
 417 Blowfish_stream2word(const uint8_t *data, uint16_t databytes, uint16_t *current)
 418 {
 419         uint8_t i;
 420         uint16_t j;
 421         uint32_t temp;
 422 
 423         temp = 0x00000000;
 424         j = *current;
 425 
 426         for (i = 0; i < 4; i++, j++) {
 427                 if (j >= databytes)
 428                         j = 0;
 429                 temp = (temp << 8) | data[j];
 430         }
 431 
 432         *current = j;
 433         return temp;
 434 }
 435 
 436 void
 437 Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
 438 {
 439         uint16_t i;
 440         uint16_t j;
 441         uint16_t k;
 442         uint32_t temp;
 443         uint32_t datal;
 444         uint32_t datar;
 445 
 446         j = 0;
 447         for (i = 0; i < BLF_N + 2; i++) {
 448                 /* Extract 4 int8 to 1 int32 from keystream */
 449                 temp = Blowfish_stream2word(key, keybytes, &j);
 450                 c->P[i] = c->P[i] ^ temp;
 451         }
 452 
 453         j = 0;
 454         datal = 0x00000000;
 455         datar = 0x00000000;
 456         for (i = 0; i < BLF_N + 2; i += 2) {
 457                 Blowfish_encipher(c, &datal, &datar);
 458 
 459                 c->P[i] = datal;
 460                 c->P[i + 1] = datar;
 461         }
 462 
 463         for (i = 0; i < 4; i++) {
 464                 for (k = 0; k < 256; k += 2) {
 465                         Blowfish_encipher(c, &datal, &datar);
 466 
 467                         c->S[i][k] = datal;
 468                         c->S[i][k + 1] = datar;
 469                 }
 470         }
 471 }
 472 
 473 
 474 void
 475 Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
 476                      const uint8_t *key, uint16_t keybytes)
 477 {
 478         uint16_t i;
 479         uint16_t j;
 480         uint16_t k;
 481         uint32_t temp;
 482         uint32_t datal;
 483         uint32_t datar;
 484 
 485         j = 0;
 486         for (i = 0; i < BLF_N + 2; i++) {
 487                 /* Extract 4 int8 to 1 int32 from keystream */
 488                 temp = Blowfish_stream2word(key, keybytes, &j);
 489                 c->P[i] = c->P[i] ^ temp;
 490         }
 491 
 492         j = 0;
 493         datal = 0x00000000;
 494         datar = 0x00000000;
 495         for (i = 0; i < BLF_N + 2; i += 2) {
 496                 datal ^= Blowfish_stream2word(data, databytes, &j);
 497                 datar ^= Blowfish_stream2word(data, databytes, &j);
 498                 Blowfish_encipher(c, &datal, &datar);
 499 
 500                 c->P[i] = datal;
 501                 c->P[i + 1] = datar;
 502         }
 503 
 504         for (i = 0; i < 4; i++) {
 505                 for (k = 0; k < 256; k += 2) {
 506                         datal ^= Blowfish_stream2word(data, databytes, &j);
 507                         datar ^= Blowfish_stream2word(data, databytes, &j);
 508                         Blowfish_encipher(c, &datal, &datar);
 509 
 510                         c->S[i][k] = datal;
 511                         c->S[i][k + 1] = datar;
 512                 }
 513         }
 514 }
 515 
 516 void
 517 blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
 518 {
 519         /* Initialize S-boxes and subkeys with Pi */
 520         Blowfish_initstate(c);
 521 
 522         /* Transform S-boxes and subkeys with key */
 523         Blowfish_expand0state(c, k, len);
 524 }
 525 
 526 void
 527 blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
 528 {
 529         uint32_t *d;
 530         uint16_t i;
 531 
 532         d = data;
 533         for (i = 0; i < blocks; i++) {
 534                 Blowfish_encipher(c, d, d + 1);
 535                 d += 2;
 536         }
 537 }
 538 
 539 void
 540 blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
 541 {
 542         uint32_t *d;
 543         uint16_t i;
 544 
 545         d = data;
 546         for (i = 0; i < blocks; i++) {
 547                 Blowfish_decipher(c, d, d + 1);
 548                 d += 2;
 549         }
 550 }
 551 
 552 void
 553 blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
 554 {
 555         uint32_t l, r;
 556         uint32_t i;
 557 
 558         for (i = 0; i < len; i += 8) {
 559                 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
 560                 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
 561                 Blowfish_encipher(c, &l, &r);
 562                 data[0] = l >> 24 & 0xff;
 563                 data[1] = l >> 16 & 0xff;
 564                 data[2] = l >> 8 & 0xff;
 565                 data[3] = l & 0xff;
 566                 data[4] = r >> 24 & 0xff;
 567                 data[5] = r >> 16 & 0xff;
 568                 data[6] = r >> 8 & 0xff;
 569                 data[7] = r & 0xff;
 570                 data += 8;
 571         }
 572 }
 573 
 574 void
 575 blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
 576 {
 577         uint32_t l, r;
 578         uint32_t i;
 579 
 580         for (i = 0; i < len; i += 8) {
 581                 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
 582                 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
 583                 Blowfish_decipher(c, &l, &r);
 584                 data[0] = l >> 24 & 0xff;
 585                 data[1] = l >> 16 & 0xff;
 586                 data[2] = l >> 8 & 0xff;
 587                 data[3] = l & 0xff;
 588                 data[4] = r >> 24 & 0xff;
 589                 data[5] = r >> 16 & 0xff;
 590                 data[6] = r >> 8 & 0xff;
 591                 data[7] = r & 0xff;
 592                 data += 8;
 593         }
 594 }
 595 
 596 void
 597 blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
 598 {
 599         uint32_t l, r;
 600         uint32_t i, j;
 601 
 602         for (i = 0; i < len; i += 8) {
 603                 for (j = 0; j < 8; j++)
 604                         data[j] ^= iv[j];
 605                 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
 606                 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
 607                 Blowfish_encipher(c, &l, &r);
 608                 data[0] = l >> 24 & 0xff;
 609                 data[1] = l >> 16 & 0xff;
 610                 data[2] = l >> 8 & 0xff;
 611                 data[3] = l & 0xff;
 612                 data[4] = r >> 24 & 0xff;
 613                 data[5] = r >> 16 & 0xff;
 614                 data[6] = r >> 8 & 0xff;
 615                 data[7] = r & 0xff;
 616                 iv = data;
 617                 data += 8;
 618         }
 619 }
 620 
 621 void
 622 blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
 623 {
 624         uint32_t l, r;
 625         uint8_t *iv;
 626         uint32_t i, j;
 627 
 628         iv = data + len - 16;
 629         data = data + len - 8;
 630         for (i = len - 8; i >= 8; i -= 8) {
 631                 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
 632                 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
 633                 Blowfish_decipher(c, &l, &r);
 634                 data[0] = l >> 24 & 0xff;
 635                 data[1] = l >> 16 & 0xff;
 636                 data[2] = l >> 8 & 0xff;
 637                 data[3] = l & 0xff;
 638                 data[4] = r >> 24 & 0xff;
 639                 data[5] = r >> 16 & 0xff;
 640                 data[6] = r >> 8 & 0xff;
 641                 data[7] = r & 0xff;
 642                 for (j = 0; j < 8; j++)
 643                         data[j] ^= iv[j];
 644                 iv -= 8;
 645                 data -= 8;
 646         }
 647         l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
 648         r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
 649         Blowfish_decipher(c, &l, &r);
 650         data[0] = l >> 24 & 0xff;
 651         data[1] = l >> 16 & 0xff;
 652         data[2] = l >> 8 & 0xff;
 653         data[3] = l & 0xff;
 654         data[4] = r >> 24 & 0xff;
 655         data[5] = r >> 16 & 0xff;
 656         data[6] = r >> 8 & 0xff;
 657         data[7] = r & 0xff;
 658         for (j = 0; j < 8; j++)
 659                 data[j] ^= iva[j];
 660 }
 661 
 662 #if 0
 663 void
 664 report(uint32_t data[], uint16_t len)
 665 {
 666         uint16_t i;
 667         for (i = 0; i < len; i += 2)
 668                 printf("Block %0hd: %08lx %08lx.\n",
 669                     i / 2, data[i], data[i + 1]);
 670 }
 671 void
 672 main(void)
 673 {
 674 
 675         blf_ctx c;
 676         char    key[] = "AAAAA";
 677         char    key2[] = "abcdefghijklmnopqrstuvwxyz";
 678 
 679         uint32_t data[10];
 680         uint32_t data2[] =
 681         {0x424c4f57l, 0x46495348l};
 682 
 683         uint16_t i;
 684 
 685         /* First test */
 686         for (i = 0; i < 10; i++)
 687                 data[i] = i;
 688 
 689         blf_key(&c, (uint8_t *) key, 5);
 690         blf_enc(&c, data, 5);
 691         blf_dec(&c, data, 1);
 692         blf_dec(&c, data + 2, 4);
 693         printf("Should read as 0 - 9.\n");
 694         report(data, 10);
 695 
 696         /* Second test */
 697         blf_key(&c, (uint8_t *) key2, strlen(key2));
 698         blf_enc(&c, data2, 1);
 699         printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
 700         report(data2, 2);
 701         blf_dec(&c, data2, 1);
 702         report(data2, 2);
 703 }
 704 #endif