xref: /openssl/crypto/rc5/rc5_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  * RC5 low level APIs are deprecated for public use, but still ok for internal
12  * use.
13  */
14 #include "internal/deprecated.h"
15 
16 #include <stdio.h>
17 #include <openssl/rc5.h>
18 #include "rc5_local.h"
19 
RC5_32_cbc_encrypt(const unsigned char * in,unsigned char * out,long length,RC5_32_KEY * ks,unsigned char * iv,int encrypt)20 void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
21                         long length, RC5_32_KEY *ks, unsigned char *iv,
22                         int encrypt)
23 {
24     register unsigned long tin0, tin1;
25     register unsigned long tout0, tout1, xor0, xor1;
26     register long l = length;
27     unsigned long tin[2];
28 
29     if (encrypt) {
30         c2l(iv, tout0);
31         c2l(iv, tout1);
32         iv -= 8;
33         for (l -= 8; l >= 0; l -= 8) {
34             c2l(in, tin0);
35             c2l(in, tin1);
36             tin0 ^= tout0;
37             tin1 ^= tout1;
38             tin[0] = tin0;
39             tin[1] = tin1;
40             RC5_32_encrypt(tin, ks);
41             tout0 = tin[0];
42             l2c(tout0, out);
43             tout1 = tin[1];
44             l2c(tout1, out);
45         }
46         if (l != -8) {
47             c2ln(in, tin0, tin1, l + 8);
48             tin0 ^= tout0;
49             tin1 ^= tout1;
50             tin[0] = tin0;
51             tin[1] = tin1;
52             RC5_32_encrypt(tin, ks);
53             tout0 = tin[0];
54             l2c(tout0, out);
55             tout1 = tin[1];
56             l2c(tout1, out);
57         }
58         l2c(tout0, iv);
59         l2c(tout1, iv);
60     } else {
61         c2l(iv, xor0);
62         c2l(iv, xor1);
63         iv -= 8;
64         for (l -= 8; l >= 0; l -= 8) {
65             c2l(in, tin0);
66             tin[0] = tin0;
67             c2l(in, tin1);
68             tin[1] = tin1;
69             RC5_32_decrypt(tin, ks);
70             tout0 = tin[0] ^ xor0;
71             tout1 = tin[1] ^ xor1;
72             l2c(tout0, out);
73             l2c(tout1, out);
74             xor0 = tin0;
75             xor1 = tin1;
76         }
77         if (l != -8) {
78             c2l(in, tin0);
79             tin[0] = tin0;
80             c2l(in, tin1);
81             tin[1] = tin1;
82             RC5_32_decrypt(tin, ks);
83             tout0 = tin[0] ^ xor0;
84             tout1 = tin[1] ^ xor1;
85             l2cn(tout0, tout1, out, l + 8);
86             xor0 = tin0;
87             xor1 = tin1;
88         }
89         l2c(xor0, iv);
90         l2c(xor1, iv);
91     }
92     tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
93     tin[0] = tin[1] = 0;
94 }
95 
RC5_32_encrypt(unsigned long * d,RC5_32_KEY * key)96 void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key)
97 {
98     RC5_32_INT a, b, *s;
99 
100     s = key->data;
101 
102     a = d[0] + s[0];
103     b = d[1] + s[1];
104     E_RC5_32(a, b, s, 2);
105     E_RC5_32(a, b, s, 4);
106     E_RC5_32(a, b, s, 6);
107     E_RC5_32(a, b, s, 8);
108     E_RC5_32(a, b, s, 10);
109     E_RC5_32(a, b, s, 12);
110     E_RC5_32(a, b, s, 14);
111     E_RC5_32(a, b, s, 16);
112     if (key->rounds == 12) {
113         E_RC5_32(a, b, s, 18);
114         E_RC5_32(a, b, s, 20);
115         E_RC5_32(a, b, s, 22);
116         E_RC5_32(a, b, s, 24);
117     } else if (key->rounds == 16) {
118         /* Do a full expansion to avoid a jump */
119         E_RC5_32(a, b, s, 18);
120         E_RC5_32(a, b, s, 20);
121         E_RC5_32(a, b, s, 22);
122         E_RC5_32(a, b, s, 24);
123         E_RC5_32(a, b, s, 26);
124         E_RC5_32(a, b, s, 28);
125         E_RC5_32(a, b, s, 30);
126         E_RC5_32(a, b, s, 32);
127     }
128     d[0] = a;
129     d[1] = b;
130 }
131 
RC5_32_decrypt(unsigned long * d,RC5_32_KEY * key)132 void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key)
133 {
134     RC5_32_INT a, b, *s;
135 
136     s = key->data;
137 
138     a = d[0];
139     b = d[1];
140     if (key->rounds == 16) {
141         D_RC5_32(a, b, s, 32);
142         D_RC5_32(a, b, s, 30);
143         D_RC5_32(a, b, s, 28);
144         D_RC5_32(a, b, s, 26);
145         /* Do a full expansion to avoid a jump */
146         D_RC5_32(a, b, s, 24);
147         D_RC5_32(a, b, s, 22);
148         D_RC5_32(a, b, s, 20);
149         D_RC5_32(a, b, s, 18);
150     } else if (key->rounds == 12) {
151         D_RC5_32(a, b, s, 24);
152         D_RC5_32(a, b, s, 22);
153         D_RC5_32(a, b, s, 20);
154         D_RC5_32(a, b, s, 18);
155     }
156     D_RC5_32(a, b, s, 16);
157     D_RC5_32(a, b, s, 14);
158     D_RC5_32(a, b, s, 12);
159     D_RC5_32(a, b, s, 10);
160     D_RC5_32(a, b, s, 8);
161     D_RC5_32(a, b, s, 6);
162     D_RC5_32(a, b, s, 4);
163     D_RC5_32(a, b, s, 2);
164     d[0] = a - s[0];
165     d[1] = b - s[1];
166 }
167