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