Implement RC4.

This is another old algorithm with known vulnerabilities, but it is still used in some places.
This commit is contained in:
Stephen Heumann 2023-12-01 21:39:40 -06:00
parent aece58138f
commit 5a986a996f
6 changed files with 230 additions and 5 deletions

View File

@ -3,7 +3,7 @@ CFLAGS = -O255 -w255
LIBRARIES = lib65816crypto lib65816hash
PROGRAMS = aescbctest aesctrtest aestest aescrypt sha1sum sha1test \
PROGRAMS = aescbctest aesctrtest aestest aescrypt rc4test sha1sum sha1test \
sha256sum sha256test md5sum md5test md4sum md4test hmactest
.PHONY: default
@ -13,13 +13,17 @@ pagealign.root: pagealign.asm
$(CC) -c $<
mv pagealign.ROOT pagealign.root
# AES encryption/decryption algorithm
# Encryption/decryption algorithms
aesmodes.a: aesmodes.c aes.h
$(CC) $(CFLAGS) -c $<
aes.a: aes.asm aes.macros
$(CC) $(CFLAGS) -c $<
mv aes.A aes.a
rc4.a: rc4.cc rc4.h rc4.asm
$(CC) $(CFLAGS) -c $<
rc4.B: rc4.a
# Hash algorithms
sha1.a: sha1.cc sha1.h sha1.asm sha1.macros hmacimpl.h
$(CC) $(CFLAGS) -c $<
@ -38,7 +42,7 @@ md4.a: md4.cc md4.h md4.asm md4.macros hmacimpl.h
md4.B: md4.a
# Libraries
lib65816crypto: aesmodes.a aes.a
lib65816crypto: aesmodes.a aes.a rc4.a rc4.B
rm -f $@
iix makelib -P $@ $(patsubst %,+%,$^)
lib65816hash: sha1.a sha1.B sha256.a sha256.B md5.a md5.B md4.a md4.B
@ -55,6 +59,9 @@ aestest.a: aestest.c aes.h
aescrypt.a: aescrypt.c aes.h
$(CC) $(CFLAGS) -c $<
rc4test.a: rc4test.c rc4.h
$(CC) $(CFLAGS) -c $<
sha1sum.a: sha1sum.c sha1.h cksumcommon.h
$(CC) $(CFLAGS) -c $<
sha1test.a: sha1test.c sha1.h
@ -87,6 +94,9 @@ aestest: aestest.a pagealign.root lib65816crypto
aescrypt: aescrypt.a pagealign.root lib65816crypto
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816crypto -o $@
rc4test: rc4test.a lib65816crypto
$(CC) $(CFLAGS) $< -L. -llib65816crypto -o $@
sha1sum: sha1sum.a lib65816hash
$(CC) $(CFLAGS) $< -L. -llib65816hash -o $@
sha1test: sha1test.a lib65816hash

View File

@ -1,7 +1,7 @@
65816 Cryptographic & Hash Libraries
====================================
This package contains libraries implementing cryptographic algorithms for the 65816, suitable for use on the Apple IIgs and potentially also other 65816-based systems. Currently, it includes implementations of AES encryption and decryption (in `lib65816crypto`), and of the MD4, MD5, SHA-1, and SHA-256 hash functions (in `lib65816hash`). The core algorithms for each of these are written in carefully optimized assembly code, and they can generally process at least several thousand bytes per second on a 2.8 MHz Apple IIgs.
This package contains libraries implementing cryptographic algorithms for the 65816, suitable for use on the Apple IIgs and potentially also other 65816-based systems. Currently, it includes implementations of AES and RC4 encryption and decryption (in `lib65816crypto`), and of the MD4, MD5, SHA-1, and SHA-256 hash functions (in `lib65816hash`). The core algorithms for each of these are written in carefully optimized assembly code, and they can generally process at least several thousand bytes per second on a 2.8 MHz Apple IIgs.
Using the Libraries
-------------------
@ -11,7 +11,7 @@ If you are calling these algorithms from assembly language, simply follow the us
If you use these libraries in your program, you will need to link them into it. You can either place the libraries in the `Libraries` directory of your ORCA installation, or place them somewhere else and specify them on the command line when linking your program. When using certain algorithms (currently AES and MD5), you may also need to include `pagealign.root` as the first file on the linker command line. This file contains no code, but simply specifies that the default load segment should be page-aligned. This is needed because those algorithms include data tables that are page-aligned to maximize performance.
Note that some of the algorithms implemented in this package (including MD4, MD5, and SHA-1) have known security weaknesses. If you are using them in a situation where security is important, you should refer to up-to-date cryptanalytic results and advice to determine whether they are appropriate for your application.
Note that some of the algorithms implemented in this package (including RC4, MD4, MD5, and SHA-1) have known security weaknesses. If you are using any of these algorithms in a situation where security is important, you should refer to up-to-date cryptanalytic results and advice to determine whether they are appropriate for your application.
Building the Libraries
----------------------

55
rc4.asm Normal file
View File

@ -0,0 +1,55 @@
* Copyright (c) 2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* Direct page locations
i gequ 0
j gequ 1
S gequ 2
* Do one step of the RC4 pseudo-random generation algorithm.
* Call with DP = RC4 context structure, and short M/X.
RC4_PRGA start
;i := (i + 1) mod 256
inc i
;j := (j + S[i]) mod 256
ldx i
clc
lda S,x
tay
adc j
sta j
;swap values of S[i] and S[j]
tax
lda S,x
ldx i
sta S,x
ldx j
tya
sta S,x
;temp := (S[i] + S[j]) mod 256
ldx i
clc
adc S,x
;return S[temp]
tax
lda S,x
rtl
end

81
rc4.cc Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "rc4.h"
/*
* Initialize an RC4 context context with a specified key.
* This must be called before calling rc4_process.
*/
void rc4_init(struct rc4_context *context,
const unsigned char *key,
unsigned keylength)
{
unsigned int i;
unsigned char j;
unsigned char temp;
for (i = 0; i < 256; i++) {
context->S[i] = i;
}
j = 0;
for (i = 0; i < 256; i++) {
j = j + context->S[i] + key[i % keylength];
temp = context->S[j];
context->S[j] = context->S[i];
context->S[i] = temp;
}
context->i = 0;
context->j = 0;
}
/*
* Process data using RC4. This either encrypts or decrypts data,
* depending on whether in contains plaintext or ciphertext.
*
* To get the raw RC4 output stream, specify the input as all zeros.
* The same buffer may be used for in and out.
*/
void rc4_process(struct rc4_context *context,
const unsigned char *in,
unsigned char *out,
unsigned long length)
{
extern unsigned char RC4_PRGA(void);
while (length--) {
asm {
phd
lda context
tcd
sep #0x30
jsl RC4_PRGA
pld
eor [in]
sta [out]
rep #0x30
}
in++;
out++;
}
}
#append "rc4.asm"

40
rc4.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
struct rc4_context {
unsigned char i,j;
unsigned char S[256];
};
/*
* Initialize an RC4 context context with a specified key.
* This must be called before calling rc4_process.
*/
void rc4_init(struct rc4_context *context,
const unsigned char *key,
unsigned keylength);
/*
* Process data using RC4. This either encrypts or decrypts data,
* depending on whether in contains plaintext or ciphertext.
*
* To get the raw RC4 output stream, specify the input as all zeros.
* The same buffer may be used for in and out.
*/
void rc4_process(struct rc4_context *context,
const unsigned char *in,
unsigned char *out,
unsigned long length);

39
rc4test.c Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include "rc4.h"
int main(int argc, char *argv[]) {
struct rc4_context context;
size_t length;
size_t i;
if (argc < 3)
return 0;
rc4_init(&context, argv[1], strlen(argv[1]));
length = strlen(argv[2]);
rc4_process(&context, argv[2], argv[2], length);
for(i = 0; i < length; i++) {
printf("%02x", argv[2][i]);
}
printf("\n");
}