Blame crypto/perlasm/README

Packit Service 084de1
The perl scripts in this directory are my 'hack' to generate
Packit Service 084de1
multiple different assembler formats via the one original script.
Packit Service 084de1
Packit Service 084de1
The way to use this library is to start with adding the path to this directory
Packit Service 084de1
and then include it.
Packit Service 084de1
Packit Service 084de1
push(@INC,"perlasm","../../perlasm");
Packit Service 084de1
require "x86asm.pl";
Packit Service 084de1
Packit Service 084de1
The first thing we do is setup the file and type of assembler
Packit Service 084de1
Packit Service 084de1
&asm_init($ARGV[0]);
Packit Service 084de1
Packit Service 084de1
The first argument is the 'type'.  Currently
Packit Service 084de1
'cpp', 'sol', 'a.out', 'elf' or 'win32'.
Packit Service 084de1
Argument 2 is the file name.
Packit Service 084de1
Packit Service 084de1
The reciprocal function is
Packit Service 084de1
&asm_finish() which should be called at the end.
Packit Service 084de1
Packit Service 084de1
There are 2 main 'packages'. x86ms.pl, which is the Microsoft assembler,
Packit Service 084de1
and x86unix.pl which is the unix (gas) version.
Packit Service 084de1
Packit Service 084de1
Functions of interest are:
Packit Service 084de1
&external_label("des_SPtrans");	declare and external variable
Packit Service 084de1
&LB(reg);			Low byte for a register
Packit Service 084de1
&HB(reg);			High byte for a register
Packit Service 084de1
&BP(off,base,index,scale)	Byte pointer addressing
Packit Service 084de1
&DWP(off,base,index,scale)	Word pointer addressing
Packit Service 084de1
&stack_push(num)		Basically a 'sub esp, num*4' with extra
Packit Service 084de1
&stack_pop(num)			inverse of stack_push
Packit Service 084de1
&function_begin(name,extra)	Start a function with pushing of
Packit Service 084de1
				edi, esi, ebx and ebp.  extra is extra win32
Packit Service 084de1
				external info that may be required.
Packit Service 084de1
&function_begin_B(name,extra)	Same as normal function_begin but no pushing.
Packit Service 084de1
&function_end(name)		Call at end of function.
Packit Service 084de1
&function_end_A(name)		Standard pop and ret, for use inside functions
Packit Service 084de1
&function_end_B(name)		Call at end but with pop or ret.
Packit Service 084de1
&swtmp(num)			Address on stack temp word.
Packit Service 084de1
&wparam(num)			Parameter number num, that was push
Packit Service 084de1
				in C convention.  This all works over pushes
Packit Service 084de1
				and pops.
Packit Service 084de1
&comment("hello there")		Put in a comment.
Packit Service 084de1
&label("loop")			Refer to a label, normally a jmp target.
Packit Service 084de1
&set_label("loop")		Set a label at this point.
Packit Service 084de1
&data_word(word)		Put in a word of data.
Packit Service 084de1
Packit Service 084de1
So how does this all hold together?  Given
Packit Service 084de1
Packit Service 084de1
int calc(int len, int *data)
Packit Service 084de1
	{
Packit Service 084de1
	int i,j=0;
Packit Service 084de1
Packit Service 084de1
	for (i=0; i
Packit Service 084de1
		{
Packit Service 084de1
		j+=other(data[i]);
Packit Service 084de1
		}
Packit Service 084de1
	}
Packit Service 084de1
Packit Service 084de1
So a very simple version of this function could be coded as
Packit Service 084de1
Packit Service 084de1
	push(@INC,"perlasm","../../perlasm");
Packit Service 084de1
	require "x86asm.pl";
Packit Service 084de1
	
Packit Service 084de1
	&asm_init($ARGV[0]);
Packit Service 084de1
Packit Service 084de1
	&external_label("other");
Packit Service 084de1
Packit Service 084de1
	$tmp1=	"eax";
Packit Service 084de1
	$j=	"edi";
Packit Service 084de1
	$data=	"esi";
Packit Service 084de1
	$i=	"ebp";
Packit Service 084de1
Packit Service 084de1
	&comment("a simple function");
Packit Service 084de1
	&function_begin("calc");
Packit Service 084de1
	&mov(	$data,		&wparam(1)); # data
Packit Service 084de1
	&xor(	$j,		$j);
Packit Service 084de1
	&xor(	$i,		$i);
Packit Service 084de1
Packit Service 084de1
	&set_label("loop");
Packit Service 084de1
	&cmp(	$i,		&wparam(0));
Packit Service 084de1
	&jge(	&label("end"));
Packit Service 084de1
Packit Service 084de1
	&mov(	$tmp1,		&DWP(0,$data,$i,4));
Packit Service 084de1
	&push(	$tmp1);
Packit Service 084de1
	&call(	"other");
Packit Service 084de1
	&add(	$j,		"eax");
Packit Service 084de1
	&pop(	$tmp1);
Packit Service 084de1
	&inc(	$i);
Packit Service 084de1
	&jmp(	&label("loop"));
Packit Service 084de1
Packit Service 084de1
	&set_label("end");
Packit Service 084de1
	&mov(	"eax",		$j);
Packit Service 084de1
Packit Service 084de1
	&function_end("calc");
Packit Service 084de1
Packit Service 084de1
	&asm_finish();
Packit Service 084de1
Packit Service 084de1
The above example is very very unoptimised but gives an idea of how
Packit Service 084de1
things work.
Packit Service 084de1
Packit Service 084de1
There is also a cbc mode function generator in cbc.pl
Packit Service 084de1
Packit Service 084de1
&cbc(	$name,
Packit Service 084de1
	$encrypt_function_name,
Packit Service 084de1
	$decrypt_function_name,
Packit Service 084de1
	$true_if_byte_swap_needed,
Packit Service 084de1
	$parameter_number_for_iv,
Packit Service 084de1
	$parameter_number_for_encrypt_flag,
Packit Service 084de1
	$first_parameter_to_pass,
Packit Service 084de1
	$second_parameter_to_pass,
Packit Service 084de1
	$third_parameter_to_pass);
Packit Service 084de1
Packit Service 084de1
So for example, given
Packit Service 084de1
void BF_encrypt(BF_LONG *data,BF_KEY *key);
Packit Service 084de1
void BF_decrypt(BF_LONG *data,BF_KEY *key);
Packit Service 084de1
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
Packit Service 084de1
        BF_KEY *ks, unsigned char *iv, int enc);
Packit Service 084de1
Packit Service 084de1
&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
Packit Service 084de1
Packit Service 084de1
&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
Packit Service 084de1
&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
Packit Service 084de1