cmll-x86.pl 32.3 KB
Newer Older
		&mov	($key,$_tmp);		# load ivp
		&mov	($idx,$_len);		# load len

		&bswap	($s0);
		&bswap	($s1);
		&bswap	($s2);
		&xor	($s0,&DWP(0,$key));	# xor iv
		&bswap	($s3);
		&xor	($s1,&DWP(4,$key));
		&xor	($s2,&DWP(8,$key));
		&xor	($s3,&DWP(12,$key));

		&sub	($idx,16);
		&jc	(&label("dec_partial"));
		&mov	($_len,$idx);		# save len
		&mov	($idx,$_inp);		# load inp
		&mov	($key,$_out);		# load out

		&mov	(&DWP(0,$key),$s0);	# write output
		&mov	(&DWP(4,$key),$s1);
		&mov	(&DWP(8,$key),$s2);
		&mov	(&DWP(12,$key),$s3);

		&mov	($_tmp,$idx);		# save ivp
		&lea	($idx,&DWP(16,$idx));
		&mov	($_inp,$idx);		# save inp

		&lea	($key,&DWP(16,$key));
		&mov	($_out,$key);		# save out

	&jnz	(&label("dec_loop"));
	&mov	($key,$_tmp);		# load temp ivp
    &set_label("dec_end");
	&mov	($idx,$_ivp);		# load user ivp
	&mov	($s0,&DWP(0,$key));	# load iv
	&mov	($s1,&DWP(4,$key));
	&mov	($s2,&DWP(8,$key));
	&mov	($s3,&DWP(12,$key));
	&mov	(&DWP(0,$idx),$s0);	# copy back to user
	&mov	(&DWP(4,$idx),$s1);
	&mov	(&DWP(8,$idx),$s2);
	&mov	(&DWP(12,$idx),$s3);
	&jmp	(&label("dec_out"));

    &set_label("dec_partial",4);
	&lea	($key,$ivec);
	&mov	(&DWP(0,$key),$s0);	# dump output to stack
	&mov	(&DWP(4,$key),$s1);
	&mov	(&DWP(8,$key),$s2);
	&mov	(&DWP(12,$key),$s3);
	&lea	($s2 eq "ecx" ? $s2 : "",&DWP(16,$idx));
	&mov	($idx eq "esi" ? $idx : "",$key);
	&mov	($key eq "edi" ? $key : "",$_out);	# load out
	&data_word(0xA4F3F689);	# rep movsb		# copy output
	&mov	($key,$_inp);				# use inp as temp ivp
	&jmp	(&label("dec_end"));

    &set_label("dec_in_place",4);
	&set_label("dec_in_place_loop");
		&lea	($key,$ivec);
		&mov	($s0,&DWP(0,$idx));	# read input
		&mov	($s1,&DWP(4,$idx));
		&mov	($s2,&DWP(8,$idx));
		&mov	($s3,&DWP(12,$idx));

		&mov	(&DWP(0,$key),$s0);	# copy to temp
		&mov	(&DWP(4,$key),$s1);
		&mov	(&DWP(8,$key),$s2);
		&bswap	($s0);
		&mov	(&DWP(12,$key),$s3);
		&bswap	($s1);
		&mov	($key,$_key);		# load key
		&bswap	($s2);
		&bswap	($s3);

		&call	("_x86_Camellia_decrypt");

		&mov	($key,$_ivp);		# load ivp
		&mov	($idx,$_out);		# load out

		&bswap	($s0);
		&bswap	($s1);
		&bswap	($s2);
		&xor	($s0,&DWP(0,$key));	# xor iv
		&bswap	($s3);
		&xor	($s1,&DWP(4,$key));
		&xor	($s2,&DWP(8,$key));
		&xor	($s3,&DWP(12,$key));

		&mov	(&DWP(0,$idx),$s0);	# write output
		&mov	(&DWP(4,$idx),$s1);
		&mov	(&DWP(8,$idx),$s2);
		&mov	(&DWP(12,$idx),$s3);

		&lea	($idx,&DWP(16,$idx));
		&mov	($_out,$idx);		# save out

		&lea	($idx,$ivec);
		&mov	($s0,&DWP(0,$idx));	# read temp
		&mov	($s1,&DWP(4,$idx));
		&mov	($s2,&DWP(8,$idx));
		&mov	($s3,&DWP(12,$idx));

		&mov	(&DWP(0,$key),$s0);	# copy iv
		&mov	(&DWP(4,$key),$s1);
		&mov	(&DWP(8,$key),$s2);
		&mov	(&DWP(12,$key),$s3);

		&mov	($idx,$_inp);		# load inp

		&lea	($idx,&DWP(16,$idx));
		&mov	($_inp,$idx);		# save inp

		&mov	($s2,$_len);		# load len
		&sub	($s2,16);
		&jc	(&label("dec_in_place_partial"));
		&mov	($_len,$s2);		# save len
	&jnz	(&label("dec_in_place_loop"));
	&jmp	(&label("dec_out"));

    &set_label("dec_in_place_partial",4);
	# one can argue if this is actually required...
	&mov	($key eq "edi" ? $key : "",$_out);
	&lea	($idx eq "esi" ? $idx : "",$ivec);
	&lea	($key,&DWP(0,$key,$s2));
	&lea	($idx,&DWP(16,$idx,$s2));
	&neg	($s2 eq "ecx" ? $s2 : "");
	&data_word(0xA4F3F689);	# rep movsb	# restore tail

    &set_label("dec_out",4);
    &mov	("esp",$_esp);
    &popf	();
&function_end("Camellia_cbc_encrypt");
}

&asciz("Camellia for x86 by <appro\@openssl.org>");

&asm_finish();