1 /* crypto/bf/bf_enc.c */
   2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
   3  * All rights reserved.
   4  *
   5  * This package is an SSL implementation written
   6  * by Eric Young (eay@cryptsoft.com).
   7  * The implementation was written so as to conform with Netscapes SSL.
   8  * 
   9  * This library is free for commercial and non-commercial use as long as
  10  * the following conditions are aheared to.  The following conditions
  11  * apply to all code found in this distribution, be it the RC4, RSA,
  12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  13  * included with this distribution is covered by the same copyright terms
  14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15  * 
  16  * Copyright remains Eric Young's, and as such any Copyright notices in
  17  * the code are not to be removed.
  18  * If this package is used in a product, Eric Young should be given attribution
  19  * as the author of the parts of the library used.
  20  * This can be in the form of a textual message at program startup or
  21  * in documentation (online or textual) provided with the package.
  22  * 
  23  * Redistribution and use in source and binary forms, with or without
  24  * modification, are permitted provided that the following conditions
  25  * are met:
  26  * 1. Redistributions of source code must retain the copyright
  27  *    notice, this list of conditions and the following disclaimer.
  28  * 2. Redistributions in binary form must reproduce the above copyright
  29  *    notice, this list of conditions and the following disclaimer in the
  30  *    documentation and/or other materials provided with the distribution.
  31  * 3. All advertising materials mentioning features or use of this software
  32  *    must display the following acknowledgement:
  33  *    "This product includes cryptographic software written by
  34  *     Eric Young (eay@cryptsoft.com)"
  35  *    The word 'cryptographic' can be left out if the rouines from the library
  36  *    being used are not cryptographic related :-).
  37  * 4. If you include any Windows specific code (or a derivative thereof) from 
  38  *    the apps directory (application code) you must include an acknowledgement:
  39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40  * 
  41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51  * SUCH DAMAGE.
  52  * 
  53  * The licence and distribution terms for any publically available version or
  54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  55  * copied and put under another distribution licence
  56  * [including the GNU Public Licence.]
  57  */
  58 
  59 #include <openssl/blowfish.h>
  60 #include "bf_locl.h"
  61 
  62 /* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
  63  * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
  64  * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
  65  */
  66 
  67 #if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
  68 #error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
  69 to modify the code.
  70 #endif
  71 
  72 void BF_encrypt(BF_LONG *data, const BF_KEY *key)
  73         {
  74 #ifndef BF_PTR2
  75         register BF_LONG l,r;
  76         register const BF_LONG *p,*s;
  77 
  78         p=key->P;
  79         s= &(key->S[0]);
  80         l=data[0];
  81         r=data[1];
  82 
  83         l^=p[0];
  84         BF_ENC(r,l,s,p[ 1]);
  85         BF_ENC(l,r,s,p[ 2]);
  86         BF_ENC(r,l,s,p[ 3]);
  87         BF_ENC(l,r,s,p[ 4]);
  88         BF_ENC(r,l,s,p[ 5]);
  89         BF_ENC(l,r,s,p[ 6]);
  90         BF_ENC(r,l,s,p[ 7]);
  91         BF_ENC(l,r,s,p[ 8]);
  92         BF_ENC(r,l,s,p[ 9]);
  93         BF_ENC(l,r,s,p[10]);
  94         BF_ENC(r,l,s,p[11]);
  95         BF_ENC(l,r,s,p[12]);
  96         BF_ENC(r,l,s,p[13]);
  97         BF_ENC(l,r,s,p[14]);
  98         BF_ENC(r,l,s,p[15]);
  99         BF_ENC(l,r,s,p[16]);
 100 #if BF_ROUNDS == 20
 101         BF_ENC(r,l,s,p[17]);
 102         BF_ENC(l,r,s,p[18]);
 103         BF_ENC(r,l,s,p[19]);
 104         BF_ENC(l,r,s,p[20]);
 105 #endif
 106         r^=p[BF_ROUNDS+1];
 107 
 108         data[1]=l&0xffffffffL;
 109         data[0]=r&0xffffffffL;
 110 #else
 111         register BF_LONG l,r,t,*k;
 112 
 113         l=data[0];
 114         r=data[1];
 115         k=(BF_LONG*)key;
 116 
 117         l^=k[0];
 118         BF_ENC(r,l,k, 1);
 119         BF_ENC(l,r,k, 2);
 120         BF_ENC(r,l,k, 3);
 121         BF_ENC(l,r,k, 4);
 122         BF_ENC(r,l,k, 5);
 123         BF_ENC(l,r,k, 6);
 124         BF_ENC(r,l,k, 7);
 125         BF_ENC(l,r,k, 8);
 126         BF_ENC(r,l,k, 9);
 127         BF_ENC(l,r,k,10);
 128         BF_ENC(r,l,k,11);
 129         BF_ENC(l,r,k,12);
 130         BF_ENC(r,l,k,13);
 131         BF_ENC(l,r,k,14);
 132         BF_ENC(r,l,k,15);
 133         BF_ENC(l,r,k,16);
 134 #if BF_ROUNDS == 20
 135         BF_ENC(r,l,k,17);
 136         BF_ENC(l,r,k,18);
 137         BF_ENC(r,l,k,19);
 138         BF_ENC(l,r,k,20);
 139 #endif
 140         r^=k[BF_ROUNDS+1];
 141 
 142         data[1]=l&0xffffffffL;
 143         data[0]=r&0xffffffffL;
 144 #endif
 145         }
 146 
 147 #ifndef BF_DEFAULT_OPTIONS
 148 
 149 void BF_decrypt(BF_LONG *data, const BF_KEY *key)
 150         {
 151 #ifndef BF_PTR2
 152         register BF_LONG l,r;
 153         register const BF_LONG *p,*s;
 154 
 155         p=key->P;
 156         s= &(key->S[0]);
 157         l=data[0];
 158         r=data[1];
 159 
 160         l^=p[BF_ROUNDS+1];
 161 #if BF_ROUNDS == 20
 162         BF_ENC(r,l,s,p[20]);
 163         BF_ENC(l,r,s,p[19]);
 164         BF_ENC(r,l,s,p[18]);
 165         BF_ENC(l,r,s,p[17]);
 166 #endif
 167         BF_ENC(r,l,s,p[16]);
 168         BF_ENC(l,r,s,p[15]);
 169         BF_ENC(r,l,s,p[14]);
 170         BF_ENC(l,r,s,p[13]);
 171         BF_ENC(r,l,s,p[12]);
 172         BF_ENC(l,r,s,p[11]);
 173         BF_ENC(r,l,s,p[10]);
 174         BF_ENC(l,r,s,p[ 9]);
 175         BF_ENC(r,l,s,p[ 8]);
 176         BF_ENC(l,r,s,p[ 7]);
 177         BF_ENC(r,l,s,p[ 6]);
 178         BF_ENC(l,r,s,p[ 5]);
 179         BF_ENC(r,l,s,p[ 4]);
 180         BF_ENC(l,r,s,p[ 3]);
 181         BF_ENC(r,l,s,p[ 2]);
 182         BF_ENC(l,r,s,p[ 1]);
 183         r^=p[0];
 184 
 185         data[1]=l&0xffffffffL;
 186         data[0]=r&0xffffffffL;
 187 #else
 188         register BF_LONG l,r,t,*k;
 189 
 190         l=data[0];
 191         r=data[1];
 192         k=(BF_LONG *)key;
 193 
 194         l^=k[BF_ROUNDS+1];
 195 #if BF_ROUNDS == 20
 196         BF_ENC(r,l,k,20);
 197         BF_ENC(l,r,k,19);
 198         BF_ENC(r,l,k,18);
 199         BF_ENC(l,r,k,17);
 200 #endif
 201         BF_ENC(r,l,k,16);
 202         BF_ENC(l,r,k,15);
 203         BF_ENC(r,l,k,14);
 204         BF_ENC(l,r,k,13);
 205         BF_ENC(r,l,k,12);
 206         BF_ENC(l,r,k,11);
 207         BF_ENC(r,l,k,10);
 208         BF_ENC(l,r,k, 9);
 209         BF_ENC(r,l,k, 8);
 210         BF_ENC(l,r,k, 7);
 211         BF_ENC(r,l,k, 6);
 212         BF_ENC(l,r,k, 5);
 213         BF_ENC(r,l,k, 4);
 214         BF_ENC(l,r,k, 3);
 215         BF_ENC(r,l,k, 2);
 216         BF_ENC(l,r,k, 1);
 217         r^=k[0];
 218 
 219         data[1]=l&0xffffffffL;
 220         data[0]=r&0xffffffffL;
 221 #endif
 222         }
 223 
 224 void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
 225              const BF_KEY *schedule, unsigned char *ivec, int encrypt)
 226         {
 227         register BF_LONG tin0,tin1;
 228         register BF_LONG tout0,tout1,xor0,xor1;
 229         register long l=length;
 230         BF_LONG tin[2];
 231 
 232         if (encrypt)
 233                 {
 234                 n2l(ivec,tout0);
 235                 n2l(ivec,tout1);
 236                 ivec-=8;
 237                 for (l-=8; l>=0; l-=8)
 238                         {
 239                         n2l(in,tin0);
 240                         n2l(in,tin1);
 241                         tin0^=tout0;
 242                         tin1^=tout1;
 243                         tin[0]=tin0;
 244                         tin[1]=tin1;
 245                         BF_encrypt(tin,schedule);
 246                         tout0=tin[0];
 247                         tout1=tin[1];
 248                         l2n(tout0,out);
 249                         l2n(tout1,out);
 250                         }
 251                 if (l != -8)
 252                         {
 253                         n2ln(in,tin0,tin1,l+8);
 254                         tin0^=tout0;
 255                         tin1^=tout1;
 256                         tin[0]=tin0;
 257                         tin[1]=tin1;
 258                         BF_encrypt(tin,schedule);
 259                         tout0=tin[0];
 260                         tout1=tin[1];
 261                         l2n(tout0,out);
 262                         l2n(tout1,out);
 263                         }
 264                 l2n(tout0,ivec);
 265                 l2n(tout1,ivec);
 266                 }
 267         else
 268                 {
 269                 n2l(ivec,xor0);
 270                 n2l(ivec,xor1);
 271                 ivec-=8;
 272                 for (l-=8; l>=0; l-=8)
 273                         {
 274                         n2l(in,tin0);
 275                         n2l(in,tin1);
 276                         tin[0]=tin0;
 277                         tin[1]=tin1;
 278                         BF_decrypt(tin,schedule);
 279                         tout0=tin[0]^xor0;
 280                         tout1=tin[1]^xor1;
 281                         l2n(tout0,out);
 282                         l2n(tout1,out);
 283                         xor0=tin0;
 284                         xor1=tin1;
 285                         }
 286                 if (l != -8)
 287                         {
 288                         n2l(in,tin0);
 289                         n2l(in,tin1);
 290                         tin[0]=tin0;
 291                         tin[1]=tin1;
 292                         BF_decrypt(tin,schedule);
 293                         tout0=tin[0]^xor0;
 294                         tout1=tin[1]^xor1;
 295                         l2nn(tout0,tout1,out,l+8);
 296                         xor0=tin0;
 297                         xor1=tin1;
 298                         }
 299                 l2n(xor0,ivec);
 300                 l2n(xor1,ivec);
 301                 }
 302         tin0=tin1=tout0=tout1=xor0=xor1=0;
 303         tin[0]=tin[1]=0;
 304         }
 305 
 306 #endif