1e1051a39Sopenharmony_ci#! /usr/bin/env perl
2e1051a39Sopenharmony_ci# Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci#
4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
11e1051a39Sopenharmony_cipush(@INC,"${dir}","${dir}../../perlasm");
12e1051a39Sopenharmony_cirequire "x86asm.pl";
13e1051a39Sopenharmony_cirequire "cbc.pl";
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_ci$output = pop and open STDOUT,">$output";
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci&asm_init($ARGV[0]);
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ci$RC5_MAX_ROUNDS=16;
20e1051a39Sopenharmony_ci$RC5_32_OFF=($RC5_MAX_ROUNDS+2)*4;
21e1051a39Sopenharmony_ci$A="edi";
22e1051a39Sopenharmony_ci$B="esi";
23e1051a39Sopenharmony_ci$S="ebp";
24e1051a39Sopenharmony_ci$tmp1="eax";
25e1051a39Sopenharmony_ci$r="ebx";
26e1051a39Sopenharmony_ci$tmpc="ecx";
27e1051a39Sopenharmony_ci$tmp4="edx";
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci&RC5_32_encrypt("RC5_32_encrypt",1);
30e1051a39Sopenharmony_ci&RC5_32_encrypt("RC5_32_decrypt",0);
31e1051a39Sopenharmony_ci&cbc("RC5_32_cbc_encrypt","RC5_32_encrypt","RC5_32_decrypt",0,4,5,3,-1,-1);
32e1051a39Sopenharmony_ci&asm_finish();
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_ciclose STDOUT or die "error closing STDOUT: $!";
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_cisub RC5_32_encrypt
37e1051a39Sopenharmony_ci	{
38e1051a39Sopenharmony_ci	local($name,$enc)=@_;
39e1051a39Sopenharmony_ci
40e1051a39Sopenharmony_ci	&function_begin_B($name,"");
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_ci	&comment("");
43e1051a39Sopenharmony_ci
44e1051a39Sopenharmony_ci	&push("ebp");
45e1051a39Sopenharmony_ci	 &push("esi");
46e1051a39Sopenharmony_ci	&push("edi");
47e1051a39Sopenharmony_ci	 &mov($tmp4,&wparam(0));
48e1051a39Sopenharmony_ci	&mov($S,&wparam(1));
49e1051a39Sopenharmony_ci
50e1051a39Sopenharmony_ci	&comment("Load the 2 words");
51e1051a39Sopenharmony_ci	 &mov($A,&DWP(0,$tmp4,"",0));
52e1051a39Sopenharmony_ci	&mov($B,&DWP(4,$tmp4,"",0));
53e1051a39Sopenharmony_ci
54e1051a39Sopenharmony_ci	&push($r);
55e1051a39Sopenharmony_ci	 &mov($r,	&DWP(0,$S,"",0));
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci	# encrypting part
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ci	if ($enc)
60e1051a39Sopenharmony_ci		{
61e1051a39Sopenharmony_ci		 &add($A,	&DWP(4+0,$S,"",0));
62e1051a39Sopenharmony_ci		&add($B,	&DWP(4+4,$S,"",0));
63e1051a39Sopenharmony_ci
64e1051a39Sopenharmony_ci		for ($i=0; $i<$RC5_MAX_ROUNDS; $i++)
65e1051a39Sopenharmony_ci			{
66e1051a39Sopenharmony_ci			 &xor($A,	$B);
67e1051a39Sopenharmony_ci			&mov($tmp1,	&DWP(12+$i*8,$S,"",0));
68e1051a39Sopenharmony_ci			 &mov($tmpc,	$B);
69e1051a39Sopenharmony_ci			&rotl($A,	&LB("ecx"));
70e1051a39Sopenharmony_ci			&add($A,	$tmp1);
71e1051a39Sopenharmony_ci
72e1051a39Sopenharmony_ci			 &xor($B,	$A);
73e1051a39Sopenharmony_ci			&mov($tmp1,	&DWP(16+$i*8,$S,"",0));
74e1051a39Sopenharmony_ci			 &mov($tmpc,	$A);
75e1051a39Sopenharmony_ci			&rotl($B,	&LB("ecx"));
76e1051a39Sopenharmony_ci			&add($B,	$tmp1);
77e1051a39Sopenharmony_ci			if (($i == 7) || ($i == 11))
78e1051a39Sopenharmony_ci				{
79e1051a39Sopenharmony_ci			 &cmp($r,	$i+1);
80e1051a39Sopenharmony_ci			&je(&label("rc5_exit"));
81e1051a39Sopenharmony_ci				}
82e1051a39Sopenharmony_ci			}
83e1051a39Sopenharmony_ci		}
84e1051a39Sopenharmony_ci	else
85e1051a39Sopenharmony_ci		{
86e1051a39Sopenharmony_ci		 &cmp($r,	12);
87e1051a39Sopenharmony_ci		&je(&label("rc5_dec_12"));
88e1051a39Sopenharmony_ci		 &cmp($r,	8);
89e1051a39Sopenharmony_ci		&je(&label("rc5_dec_8"));
90e1051a39Sopenharmony_ci		for ($i=$RC5_MAX_ROUNDS; $i > 0; $i--)
91e1051a39Sopenharmony_ci			{
92e1051a39Sopenharmony_ci			&set_label("rc5_dec_$i") if ($i == 12) || ($i == 8);
93e1051a39Sopenharmony_ci			 &mov($tmp1,	&DWP($i*8+8,$S,"",0));
94e1051a39Sopenharmony_ci			&sub($B,	$tmp1);
95e1051a39Sopenharmony_ci			 &mov($tmpc,	$A);
96e1051a39Sopenharmony_ci			&rotr($B,	&LB("ecx"));
97e1051a39Sopenharmony_ci			&xor($B,	$A);
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ci			 &mov($tmp1,	&DWP($i*8+4,$S,"",0));
100e1051a39Sopenharmony_ci			&sub($A,	$tmp1);
101e1051a39Sopenharmony_ci			 &mov($tmpc,	$B);
102e1051a39Sopenharmony_ci			&rotr($A,	&LB("ecx"));
103e1051a39Sopenharmony_ci			&xor($A,	$B);
104e1051a39Sopenharmony_ci			}
105e1051a39Sopenharmony_ci		 &sub($B,	&DWP(4+4,$S,"",0));
106e1051a39Sopenharmony_ci		&sub($A,	&DWP(4+0,$S,"",0));
107e1051a39Sopenharmony_ci		}
108e1051a39Sopenharmony_ci
109e1051a39Sopenharmony_ci	&set_label("rc5_exit");
110e1051a39Sopenharmony_ci	 &mov(&DWP(0,$tmp4,"",0),$A);
111e1051a39Sopenharmony_ci	&mov(&DWP(4,$tmp4,"",0),$B);
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ci	 &pop("ebx");
114e1051a39Sopenharmony_ci	&pop("edi");
115e1051a39Sopenharmony_ci	 &pop("esi");
116e1051a39Sopenharmony_ci	&pop("ebp");
117e1051a39Sopenharmony_ci	 &ret();
118e1051a39Sopenharmony_ci	&function_end_B($name);
119e1051a39Sopenharmony_ci	}
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci
122