Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34024083
arcfour.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
4 KB
Subscribers
None
arcfour.c
View Options
/* arcfour.c - The arcfour stream cipher
* Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
* ISBN 0-471-11709-9. Pages 397 ff.
*/
#include
<config.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
"types.h"
#include
"g10lib.h"
#include
"cipher.h"
static
const
char
*
selftest
(
void
);
typedef
struct
{
int
idx_i
,
idx_j
;
byte
sbox
[
256
];
}
ARCFOUR_context
;
static
void
do_encrypt_stream
(
ARCFOUR_context
*
ctx
,
byte
*
outbuf
,
const
byte
*
inbuf
,
unsigned
int
length
)
{
register
int
i
=
ctx
->
idx_i
;
register
int
j
=
ctx
->
idx_j
;
register
byte
*
sbox
=
ctx
->
sbox
;
register
int
t
;
while
(
length
--
)
{
i
++
;
i
=
i
&
255
;
/* The and-op seems to be faster than the mod-op. */
j
+=
sbox
[
i
];
j
&=
255
;
t
=
sbox
[
i
];
sbox
[
i
]
=
sbox
[
j
];
sbox
[
j
]
=
t
;
*
outbuf
++
=
*
inbuf
++
^
sbox
[(
sbox
[
i
]
+
sbox
[
j
])
&
255
];
}
ctx
->
idx_i
=
i
;
ctx
->
idx_j
=
j
;
}
static
void
encrypt_stream
(
void
*
context
,
byte
*
outbuf
,
const
byte
*
inbuf
,
unsigned
int
length
)
{
ARCFOUR_context
*
ctx
=
(
ARCFOUR_context
*
)
context
;
do_encrypt_stream
(
ctx
,
outbuf
,
inbuf
,
length
);
_gcry_burn_stack
(
64
);
}
static
gcry_err_code_t
do_arcfour_setkey
(
void
*
context
,
const
byte
*
key
,
unsigned
int
keylen
)
{
static
int
initialized
;
static
const
char
*
selftest_failed
;
int
i
,
j
;
byte
karr
[
256
];
ARCFOUR_context
*
ctx
=
(
ARCFOUR_context
*
)
context
;
if
(
!
initialized
)
{
initialized
=
1
;
selftest_failed
=
selftest
();
if
(
selftest_failed
)
log_error
(
"ARCFOUR selftest failed (%s)
\n
"
,
selftest_failed
);
}
if
(
selftest_failed
)
return
GPG_ERR_SELFTEST_FAILED
;
if
(
keylen
<
40
/
8
)
/* we want at least 40 bits */
return
GPG_ERR_INV_KEYLEN
;
ctx
->
idx_i
=
ctx
->
idx_j
=
0
;
for
(
i
=
0
;
i
<
256
;
i
++
)
ctx
->
sbox
[
i
]
=
i
;
for
(
i
=
0
;
i
<
256
;
i
++
)
karr
[
i
]
=
key
[
i
%
keylen
];
for
(
i
=
j
=
0
;
i
<
256
;
i
++
)
{
int
t
;
j
=
(
j
+
ctx
->
sbox
[
i
]
+
karr
[
i
])
%
256
;
t
=
ctx
->
sbox
[
i
];
ctx
->
sbox
[
i
]
=
ctx
->
sbox
[
j
];
ctx
->
sbox
[
j
]
=
t
;
}
memset
(
karr
,
0
,
256
);
return
GPG_ERR_NO_ERROR
;
}
static
gcry_err_code_t
arcfour_setkey
(
void
*
context
,
const
byte
*
key
,
unsigned
int
keylen
)
{
ARCFOUR_context
*
ctx
=
(
ARCFOUR_context
*
)
context
;
gcry_err_code_t
rc
=
do_arcfour_setkey
(
ctx
,
key
,
keylen
);
_gcry_burn_stack
(
300
);
return
rc
;
}
static
const
char
*
selftest
(
void
)
{
ARCFOUR_context
ctx
;
byte
scratch
[
16
];
/* Test vector from Cryptlib labeled there: "from the
State/Commerce Department". */
static
byte
key_1
[]
=
{
0x61
,
0x8A
,
0x63
,
0xD2
,
0xFB
};
static
byte
plaintext_1
[]
=
{
0xDC
,
0xEE
,
0x4C
,
0xF9
,
0x2C
};
static
const
byte
ciphertext_1
[]
=
{
0xF1
,
0x38
,
0x29
,
0xC9
,
0xDE
};
arcfour_setkey
(
&
ctx
,
key_1
,
sizeof
(
key_1
));
encrypt_stream
(
&
ctx
,
scratch
,
plaintext_1
,
sizeof
(
plaintext_1
));
if
(
memcmp
(
scratch
,
ciphertext_1
,
sizeof
(
ciphertext_1
)))
return
"Arcfour encryption test 1 failed."
;
arcfour_setkey
(
&
ctx
,
key_1
,
sizeof
(
key_1
));
encrypt_stream
(
&
ctx
,
scratch
,
scratch
,
sizeof
(
plaintext_1
));
/* decrypt */
if
(
memcmp
(
scratch
,
plaintext_1
,
sizeof
(
plaintext_1
)))
return
"Arcfour decryption test 1 failed."
;
return
NULL
;
}
gcry_cipher_spec_t
_gcry_cipher_spec_arcfour
=
{
"ARCFOUR"
,
NULL
,
NULL
,
1
,
128
,
sizeof
(
ARCFOUR_context
),
arcfour_setkey
,
NULL
,
NULL
,
encrypt_stream
,
encrypt_stream
,
};
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Nov 29, 7:04 AM (17 m, 58 s)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
1c/c6/e28f188ba017108eb2b2c78ffde0
Attached To
rC libgcrypt
Event Timeline
Log In to Comment