]>
Commit | Line | Data |
---|---|---|
2039c421 RS |
1 | /* |
2 | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. | |
58964a49 | 3 | * |
5e4435a7 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
2039c421 RS |
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 | |
58964a49 RE |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
ec577822 | 11 | #include <openssl/rc5.h> |
58964a49 RE |
12 | #include "rc5_locl.h" |
13 | ||
1921eaad | 14 | void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, |
0f113f3e MC |
15 | long length, RC5_32_KEY *ks, unsigned char *iv, |
16 | int encrypt) | |
17 | { | |
18 | register unsigned long tin0, tin1; | |
19 | register unsigned long tout0, tout1, xor0, xor1; | |
20 | register long l = length; | |
21 | unsigned long tin[2]; | |
58964a49 | 22 | |
0f113f3e MC |
23 | if (encrypt) { |
24 | c2l(iv, tout0); | |
25 | c2l(iv, tout1); | |
26 | iv -= 8; | |
27 | for (l -= 8; l >= 0; l -= 8) { | |
28 | c2l(in, tin0); | |
29 | c2l(in, tin1); | |
30 | tin0 ^= tout0; | |
31 | tin1 ^= tout1; | |
32 | tin[0] = tin0; | |
33 | tin[1] = tin1; | |
34 | RC5_32_encrypt(tin, ks); | |
35 | tout0 = tin[0]; | |
36 | l2c(tout0, out); | |
37 | tout1 = tin[1]; | |
38 | l2c(tout1, out); | |
39 | } | |
40 | if (l != -8) { | |
41 | c2ln(in, tin0, tin1, l + 8); | |
42 | tin0 ^= tout0; | |
43 | tin1 ^= tout1; | |
44 | tin[0] = tin0; | |
45 | tin[1] = tin1; | |
46 | RC5_32_encrypt(tin, ks); | |
47 | tout0 = tin[0]; | |
48 | l2c(tout0, out); | |
49 | tout1 = tin[1]; | |
50 | l2c(tout1, out); | |
51 | } | |
52 | l2c(tout0, iv); | |
53 | l2c(tout1, iv); | |
54 | } else { | |
55 | c2l(iv, xor0); | |
56 | c2l(iv, xor1); | |
57 | iv -= 8; | |
58 | for (l -= 8; l >= 0; l -= 8) { | |
59 | c2l(in, tin0); | |
60 | tin[0] = tin0; | |
61 | c2l(in, tin1); | |
62 | tin[1] = tin1; | |
63 | RC5_32_decrypt(tin, ks); | |
64 | tout0 = tin[0] ^ xor0; | |
65 | tout1 = tin[1] ^ xor1; | |
66 | l2c(tout0, out); | |
67 | l2c(tout1, out); | |
68 | xor0 = tin0; | |
69 | xor1 = tin1; | |
70 | } | |
71 | if (l != -8) { | |
72 | c2l(in, tin0); | |
73 | tin[0] = tin0; | |
74 | c2l(in, tin1); | |
75 | tin[1] = tin1; | |
76 | RC5_32_decrypt(tin, ks); | |
77 | tout0 = tin[0] ^ xor0; | |
78 | tout1 = tin[1] ^ xor1; | |
79 | l2cn(tout0, tout1, out, l + 8); | |
80 | xor0 = tin0; | |
81 | xor1 = tin1; | |
82 | } | |
83 | l2c(xor0, iv); | |
84 | l2c(xor1, iv); | |
85 | } | |
86 | tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; | |
87 | tin[0] = tin[1] = 0; | |
88 | } | |
58964a49 | 89 | |
6b691a5c | 90 | void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key) |
0f113f3e MC |
91 | { |
92 | RC5_32_INT a, b, *s; | |
58964a49 | 93 | |
0f113f3e | 94 | s = key->data; |
58964a49 | 95 | |
0f113f3e MC |
96 | a = d[0] + s[0]; |
97 | b = d[1] + s[1]; | |
98 | E_RC5_32(a, b, s, 2); | |
99 | E_RC5_32(a, b, s, 4); | |
100 | E_RC5_32(a, b, s, 6); | |
101 | E_RC5_32(a, b, s, 8); | |
102 | E_RC5_32(a, b, s, 10); | |
103 | E_RC5_32(a, b, s, 12); | |
104 | E_RC5_32(a, b, s, 14); | |
105 | E_RC5_32(a, b, s, 16); | |
106 | if (key->rounds == 12) { | |
107 | E_RC5_32(a, b, s, 18); | |
108 | E_RC5_32(a, b, s, 20); | |
109 | E_RC5_32(a, b, s, 22); | |
110 | E_RC5_32(a, b, s, 24); | |
111 | } else if (key->rounds == 16) { | |
112 | /* Do a full expansion to avoid a jump */ | |
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 | E_RC5_32(a, b, s, 26); | |
118 | E_RC5_32(a, b, s, 28); | |
119 | E_RC5_32(a, b, s, 30); | |
120 | E_RC5_32(a, b, s, 32); | |
121 | } | |
122 | d[0] = a; | |
123 | d[1] = b; | |
124 | } | |
58964a49 | 125 | |
6b691a5c | 126 | void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key) |
0f113f3e MC |
127 | { |
128 | RC5_32_INT a, b, *s; | |
58964a49 | 129 | |
0f113f3e | 130 | s = key->data; |
58964a49 | 131 | |
0f113f3e MC |
132 | a = d[0]; |
133 | b = d[1]; | |
134 | if (key->rounds == 16) { | |
135 | D_RC5_32(a, b, s, 32); | |
136 | D_RC5_32(a, b, s, 30); | |
137 | D_RC5_32(a, b, s, 28); | |
138 | D_RC5_32(a, b, s, 26); | |
139 | /* Do a full expansion to avoid a jump */ | |
140 | D_RC5_32(a, b, s, 24); | |
141 | D_RC5_32(a, b, s, 22); | |
142 | D_RC5_32(a, b, s, 20); | |
143 | D_RC5_32(a, b, s, 18); | |
144 | } else if (key->rounds == 12) { | |
145 | D_RC5_32(a, b, s, 24); | |
146 | D_RC5_32(a, b, s, 22); | |
147 | D_RC5_32(a, b, s, 20); | |
148 | D_RC5_32(a, b, s, 18); | |
149 | } | |
150 | D_RC5_32(a, b, s, 16); | |
151 | D_RC5_32(a, b, s, 14); | |
152 | D_RC5_32(a, b, s, 12); | |
153 | D_RC5_32(a, b, s, 10); | |
154 | D_RC5_32(a, b, s, 8); | |
155 | D_RC5_32(a, b, s, 6); | |
156 | D_RC5_32(a, b, s, 4); | |
157 | D_RC5_32(a, b, s, 2); | |
158 | d[0] = a - s[0]; | |
159 | d[1] = b - s[1]; | |
160 | } |