]>
Commit | Line | Data |
---|---|---|
d2e9e320 RS |
1 | /* |
2 | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. | |
d02b48c6 | 3 | * |
d2e9e320 RS |
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 | |
d02b48c6 RE |
8 | */ |
9 | ||
cf89b405 | 10 | #include "e_os.h" |
d02b48c6 | 11 | #include "des_locl.h" |
1a979201 | 12 | #include <assert.h> |
d02b48c6 | 13 | |
0f113f3e MC |
14 | /* |
15 | * The input and output are loaded in multiples of 8 bits. What this means is | |
16 | * that if you hame numbits=12 and length=2 the first 12 bits will be | |
17 | * retrieved from the first byte and half the second. The second 12 bits | |
18 | * will come from the 3rd and half the 4th byte. | |
19 | */ | |
20 | /* | |
21 | * Until Aug 1 2003 this function did not correctly implement CFB-r, so it | |
22 | * will not be compatible with any encryption prior to that date. Ben. | |
d02b48c6 | 23 | */ |
c2e4f17c | 24 | void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, |
0f113f3e MC |
25 | long length, DES_key_schedule *schedule, |
26 | DES_cblock *ivec, int enc) | |
27 | { | |
28 | register DES_LONG d0, d1, v0, v1; | |
29 | register unsigned long l = length; | |
30 | register int num = numbits / 8, n = (numbits + 7) / 8, i, rem = | |
31 | numbits % 8; | |
32 | DES_LONG ti[2]; | |
33 | unsigned char *iv; | |
1a979201 | 34 | #ifndef L_ENDIAN |
0f113f3e | 35 | unsigned char ovec[16]; |
1a979201 | 36 | #else |
0f113f3e MC |
37 | unsigned int sh[4]; |
38 | unsigned char *ovec = (unsigned char *)sh; | |
39 | ||
46f4e1be | 40 | /* I kind of count that compiler optimizes away this assertion, */ |
0f113f3e MC |
41 | assert(sizeof(sh[0]) == 4); /* as this holds true for all, */ |
42 | /* but 16-bit platforms... */ | |
d02b48c6 | 43 | |
1a979201 AP |
44 | #endif |
45 | ||
0f113f3e MC |
46 | if (numbits <= 0 || numbits > 64) |
47 | return; | |
48 | iv = &(*ivec)[0]; | |
49 | c2l(iv, v0); | |
50 | c2l(iv, v1); | |
51 | if (enc) { | |
52 | while (l >= (unsigned long)n) { | |
53 | l -= n; | |
54 | ti[0] = v0; | |
55 | ti[1] = v1; | |
56 | DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); | |
57 | c2ln(in, d0, d1, n); | |
58 | in += n; | |
59 | d0 ^= ti[0]; | |
60 | d1 ^= ti[1]; | |
61 | l2cn(d0, d1, out, n); | |
62 | out += n; | |
63 | /* | |
64 | * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under | |
65 | * gcc :-( | |
66 | */ | |
67 | if (numbits == 32) { | |
68 | v0 = v1; | |
69 | v1 = d0; | |
70 | } else if (numbits == 64) { | |
71 | v0 = d0; | |
72 | v1 = d1; | |
73 | } else { | |
1a979201 | 74 | #ifndef L_ENDIAN |
0f113f3e MC |
75 | iv = &ovec[0]; |
76 | l2c(v0, iv); | |
77 | l2c(v1, iv); | |
78 | l2c(d0, iv); | |
79 | l2c(d1, iv); | |
1a979201 | 80 | #else |
0f113f3e | 81 | sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; |
1a979201 | 82 | #endif |
0f113f3e MC |
83 | if (rem == 0) |
84 | memmove(ovec, ovec + num, 8); | |
85 | else | |
86 | for (i = 0; i < 8; ++i) | |
87 | ovec[i] = ovec[i + num] << rem | | |
88 | ovec[i + num + 1] >> (8 - rem); | |
1a979201 | 89 | #ifdef L_ENDIAN |
0f113f3e | 90 | v0 = sh[0], v1 = sh[1]; |
1a979201 | 91 | #else |
0f113f3e MC |
92 | iv = &ovec[0]; |
93 | c2l(iv, v0); | |
94 | c2l(iv, v1); | |
1a979201 | 95 | #endif |
0f113f3e MC |
96 | } |
97 | } | |
98 | } else { | |
99 | while (l >= (unsigned long)n) { | |
100 | l -= n; | |
101 | ti[0] = v0; | |
102 | ti[1] = v1; | |
103 | DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); | |
104 | c2ln(in, d0, d1, n); | |
105 | in += n; | |
106 | /* | |
107 | * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under | |
108 | * gcc :-( | |
109 | */ | |
110 | if (numbits == 32) { | |
111 | v0 = v1; | |
112 | v1 = d0; | |
113 | } else if (numbits == 64) { | |
114 | v0 = d0; | |
115 | v1 = d1; | |
116 | } else { | |
1a979201 | 117 | #ifndef L_ENDIAN |
0f113f3e MC |
118 | iv = &ovec[0]; |
119 | l2c(v0, iv); | |
120 | l2c(v1, iv); | |
121 | l2c(d0, iv); | |
122 | l2c(d1, iv); | |
1a979201 | 123 | #else |
0f113f3e | 124 | sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; |
1a979201 | 125 | #endif |
0f113f3e MC |
126 | if (rem == 0) |
127 | memmove(ovec, ovec + num, 8); | |
128 | else | |
129 | for (i = 0; i < 8; ++i) | |
130 | ovec[i] = ovec[i + num] << rem | | |
131 | ovec[i + num + 1] >> (8 - rem); | |
1a979201 | 132 | #ifdef L_ENDIAN |
0f113f3e | 133 | v0 = sh[0], v1 = sh[1]; |
1a979201 | 134 | #else |
0f113f3e MC |
135 | iv = &ovec[0]; |
136 | c2l(iv, v0); | |
137 | c2l(iv, v1); | |
1a979201 | 138 | #endif |
0f113f3e MC |
139 | } |
140 | d0 ^= ti[0]; | |
141 | d1 ^= ti[1]; | |
142 | l2cn(d0, d1, out, n); | |
143 | out += n; | |
144 | } | |
145 | } | |
146 | iv = &(*ivec)[0]; | |
147 | l2c(v0, iv); | |
148 | l2c(v1, iv); | |
149 | v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; | |
150 | } |