Sat, 21 Apr 2007 04:18:16 +0000
Gaim -> Purple
| 16322 | 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: crypt-rc4.c 12116 2004-09-27 23:29:22Z guy $ | |
| 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 | Modified by Jeff Connelly for MySpaceIM Gaim plugin. | |
| 27 | */ | |
| 28 | ||
| 29 | #include <glib.h> | |
| 30 | #include <string.h> | |
| 31 | ||
| 32 | #include "crypt-rc4.h" | |
| 33 | ||
| 34 | /* Perform RC4 on a block of data using specified key. "data" is a pointer | |
| 35 | to the block to be processed. Output is written to same memory as input, | |
| 36 | so caller may need to make a copy before calling this function, since | |
| 37 | the input will be overwritten. | |
| 38 | ||
| 39 | Taken from Samba source code. Modified to allow us to maintain state | |
| 40 | between calls to crypt_rc4. | |
| 41 | */ | |
| 42 | ||
| 43 | void crypt_rc4_init(rc4_state_struct *rc4_state, | |
| 44 | const unsigned char *key, int key_len) | |
| 45 | { | |
| 46 | int ind; | |
| 47 | unsigned char j = 0; | |
| 48 | unsigned char *s_box; | |
| 49 | ||
| 50 | memset(rc4_state, 0, sizeof(rc4_state_struct)); | |
| 51 | s_box = rc4_state->s_box; | |
| 52 | ||
| 53 | for (ind = 0; ind < 256; ind++) | |
| 54 | { | |
| 55 | s_box[ind] = (unsigned char)ind; | |
| 56 | } | |
| 57 | ||
| 58 | for( ind = 0; ind < 256; ind++) | |
| 59 | { | |
| 60 | unsigned char tc; | |
| 61 | ||
| 62 | j += (s_box[ind] + key[ind%key_len]); | |
| 63 | ||
| 64 | tc = s_box[ind]; | |
| 65 | s_box[ind] = s_box[j]; | |
| 66 | s_box[j] = tc; | |
| 67 | } | |
| 68 | ||
| 69 | } | |
| 70 | ||
| 71 | void crypt_rc4(rc4_state_struct *rc4_state, unsigned char *data, int data_len) | |
| 72 | { | |
| 73 | unsigned char *s_box; | |
| 74 | unsigned char index_i; | |
| 75 | unsigned char index_j; | |
| 76 | int ind; | |
| 77 | ||
| 78 | /* retrieve current state from the state struct (so we can resume where | |
| 79 | we left off) */ | |
| 80 | index_i = rc4_state->index_i; | |
| 81 | index_j = rc4_state->index_j; | |
| 82 | s_box = rc4_state->s_box; | |
| 83 | ||
| 84 | for( ind = 0; ind < data_len; ind++) | |
| 85 | { | |
| 86 | unsigned char tc; | |
| 87 | unsigned char t; | |
| 88 | ||
| 89 | index_i++; | |
| 90 | index_j += s_box[index_i]; | |
| 91 | ||
| 92 | tc = s_box[index_i]; | |
| 93 | s_box[index_i] = s_box[index_j]; | |
| 94 | s_box[index_j] = tc; | |
| 95 | ||
| 96 | t = s_box[index_i] + s_box[index_j]; | |
| 97 | data[ind] = data[ind] ^ s_box[t]; | |
| 98 | } | |
| 99 | ||
| 100 | /* Store the updated state */ | |
| 101 | rc4_state->index_i = index_i; | |
| 102 | rc4_state->index_j = index_j; | |
| 103 | } |