/************************************************************************ * IRC - Internet Relay Chat, src/rc4.c * Copyright (C) 2000 Lucas Madar * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id: rc4.c,v 1.3 2005/07/05 03:17:53 sheik Exp $ */ #include #include #include #include "memcount.h" /* * Transparent rc4 implementation * Based upon sample in crypto++ library, * which was based upon an anonymous usenet posting. * Implemented by Lucas Madar * * Remember that it is IMPERITAVE to generate a new key * for each state. DO NOT USE THE SAME KEY FOR ANY TWO STATES. */ typedef unsigned char RC4BYTE; typedef unsigned int RC4DWORD; struct rc4_state { RC4BYTE mstate[256]; RC4BYTE x; RC4BYTE y; }; void *rc4_initstate(unsigned char *key, int keylen) { RC4DWORD i; RC4BYTE tmp, idx1, idx2; struct rc4_state *rc4; if(sizeof(RC4BYTE) != 1) abort(); /* MUST BE 1 BYTE! */ if(sizeof(RC4DWORD) != 4) abort(); /* MUST BE 4 BYTES! */ rc4 = (struct rc4_state *) MyMalloc(sizeof(struct rc4_state)); memset(rc4, 0, sizeof(struct rc4_state)); for(i = 0; i < 256; i++) /* initialize our state array */ rc4->mstate[i] = (RC4BYTE) i; for(i = 0, idx1 = idx2 = 0; i < 256; i++) { idx2 = (key[idx1++] + rc4->mstate[i] + idx2); tmp = rc4->mstate[i]; rc4->mstate[i] = rc4->mstate[idx2]; rc4->mstate[idx2] = tmp; if(idx1 >= keylen) idx1 = 0; } return (void *) rc4; } void rc4_process_stream(void *rc4_context, unsigned char *istring, unsigned int stringlen) { struct rc4_state *rc4 = (struct rc4_state *) rc4_context; RC4BYTE *s = rc4->mstate; RC4DWORD x = rc4->x, y = rc4->y; while(stringlen--) { RC4DWORD a, b; x = (x+1) & 0xFF; a = s[x]; y = (y+a) & 0xFF; b = s[y]; s[x] = b; s[y] = a; *istring++ ^= s[(a + b) & 0xFF]; } rc4->x = (RC4BYTE) x; rc4->y = (RC4BYTE) y; } void rc4_process_stream_to_buf(void *rc4_context, const unsigned char *istring, unsigned char *ostring, unsigned int stringlen) { struct rc4_state *rc4 = (struct rc4_state *) rc4_context; RC4BYTE *s = rc4->mstate; RC4DWORD x = rc4->x, y = rc4->y; while(stringlen--) { RC4DWORD a, b; x = (x+1) & 0xFF; a = s[x]; y = (y+a) & 0xFF; b = s[y]; s[x] = b; s[y] = a; *ostring++ = *istring++ ^ s[(a + b) & 0xFF]; } rc4->x = (RC4BYTE) x; rc4->y = (RC4BYTE) y; } void rc4_destroystate(void *a) { memset(a, 0, sizeof(struct rc4_state)); MyFree(a); } u_long memcount_rc4(MCrc4 *mc) { mc->file = __FILE__; mc->m_rc4state_size = sizeof(struct rc4_state); return 0; }