1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/blowfish.h> 11 #include "bf_local.h" 12 13 /* 14 * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From 15 * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE 16 * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) 17 */ 18 19 #if (BF_ROUNDS != 16) && (BF_ROUNDS != 20) 20 # error If you set BF_ROUNDS to some value other than 16 or 20, you will have \ 21 to modify the code. 22 #endif 23 24 void BF_encrypt(BF_LONG *data, const BF_KEY *key) 25 { 26 register BF_LONG l, r; 27 register const BF_LONG *p, *s; 28 29 p = key->P; 30 s = &(key->S[0]); 31 l = data[0]; 32 r = data[1]; 33 34 l ^= p[0]; 35 BF_ENC(r, l, s, p[1]); 36 BF_ENC(l, r, s, p[2]); 37 BF_ENC(r, l, s, p[3]); 38 BF_ENC(l, r, s, p[4]); 39 BF_ENC(r, l, s, p[5]); 40 BF_ENC(l, r, s, p[6]); 41 BF_ENC(r, l, s, p[7]); 42 BF_ENC(l, r, s, p[8]); 43 BF_ENC(r, l, s, p[9]); 44 BF_ENC(l, r, s, p[10]); 45 BF_ENC(r, l, s, p[11]); 46 BF_ENC(l, r, s, p[12]); 47 BF_ENC(r, l, s, p[13]); 48 BF_ENC(l, r, s, p[14]); 49 BF_ENC(r, l, s, p[15]); 50 BF_ENC(l, r, s, p[16]); 51 # if BF_ROUNDS == 20 52 BF_ENC(r, l, s, p[17]); 53 BF_ENC(l, r, s, p[18]); 54 BF_ENC(r, l, s, p[19]); 55 BF_ENC(l, r, s, p[20]); 56 # endif 57 r ^= p[BF_ROUNDS + 1]; 58 59 data[1] = l & 0xffffffffU; 60 data[0] = r & 0xffffffffU; 61 } 62 63 void BF_decrypt(BF_LONG *data, const BF_KEY *key) 64 { 65 register BF_LONG l, r; 66 register const BF_LONG *p, *s; 67 68 p = key->P; 69 s = &(key->S[0]); 70 l = data[0]; 71 r = data[1]; 72 73 l ^= p[BF_ROUNDS + 1]; 74 # if BF_ROUNDS == 20 75 BF_ENC(r, l, s, p[20]); 76 BF_ENC(l, r, s, p[19]); 77 BF_ENC(r, l, s, p[18]); 78 BF_ENC(l, r, s, p[17]); 79 # endif 80 BF_ENC(r, l, s, p[16]); 81 BF_ENC(l, r, s, p[15]); 82 BF_ENC(r, l, s, p[14]); 83 BF_ENC(l, r, s, p[13]); 84 BF_ENC(r, l, s, p[12]); 85 BF_ENC(l, r, s, p[11]); 86 BF_ENC(r, l, s, p[10]); 87 BF_ENC(l, r, s, p[9]); 88 BF_ENC(r, l, s, p[8]); 89 BF_ENC(l, r, s, p[7]); 90 BF_ENC(r, l, s, p[6]); 91 BF_ENC(l, r, s, p[5]); 92 BF_ENC(r, l, s, p[4]); 93 BF_ENC(l, r, s, p[3]); 94 BF_ENC(r, l, s, p[2]); 95 BF_ENC(l, r, s, p[1]); 96 r ^= p[0]; 97 98 data[1] = l & 0xffffffffU; 99 data[0] = r & 0xffffffffU; 100 } 101 102 void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, 103 const BF_KEY *schedule, unsigned char *ivec, int encrypt) 104 { 105 register BF_LONG tin0, tin1; 106 register BF_LONG tout0, tout1, xor0, xor1; 107 register long l = length; 108 BF_LONG tin[2]; 109 110 if (encrypt) { 111 n2l(ivec, tout0); 112 n2l(ivec, tout1); 113 ivec -= 8; 114 for (l -= 8; l >= 0; l -= 8) { 115 n2l(in, tin0); 116 n2l(in, tin1); 117 tin0 ^= tout0; 118 tin1 ^= tout1; 119 tin[0] = tin0; 120 tin[1] = tin1; 121 BF_encrypt(tin, schedule); 122 tout0 = tin[0]; 123 tout1 = tin[1]; 124 l2n(tout0, out); 125 l2n(tout1, out); 126 } 127 if (l != -8) { 128 n2ln(in, tin0, tin1, l + 8); 129 tin0 ^= tout0; 130 tin1 ^= tout1; 131 tin[0] = tin0; 132 tin[1] = tin1; 133 BF_encrypt(tin, schedule); 134 tout0 = tin[0]; 135 tout1 = tin[1]; 136 l2n(tout0, out); 137 l2n(tout1, out); 138 } 139 l2n(tout0, ivec); 140 l2n(tout1, ivec); 141 } else { 142 n2l(ivec, xor0); 143 n2l(ivec, xor1); 144 ivec -= 8; 145 for (l -= 8; l >= 0; l -= 8) { 146 n2l(in, tin0); 147 n2l(in, tin1); 148 tin[0] = tin0; 149 tin[1] = tin1; 150 BF_decrypt(tin, schedule); 151 tout0 = tin[0] ^ xor0; 152 tout1 = tin[1] ^ xor1; 153 l2n(tout0, out); 154 l2n(tout1, out); 155 xor0 = tin0; 156 xor1 = tin1; 157 } 158 if (l != -8) { 159 n2l(in, tin0); 160 n2l(in, tin1); 161 tin[0] = tin0; 162 tin[1] = tin1; 163 BF_decrypt(tin, schedule); 164 tout0 = tin[0] ^ xor0; 165 tout1 = tin[1] ^ xor1; 166 l2nn(tout0, tout1, out, l + 8); 167 xor0 = tin0; 168 xor1 = tin1; 169 } 170 l2n(xor0, ivec); 171 l2n(xor1, ivec); 172 } 173 tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 174 tin[0] = tin[1] = 0; 175 } 176