~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/crypt/crypt-des.cc

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.