Add a warning stipulating how things should be coded in ossl_init_base
[openssl.git] / crypto / bf / bf_enc.c
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_locl.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 #ifndef BF_DEFAULT_OPTIONS
64
65 void BF_decrypt(BF_LONG *data, const BF_KEY *key)
66 {
67     register BF_LONG l, r;
68     register const BF_LONG *p, *s;
69
70     p = key->P;
71     s = &(key->S[0]);
72     l = data[0];
73     r = data[1];
74
75     l ^= p[BF_ROUNDS + 1];
76 #  if BF_ROUNDS == 20
77     BF_ENC(r, l, s, p[20]);
78     BF_ENC(l, r, s, p[19]);
79     BF_ENC(r, l, s, p[18]);
80     BF_ENC(l, r, s, p[17]);
81 #  endif
82     BF_ENC(r, l, s, p[16]);
83     BF_ENC(l, r, s, p[15]);
84     BF_ENC(r, l, s, p[14]);
85     BF_ENC(l, r, s, p[13]);
86     BF_ENC(r, l, s, p[12]);
87     BF_ENC(l, r, s, p[11]);
88     BF_ENC(r, l, s, p[10]);
89     BF_ENC(l, r, s, p[9]);
90     BF_ENC(r, l, s, p[8]);
91     BF_ENC(l, r, s, p[7]);
92     BF_ENC(r, l, s, p[6]);
93     BF_ENC(l, r, s, p[5]);
94     BF_ENC(r, l, s, p[4]);
95     BF_ENC(l, r, s, p[3]);
96     BF_ENC(r, l, s, p[2]);
97     BF_ENC(l, r, s, p[1]);
98     r ^= p[0];
99
100     data[1] = l & 0xffffffffU;
101     data[0] = r & 0xffffffffU;
102 }
103
104 void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
105                     const BF_KEY *schedule, unsigned char *ivec, int encrypt)
106 {
107     register BF_LONG tin0, tin1;
108     register BF_LONG tout0, tout1, xor0, xor1;
109     register long l = length;
110     BF_LONG tin[2];
111
112     if (encrypt) {
113         n2l(ivec, tout0);
114         n2l(ivec, tout1);
115         ivec -= 8;
116         for (l -= 8; l >= 0; l -= 8) {
117             n2l(in, tin0);
118             n2l(in, tin1);
119             tin0 ^= tout0;
120             tin1 ^= tout1;
121             tin[0] = tin0;
122             tin[1] = tin1;
123             BF_encrypt(tin, schedule);
124             tout0 = tin[0];
125             tout1 = tin[1];
126             l2n(tout0, out);
127             l2n(tout1, out);
128         }
129         if (l != -8) {
130             n2ln(in, tin0, tin1, l + 8);
131             tin0 ^= tout0;
132             tin1 ^= tout1;
133             tin[0] = tin0;
134             tin[1] = tin1;
135             BF_encrypt(tin, schedule);
136             tout0 = tin[0];
137             tout1 = tin[1];
138             l2n(tout0, out);
139             l2n(tout1, out);
140         }
141         l2n(tout0, ivec);
142         l2n(tout1, ivec);
143     } else {
144         n2l(ivec, xor0);
145         n2l(ivec, xor1);
146         ivec -= 8;
147         for (l -= 8; l >= 0; l -= 8) {
148             n2l(in, tin0);
149             n2l(in, tin1);
150             tin[0] = tin0;
151             tin[1] = tin1;
152             BF_decrypt(tin, schedule);
153             tout0 = tin[0] ^ xor0;
154             tout1 = tin[1] ^ xor1;
155             l2n(tout0, out);
156             l2n(tout1, out);
157             xor0 = tin0;
158             xor1 = tin1;
159         }
160         if (l != -8) {
161             n2l(in, tin0);
162             n2l(in, tin1);
163             tin[0] = tin0;
164             tin[1] = tin1;
165             BF_decrypt(tin, schedule);
166             tout0 = tin[0] ^ xor0;
167             tout1 = tin[1] ^ xor1;
168             l2nn(tout0, tout1, out, l + 8);
169             xor0 = tin0;
170             xor1 = tin1;
171         }
172         l2n(xor0, ivec);
173         l2n(xor1, ivec);
174     }
175     tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
176     tin[0] = tin[1] = 0;
177 }
178
179 #endif