2016-05-01 18:30:11 +03:00
/*
2005-08-20 11:59:00 +04:00
Unix SMB / CIFS implementation .
An implementation of the arcfour algorithm
Copyright ( C ) Andrew Tridgell 1998
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-08-20 11:59:00 +04:00
( at your option ) any later version .
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
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 .
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-08-20 11:59:00 +04:00
*/
2010-06-15 14:01:09 +04:00
# include "replace.h"
2008-09-24 18:04:43 +04:00
# include "../lib/crypto/arcfour.h"
2005-08-20 11:59:00 +04:00
/* initialise the arcfour sbox with key */
2016-05-01 18:30:11 +03:00
_PUBLIC_ void arcfour_init ( struct arcfour_state * state , const DATA_BLOB * key )
2005-08-20 11:59:00 +04:00
{
2016-05-01 18:28:56 +03:00
size_t ind ;
2005-08-20 11:59:00 +04:00
uint8_t j = 0 ;
for ( ind = 0 ; ind < sizeof ( state - > sbox ) ; ind + + ) {
state - > sbox [ ind ] = ( uint8_t ) ind ;
}
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
for ( ind = 0 ; ind < sizeof ( state - > sbox ) ; ind + + ) {
uint8_t tc ;
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
j + = ( state - > sbox [ ind ] + key - > data [ ind % key - > length ] ) ;
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
tc = state - > sbox [ ind ] ;
state - > sbox [ ind ] = state - > sbox [ j ] ;
state - > sbox [ j ] = tc ;
}
state - > index_i = 0 ;
state - > index_j = 0 ;
}
/* crypt the data with arcfour */
2016-05-01 18:30:11 +03:00
_PUBLIC_ void arcfour_crypt_sbox ( struct arcfour_state * state , uint8_t * data ,
int len )
2005-08-20 11:59:00 +04:00
{
int ind ;
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
for ( ind = 0 ; ind < len ; ind + + ) {
uint8_t tc ;
uint8_t t ;
state - > index_i + + ;
state - > index_j + = state - > sbox [ state - > index_i ] ;
tc = state - > sbox [ state - > index_i ] ;
state - > sbox [ state - > index_i ] = state - > sbox [ state - > index_j ] ;
state - > sbox [ state - > index_j ] = tc ;
2016-05-01 18:30:11 +03:00
2005-08-20 11:59:00 +04:00
t = state - > sbox [ state - > index_i ] + state - > sbox [ state - > index_j ] ;
data [ ind ] = data [ ind ] ^ state - > sbox [ t ] ;
}
}
/*
arcfour encryption with a blob key
*/
2016-05-01 18:30:11 +03:00
_PUBLIC_ void arcfour_crypt_blob ( uint8_t * data , int len , const DATA_BLOB * key )
2005-08-20 11:59:00 +04:00
{
struct arcfour_state state ;
arcfour_init ( & state , key ) ;
arcfour_crypt_sbox ( & state , data , len ) ;
}
/*
a variant that assumes a 16 byte key . This should be removed
when the last user is gone
*/
2006-03-07 19:25:28 +03:00
_PUBLIC_ void arcfour_crypt ( uint8_t * data , const uint8_t keystr [ 16 ] , int len )
2005-08-20 11:59:00 +04:00
{
2015-06-23 10:52:49 +03:00
uint8_t keycopy [ 16 ] ;
DATA_BLOB key = { . data = keycopy , . length = sizeof ( keycopy ) } ;
2005-08-20 11:59:00 +04:00
2015-06-23 10:52:49 +03:00
memcpy ( keycopy , keystr , sizeof ( keycopy ) ) ;
arcfour_crypt_blob ( data , len , & key ) ;
2005-08-20 11:59:00 +04:00
}