11cb0ef41Sopenharmony_ci#! /usr/bin/env perl
21cb0ef41Sopenharmony_ci# Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
31cb0ef41Sopenharmony_ci#
41cb0ef41Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
51cb0ef41Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
61cb0ef41Sopenharmony_ci# in the file LICENSE in the source distribution or at
71cb0ef41Sopenharmony_ci# https://www.openssl.org/source/license.html
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
111cb0ef41Sopenharmony_cipush(@INC,"${dir}","${dir}../../perlasm");
121cb0ef41Sopenharmony_cirequire "x86asm.pl";
131cb0ef41Sopenharmony_cirequire "cbc.pl";
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci$output = pop and open STDOUT,">$output";
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci&asm_init($ARGV[0]);
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci$RC5_MAX_ROUNDS=16;
201cb0ef41Sopenharmony_ci$RC5_32_OFF=($RC5_MAX_ROUNDS+2)*4;
211cb0ef41Sopenharmony_ci$A="edi";
221cb0ef41Sopenharmony_ci$B="esi";
231cb0ef41Sopenharmony_ci$S="ebp";
241cb0ef41Sopenharmony_ci$tmp1="eax";
251cb0ef41Sopenharmony_ci$r="ebx";
261cb0ef41Sopenharmony_ci$tmpc="ecx";
271cb0ef41Sopenharmony_ci$tmp4="edx";
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci&RC5_32_encrypt("RC5_32_encrypt",1);
301cb0ef41Sopenharmony_ci&RC5_32_encrypt("RC5_32_decrypt",0);
311cb0ef41Sopenharmony_ci&cbc("RC5_32_cbc_encrypt","RC5_32_encrypt","RC5_32_decrypt",0,4,5,3,-1,-1);
321cb0ef41Sopenharmony_ci&asm_finish();
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciclose STDOUT or die "error closing STDOUT: $!";
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cisub RC5_32_encrypt
371cb0ef41Sopenharmony_ci	{
381cb0ef41Sopenharmony_ci	local($name,$enc)=@_;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci	&function_begin_B($name,"");
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci	&comment("");
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci	&push("ebp");
451cb0ef41Sopenharmony_ci	 &push("esi");
461cb0ef41Sopenharmony_ci	&push("edi");
471cb0ef41Sopenharmony_ci	 &mov($tmp4,&wparam(0));
481cb0ef41Sopenharmony_ci	&mov($S,&wparam(1));
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci	&comment("Load the 2 words");
511cb0ef41Sopenharmony_ci	 &mov($A,&DWP(0,$tmp4,"",0));
521cb0ef41Sopenharmony_ci	&mov($B,&DWP(4,$tmp4,"",0));
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci	&push($r);
551cb0ef41Sopenharmony_ci	 &mov($r,	&DWP(0,$S,"",0));
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci	# encrypting part
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci	if ($enc)
601cb0ef41Sopenharmony_ci		{
611cb0ef41Sopenharmony_ci		 &add($A,	&DWP(4+0,$S,"",0));
621cb0ef41Sopenharmony_ci		&add($B,	&DWP(4+4,$S,"",0));
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci		for ($i=0; $i<$RC5_MAX_ROUNDS; $i++)
651cb0ef41Sopenharmony_ci			{
661cb0ef41Sopenharmony_ci			 &xor($A,	$B);
671cb0ef41Sopenharmony_ci			&mov($tmp1,	&DWP(12+$i*8,$S,"",0));
681cb0ef41Sopenharmony_ci			 &mov($tmpc,	$B);
691cb0ef41Sopenharmony_ci			&rotl($A,	&LB("ecx"));
701cb0ef41Sopenharmony_ci			&add($A,	$tmp1);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci			 &xor($B,	$A);
731cb0ef41Sopenharmony_ci			&mov($tmp1,	&DWP(16+$i*8,$S,"",0));
741cb0ef41Sopenharmony_ci			 &mov($tmpc,	$A);
751cb0ef41Sopenharmony_ci			&rotl($B,	&LB("ecx"));
761cb0ef41Sopenharmony_ci			&add($B,	$tmp1);
771cb0ef41Sopenharmony_ci			if (($i == 7) || ($i == 11))
781cb0ef41Sopenharmony_ci				{
791cb0ef41Sopenharmony_ci			 &cmp($r,	$i+1);
801cb0ef41Sopenharmony_ci			&je(&label("rc5_exit"));
811cb0ef41Sopenharmony_ci				}
821cb0ef41Sopenharmony_ci			}
831cb0ef41Sopenharmony_ci		}
841cb0ef41Sopenharmony_ci	else
851cb0ef41Sopenharmony_ci		{
861cb0ef41Sopenharmony_ci		 &cmp($r,	12);
871cb0ef41Sopenharmony_ci		&je(&label("rc5_dec_12"));
881cb0ef41Sopenharmony_ci		 &cmp($r,	8);
891cb0ef41Sopenharmony_ci		&je(&label("rc5_dec_8"));
901cb0ef41Sopenharmony_ci		for ($i=$RC5_MAX_ROUNDS; $i > 0; $i--)
911cb0ef41Sopenharmony_ci			{
921cb0ef41Sopenharmony_ci			&set_label("rc5_dec_$i") if ($i == 12) || ($i == 8);
931cb0ef41Sopenharmony_ci			 &mov($tmp1,	&DWP($i*8+8,$S,"",0));
941cb0ef41Sopenharmony_ci			&sub($B,	$tmp1);
951cb0ef41Sopenharmony_ci			 &mov($tmpc,	$A);
961cb0ef41Sopenharmony_ci			&rotr($B,	&LB("ecx"));
971cb0ef41Sopenharmony_ci			&xor($B,	$A);
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci			 &mov($tmp1,	&DWP($i*8+4,$S,"",0));
1001cb0ef41Sopenharmony_ci			&sub($A,	$tmp1);
1011cb0ef41Sopenharmony_ci			 &mov($tmpc,	$B);
1021cb0ef41Sopenharmony_ci			&rotr($A,	&LB("ecx"));
1031cb0ef41Sopenharmony_ci			&xor($A,	$B);
1041cb0ef41Sopenharmony_ci			}
1051cb0ef41Sopenharmony_ci		 &sub($B,	&DWP(4+4,$S,"",0));
1061cb0ef41Sopenharmony_ci		&sub($A,	&DWP(4+0,$S,"",0));
1071cb0ef41Sopenharmony_ci		}
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci	&set_label("rc5_exit");
1101cb0ef41Sopenharmony_ci	 &mov(&DWP(0,$tmp4,"",0),$A);
1111cb0ef41Sopenharmony_ci	&mov(&DWP(4,$tmp4,"",0),$B);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci	 &pop("ebx");
1141cb0ef41Sopenharmony_ci	&pop("edi");
1151cb0ef41Sopenharmony_ci	 &pop("esi");
1161cb0ef41Sopenharmony_ci	&pop("ebp");
1171cb0ef41Sopenharmony_ci	 &ret();
1181cb0ef41Sopenharmony_ci	&function_end_B($name);
1191cb0ef41Sopenharmony_ci	}
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci
122