1 /* crypto/bf/bf_enc.c */ 2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 307