Add checks in "rd_add_field_to_tree()" for the length of the field.
[obnox/wireshark/wip.git] / epan / crypt-rc4.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    a partial implementation of RC4 designed for use in the 
5    SMB authentication protocol
6
7    Copyright (C) Andrew Tridgell 1998
8
9    $Id$
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <string.h>
32
33 #include <epan/crypt-rc4.h>
34
35 /* Perform RC4 on a block of data using specified key.  "data" is a pointer
36    to the block to be processed.  Output is written to same memory as input,
37    so caller may need to make a copy before calling this function, since
38    the input will be overwritten.  
39    
40    Taken from Samba source code.  Modified to allow us to maintain state
41    between calls to crypt_rc4.
42 */
43
44 void crypt_rc4_init(rc4_state_struct *rc4_state, 
45                     const unsigned char *key, int key_len)
46 {
47   int ind;
48   unsigned char j = 0;
49   unsigned char *s_box;
50
51   memset(rc4_state, 0, sizeof(rc4_state_struct));
52   s_box = rc4_state->s_box;
53   
54   for (ind = 0; ind < 256; ind++)
55   {
56     s_box[ind] = (unsigned char)ind;
57   }
58
59   for( ind = 0; ind < 256; ind++)
60   {
61      unsigned char tc;
62
63      j += (s_box[ind] + key[ind%key_len]);
64
65      tc = s_box[ind];
66      s_box[ind] = s_box[j];
67      s_box[j] = tc;
68   }
69
70 }
71
72 void crypt_rc4(rc4_state_struct *rc4_state, unsigned char *data, int data_len)
73 {
74   unsigned char *s_box;
75   unsigned char index_i;
76   unsigned char index_j;
77   int ind;
78
79   /* retrieve current state from the state struct (so we can resume where
80      we left off) */
81   index_i = rc4_state->index_i;
82   index_j = rc4_state->index_j;
83   s_box = rc4_state->s_box;
84
85   for( ind = 0; ind < data_len; ind++)
86   {
87     unsigned char tc;
88     unsigned char t;
89
90     index_i++;
91     index_j += s_box[index_i];
92
93     tc = s_box[index_i];
94     s_box[index_i] = s_box[index_j];
95     s_box[index_j] = tc;
96
97     t = s_box[index_i] + s_box[index_j];
98     data[ind] = data[ind] ^ s_box[t];
99   }
100
101   /* Store the updated state */
102   rc4_state->index_i = index_i;
103   rc4_state->index_j = index_j;
104 }