an implementation of the NT domain credentials protocol
[kai/samba.git] / source3 / arcfour.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4
5    a implementation of arcfour designed for use in the 
6    SMB password change protocol based on the description
7    in 'Applied Cryptography', 2nd Edition.
8
9    Copyright (C) Jeremy Allison 1997
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 #include "arcfour.h"
27
28 void set_arc4_key(unsigned char *data, int key_length, arc4_key *arckey)
29 {
30   unsigned int i; 
31   unsigned char j;
32   unsigned char tc;
33   unsigned char *s_box = &arckey->s_box[0];
34
35   arckey->index_i = 0;
36   arckey->index_j = 0;
37   for(i = 0; i < 256; i++)
38     s_box[i] = (unsigned char)i;
39
40   j = 0;
41   for( i = 0; i < 256; i++)
42   {
43      j += (s_box[i] + data[i%key_length]);
44      tc = s_box[i];
45      s_box[i] = s_box[j];
46      s_box[j] = tc;
47   }
48 }
49
50 void arc4(arc4_key *arckey, unsigned char *data_in, unsigned char *data_out, 
51           int length)
52 {
53   unsigned char tc;
54   int ind;
55   unsigned char i, j;
56   unsigned char t;
57   unsigned char *s_box = &arckey->s_box[0];
58
59   for( ind = 0; ind < length; ind++)
60   {
61     i = ++arckey->index_i;
62     j = arckey->index_j += s_box[i];
63     tc = s_box[i];
64     s_box[i] = s_box[j];
65     s_box[j] = tc;
66     t = s_box[i] + s_box[j];
67     *data_out++ = *data_in++ ^ s_box[t];
68   }
69 }
70
71 #if 0
72 /* Test vector */
73 unsigned char key_data[] = { 0x61, 0x8a, 0x63, 0xd2, 0xfb };
74 unsigned char plaintext[] = { 0xdc, 0xee, 0x4c, 0xf9, 0x2c };
75 unsigned char ciphertext[] = { 0xf1, 0x38, 0x29, 0xc9, 0xde };
76
77 int main(int argc, char *argv[])
78 {
79   unsigned char out[5];
80   arc4_key key;
81
82   set_arc4_key(key_data, 5, &key);
83   arc4(&key, plaintext, out, 5);
84
85   if(memcmp(out, ciphertext, 5) ==0)
86     printf("Test ok !\n");
87   else
88     printf("Test fail !\n");
89   return 0;
90 }
91 #endif