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],$ARGV[$#ARGV] eq "386");
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ci$BF_ROUNDS=16;
20e1051a39Sopenharmony_ci$BF_OFF=($BF_ROUNDS+2)*4;
21e1051a39Sopenharmony_ci$L="edi";
22e1051a39Sopenharmony_ci$R="esi";
23e1051a39Sopenharmony_ci$P="ebp";
24e1051a39Sopenharmony_ci$tmp1="eax";
25e1051a39Sopenharmony_ci$tmp2="ebx";
26e1051a39Sopenharmony_ci$tmp3="ecx";
27e1051a39Sopenharmony_ci$tmp4="edx";
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci&BF_encrypt("BF_encrypt",1);
30e1051a39Sopenharmony_ci&BF_encrypt("BF_decrypt",0);
31e1051a39Sopenharmony_ci&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
32e1051a39Sopenharmony_ci&asm_finish();
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_ciclose STDOUT or die "error closing STDOUT: $!";
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_cisub BF_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("ebx");
46e1051a39Sopenharmony_ci	&mov($tmp2,&wparam(0));
47e1051a39Sopenharmony_ci	&mov($P,&wparam(1));
48e1051a39Sopenharmony_ci	&push("esi");
49e1051a39Sopenharmony_ci	&push("edi");
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci	&comment("Load the 2 words");
52e1051a39Sopenharmony_ci	&mov($L,&DWP(0,$tmp2,"",0));
53e1051a39Sopenharmony_ci	&mov($R,&DWP(4,$tmp2,"",0));
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_ci	&xor(	$tmp1,	$tmp1);
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci	# encrypting part
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ci	if ($enc)
60e1051a39Sopenharmony_ci		{
61e1051a39Sopenharmony_ci		 &mov($tmp2,&DWP(0,$P,"",0));
62e1051a39Sopenharmony_ci		&xor(	$tmp3,	$tmp3);
63e1051a39Sopenharmony_ci
64e1051a39Sopenharmony_ci		&xor($L,$tmp2);
65e1051a39Sopenharmony_ci		for ($i=0; $i<$BF_ROUNDS; $i+=2)
66e1051a39Sopenharmony_ci			{
67e1051a39Sopenharmony_ci			&comment("");
68e1051a39Sopenharmony_ci			&comment("Round $i");
69e1051a39Sopenharmony_ci			&BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
70e1051a39Sopenharmony_ci
71e1051a39Sopenharmony_ci			&comment("");
72e1051a39Sopenharmony_ci			&comment("Round ".sprintf("%d",$i+1));
73e1051a39Sopenharmony_ci			&BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
74e1051a39Sopenharmony_ci			}
75e1051a39Sopenharmony_ci		# &mov($tmp1,&wparam(0)); In last loop
76e1051a39Sopenharmony_ci		&mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
77e1051a39Sopenharmony_ci		}
78e1051a39Sopenharmony_ci	else
79e1051a39Sopenharmony_ci		{
80e1051a39Sopenharmony_ci		 &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
81e1051a39Sopenharmony_ci		&xor(	$tmp3,	$tmp3);
82e1051a39Sopenharmony_ci
83e1051a39Sopenharmony_ci		&xor($L,$tmp2);
84e1051a39Sopenharmony_ci		for ($i=$BF_ROUNDS; $i>0; $i-=2)
85e1051a39Sopenharmony_ci			{
86e1051a39Sopenharmony_ci			&comment("");
87e1051a39Sopenharmony_ci			&comment("Round $i");
88e1051a39Sopenharmony_ci			&BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
89e1051a39Sopenharmony_ci			&comment("");
90e1051a39Sopenharmony_ci			&comment("Round ".sprintf("%d",$i-1));
91e1051a39Sopenharmony_ci			&BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
92e1051a39Sopenharmony_ci			}
93e1051a39Sopenharmony_ci		# &mov($tmp1,&wparam(0)); In last loop
94e1051a39Sopenharmony_ci		&mov($tmp4,&DWP(0,$P,"",0));
95e1051a39Sopenharmony_ci		}
96e1051a39Sopenharmony_ci
97e1051a39Sopenharmony_ci	&xor($R,$tmp4);
98e1051a39Sopenharmony_ci	&mov(&DWP(4,$tmp1,"",0),$L);
99e1051a39Sopenharmony_ci
100e1051a39Sopenharmony_ci	&mov(&DWP(0,$tmp1,"",0),$R);
101e1051a39Sopenharmony_ci	&function_end($name);
102e1051a39Sopenharmony_ci	}
103e1051a39Sopenharmony_ci
104e1051a39Sopenharmony_cisub BF_ENCRYPT
105e1051a39Sopenharmony_ci	{
106e1051a39Sopenharmony_ci	local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_;
107e1051a39Sopenharmony_ci
108e1051a39Sopenharmony_ci	&mov(	$tmp4,		&DWP(&n2a($i*4),$P,"",0)); # for next round
109e1051a39Sopenharmony_ci
110e1051a39Sopenharmony_ci	&mov(	$tmp2,		$R);
111e1051a39Sopenharmony_ci	&xor(	$L,		$tmp4);
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ci	&shr(	$tmp2,		16);
114e1051a39Sopenharmony_ci	&mov(	$tmp4,		$R);
115e1051a39Sopenharmony_ci
116e1051a39Sopenharmony_ci	&movb(	&LB($tmp1),	&HB($tmp2));	# A
117e1051a39Sopenharmony_ci	&and(	$tmp2,		0xff);		# B
118e1051a39Sopenharmony_ci
119e1051a39Sopenharmony_ci	&movb(	&LB($tmp3),	&HB($tmp4));	# C
120e1051a39Sopenharmony_ci	&and(	$tmp4,		0xff);		# D
121e1051a39Sopenharmony_ci
122e1051a39Sopenharmony_ci	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
123e1051a39Sopenharmony_ci	&mov(	$tmp2,		&DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
124e1051a39Sopenharmony_ci
125e1051a39Sopenharmony_ci	&add(	$tmp2,		$tmp1);
126e1051a39Sopenharmony_ci	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4));
127e1051a39Sopenharmony_ci
128e1051a39Sopenharmony_ci	&xor(	$tmp2,		$tmp1);
129e1051a39Sopenharmony_ci	&mov(	$tmp4,		&DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4));
130e1051a39Sopenharmony_ci
131e1051a39Sopenharmony_ci	&add(	$tmp2,		$tmp4);
132e1051a39Sopenharmony_ci	if (($enc && ($i != 16)) || ((!$enc) && ($i != 1)))
133e1051a39Sopenharmony_ci		{ &xor(	$tmp1,		$tmp1); }
134e1051a39Sopenharmony_ci	else
135e1051a39Sopenharmony_ci		{
136e1051a39Sopenharmony_ci		&comment("Load parameter 0 ($i) enc=$enc");
137e1051a39Sopenharmony_ci		&mov($tmp1,&wparam(0));
138e1051a39Sopenharmony_ci		} # In last loop
139e1051a39Sopenharmony_ci
140e1051a39Sopenharmony_ci	&xor(	$L,		$tmp2);
141e1051a39Sopenharmony_ci	# delay
142e1051a39Sopenharmony_ci	}
143e1051a39Sopenharmony_ci
144e1051a39Sopenharmony_cisub n2a
145e1051a39Sopenharmony_ci	{
146e1051a39Sopenharmony_ci	sprintf("%d",$_[0]);
147e1051a39Sopenharmony_ci	}
148e1051a39Sopenharmony_ci
149