1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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 \
21to modify the code.
22#endif
23
24void 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
63void 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
102void 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