1 /*
2 * crypt-des.cc --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1995-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 static const char rcsid[] =
35 "@(#) $Header: /usr/mash/src/repository/mash/mash-1/crypt/crypt-des.cc,v 1.8 2003/11/19 19:20:26 aswan Exp $";
36
37 #include "crypt/crypt.h"
38 #include "rtp/inet.h"
39 #include "rtp/rtp.h"
40
41 extern "C" {
42 extern void DesQuickInit();
43 extern int DesMethod(u_char* m, u_char* k);
44 extern int DesQuickFipsEncrypt(u_char* dst, u_char* m, u_char* src);
45 extern int DesQuickFipsDecrypt(u_char* dst, u_char* m, u_char* src);
46 }
47
48 class CryptDES : public Crypt {
49 public:
50 CryptDES();
51 ~CryptDES();
52 virtual int install_key(const u_int8_t* key);
53 virtual u_char* Encrypt(const u_char* in, int& len);
54 virtual int Decrypt(const u_char* in, int len, u_char* out);
55 protected:
56 int encrypt(u_int32_t* blk, const u_char* in, int len, u_char* rh);
57 int decrypt(const u_char* in, int len, u_char* out, int rtcp);
58 static int didinit_;
59 u_char* wrkbuf_;
60 u_char mkey_[128];
61 };
62
63 class CryptDESctrl : public CryptDES {
64 public:
65 virtual u_char* Encrypt(const u_char* in, int& len);
66 virtual int Decrypt(const u_char* in, int len, u_char* out);
67 };
68
69 static class CryptDesDataClass : public TclClass {
70 public:
71 CryptDesDataClass() : TclClass("Crypt/Data/DES") {}
72 TclObject* create(int argc, const char*const* argv) {
73 return (new CryptDES);
74 }
75 } cld_ctrl;
76
77 static class CryptDesCtrlClass : public TclClass {
78 public:
79 CryptDesCtrlClass() : TclClass("Crypt/Control/DES") {}
80 TclObject* create(int argc, const char*const* argv) {
81 return (new CryptDESctrl);
82 }
83 } cls_data;
84
85 int CryptDES::didinit_;
86
87 CryptDES::CryptDES()
88 {
89 if (didinit_ == 0) {
90 DesQuickInit();
91 didinit_ = 1;
92 }
93 /* enough extra space for padding and RTCP 4-byte random header */
94 wrkbuf_ = new u_char[RTP_MTU + 8 + 4];
95 }
96
97 CryptDES::~CryptDES()
98 {
99 delete wrkbuf_;
100 }
101
102 int CryptDES::install_key(const u_int8_t* key)
103 {
104 /* DES key */
105 u_char dk[8];
106 /*
107 * Take the first 56-bits of the input key and spread
108 * it across the 64-bit DES key space inserting a bit-space
109 * of garbage (for parity) every 7 bits. The garbage
110 * will be taken care of below. The library we're
111 * using expects the key and parity bits in the following
112 * MSB order: K0 K1 ... K6 P0 K8 K9 ... K14 P1 ...
113 */
114 dk[0] = key[0];
115 dk[1] = key[0] << 7 | key[1] >> 1;
116 dk[2] = key[1] << 6 | key[2] >> 2;
117 dk[3] = key[2] << 5 | key[3] >> 3;
118 dk[4] = key[3] << 4 | key[4] >> 4;
119 dk[5] = key[4] << 3 | key[5] >> 5;
120 dk[6] = key[5] << 2 | key[6] >> 6;
121 dk[7] = key[6] << 1;
122
123 /* fill in parity bits to make DES library happy */
124 for (int i = 0; i < 8; ++i) {
125 register int k = dk[i] & 0xfe;
126 int j = k;
127 j ^= j >> 4;
128 j ^= j >> 2;
129 j ^= j >> 1;
130 j = (j & 1) ^ 1;
131 dk[i] = k | j;
132 }
133 #if DEBUG_KEY
134 for (i=0; i<8; ++i) fprintf(stderr, "dk[%d]=%d",i, dk[i]);
135 fprintf(stderr, "\n");
136 #endif
137 register int s = DesMethod(mkey_, dk);
138 return (s);
139 }
140
141 int CryptDES::encrypt(u_int32_t* blk, const u_char* in, int len, u_char* rh)
142 {
143 int pad = len & 7;
144 if (pad != 0) {
145 /* pad to an block (8 octet) boundary */
146 pad = 8 - pad;
147 *rh |= 0x20; // set P bit
148 }
149
150 register u_int32_t* wp = (u_int32_t*)wrkbuf_;
151 register u_char* m = mkey_;
152 DesQuickFipsEncrypt((u_char*)wp, m, (u_char*)blk);
153
154 register u_int32_t* bp = (u_int32_t*)in;
155 register int i;
156 for (i = len >> 3; --i >= 0; ) {
157 blk[0] = bp[0] ^ wp[0];
158 blk[1] = bp[1] ^ wp[1];
159 bp += 2;
160 wp += 2;
161 DesQuickFipsEncrypt((u_char*)wp, m, (u_char*)blk);
162 }
163 if (pad > 0) {
164 len += pad;
165 blk[0] = bp[0];
166 blk[1] = bp[1];
167 u_char* cp = (u_char*)blk + 7;
168 *cp = pad;
169 while (--pad > 0)
170 *--cp = 0;
171 blk[0] ^= wp[0];
172 blk[1] ^= wp[1];
173 wp += 2;
174 DesQuickFipsEncrypt((u_char*)wp, m, (u_char*)blk);
175 }
176 return (len);
177 }
178
179 u_char* CryptDES::Encrypt(const u_char* in, int& len)
180 {
181 u_int32_t blk[2];
182 blk[0] = *(u_int32_t*)in;
183 blk[1] = *(u_int32_t*)(in + 4);
184 len = encrypt(blk, in + 8, len - 8, (u_char*)blk) + 8;
185 return (wrkbuf_);
186 }
187
188 int CryptDES::decrypt(const u_char* in, int len, u_char* out, int rtcp)
189 {
190 register u_int32_t* wp = (u_int32_t*)out;
191 register const u_int32_t* bp = (u_int32_t*)in;
192 register u_char* m = mkey_;
193
194 /* check that packet is an integral number of blocks */
195 if ((len & 7) != 0) {
196 ++badpktlen_;
197 return (-1);
198 }
199 int nblk = len >> 3;
200 DesQuickFipsDecrypt((u_char*)wp, m, (u_char*)bp);
201 bp += 2;
202 nblk -= 1;
203 if (rtcp) {
204 /* throw away random RTCP header */
205 wp[0] = wp[1];
206 wp += 1;
207 len -= 4;
208 } else
209 wp += 2;
210
211 while (--nblk >= 0) {
212 DesQuickFipsDecrypt((u_char*)wp, m, (u_char*)bp);
213 wp[0] ^= bp[-2];
214 wp[1] ^= bp[-1];
215 bp += 2;
216 wp += 2;
217 }
218 if ((out[0] & 0x20) != 0) {
219 /* P bit set - trim off padding */
220 int pad = out[len - 1];
221 if (pad > 7 || pad == 0) {
222 ++badpbit_;
223 return (-1);
224 }
225 len -= pad;
226 }
227 return (len);
228 }
229
230 int CryptDES::Decrypt(const u_char* in, int len, u_char* out)
231 {
232 return (decrypt(in, len, out, 0));
233 }
234
235 u_char* CryptDESctrl::Encrypt(const u_char* in, int& len)
236 {
237 u_int32_t blk[2];
238 blk[0] = random();
239 blk[1] = *(u_int32_t*)in;
240 len = encrypt(blk, in + 4, len - 4, (u_char*)&blk[1]) + 8;
241 return (wrkbuf_);
242 }
243
244 int CryptDESctrl::Decrypt(const u_char* in, int len, u_char* out)
245 {
246 return (decrypt(in, len, out, 1));
247 }
248
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.