1 | #! /usr/bin/env perl
|
---|
2 | # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | #
|
---|
4 | # Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | # this file except in compliance with the License. You can obtain a copy
|
---|
6 | # in the file LICENSE in the source distribution or at
|
---|
7 | # https://www.openssl.org/source/license.html
|
---|
8 |
|
---|
9 |
|
---|
10 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
---|
11 | push(@INC,"${dir}","${dir}../../perlasm");
|
---|
12 | require "x86asm.pl";
|
---|
13 | require "cbc.pl";
|
---|
14 |
|
---|
15 | $output = pop and open STDOUT,">$output";
|
---|
16 |
|
---|
17 | &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386");
|
---|
18 |
|
---|
19 | $BF_ROUNDS=16;
|
---|
20 | $BF_OFF=($BF_ROUNDS+2)*4;
|
---|
21 | $L="edi";
|
---|
22 | $R="esi";
|
---|
23 | $P="ebp";
|
---|
24 | $tmp1="eax";
|
---|
25 | $tmp2="ebx";
|
---|
26 | $tmp3="ecx";
|
---|
27 | $tmp4="edx";
|
---|
28 |
|
---|
29 | &BF_encrypt("BF_encrypt",1);
|
---|
30 | &BF_encrypt("BF_decrypt",0);
|
---|
31 | &cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
|
---|
32 | &asm_finish();
|
---|
33 |
|
---|
34 | close STDOUT or die "error closing STDOUT: $!";
|
---|
35 |
|
---|
36 | sub BF_encrypt
|
---|
37 | {
|
---|
38 | local($name,$enc)=@_;
|
---|
39 |
|
---|
40 | &function_begin_B($name,"");
|
---|
41 |
|
---|
42 | &comment("");
|
---|
43 |
|
---|
44 | &push("ebp");
|
---|
45 | &push("ebx");
|
---|
46 | &mov($tmp2,&wparam(0));
|
---|
47 | &mov($P,&wparam(1));
|
---|
48 | &push("esi");
|
---|
49 | &push("edi");
|
---|
50 |
|
---|
51 | &comment("Load the 2 words");
|
---|
52 | &mov($L,&DWP(0,$tmp2,"",0));
|
---|
53 | &mov($R,&DWP(4,$tmp2,"",0));
|
---|
54 |
|
---|
55 | &xor( $tmp1, $tmp1);
|
---|
56 |
|
---|
57 | # encrypting part
|
---|
58 |
|
---|
59 | if ($enc)
|
---|
60 | {
|
---|
61 | &mov($tmp2,&DWP(0,$P,"",0));
|
---|
62 | &xor( $tmp3, $tmp3);
|
---|
63 |
|
---|
64 | &xor($L,$tmp2);
|
---|
65 | for ($i=0; $i<$BF_ROUNDS; $i+=2)
|
---|
66 | {
|
---|
67 | &comment("");
|
---|
68 | &comment("Round $i");
|
---|
69 | &BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
|
---|
70 |
|
---|
71 | &comment("");
|
---|
72 | &comment("Round ".sprintf("%d",$i+1));
|
---|
73 | &BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
|
---|
74 | }
|
---|
75 | # &mov($tmp1,&wparam(0)); In last loop
|
---|
76 | &mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
|
---|
77 | }
|
---|
78 | else
|
---|
79 | {
|
---|
80 | &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
|
---|
81 | &xor( $tmp3, $tmp3);
|
---|
82 |
|
---|
83 | &xor($L,$tmp2);
|
---|
84 | for ($i=$BF_ROUNDS; $i>0; $i-=2)
|
---|
85 | {
|
---|
86 | &comment("");
|
---|
87 | &comment("Round $i");
|
---|
88 | &BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
|
---|
89 | &comment("");
|
---|
90 | &comment("Round ".sprintf("%d",$i-1));
|
---|
91 | &BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
|
---|
92 | }
|
---|
93 | # &mov($tmp1,&wparam(0)); In last loop
|
---|
94 | &mov($tmp4,&DWP(0,$P,"",0));
|
---|
95 | }
|
---|
96 |
|
---|
97 | &xor($R,$tmp4);
|
---|
98 | &mov(&DWP(4,$tmp1,"",0),$L);
|
---|
99 |
|
---|
100 | &mov(&DWP(0,$tmp1,"",0),$R);
|
---|
101 | &function_end($name);
|
---|
102 | }
|
---|
103 |
|
---|
104 | sub BF_ENCRYPT
|
---|
105 | {
|
---|
106 | local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_;
|
---|
107 |
|
---|
108 | &mov( $tmp4, &DWP(&n2a($i*4),$P,"",0)); # for next round
|
---|
109 |
|
---|
110 | &mov( $tmp2, $R);
|
---|
111 | &xor( $L, $tmp4);
|
---|
112 |
|
---|
113 | &shr( $tmp2, 16);
|
---|
114 | &mov( $tmp4, $R);
|
---|
115 |
|
---|
116 | &movb( &LB($tmp1), &HB($tmp2)); # A
|
---|
117 | &and( $tmp2, 0xff); # B
|
---|
118 |
|
---|
119 | &movb( &LB($tmp3), &HB($tmp4)); # C
|
---|
120 | &and( $tmp4, 0xff); # D
|
---|
121 |
|
---|
122 | &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
|
---|
123 | &mov( $tmp2, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
|
---|
124 |
|
---|
125 | &add( $tmp2, $tmp1);
|
---|
126 | &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4));
|
---|
127 |
|
---|
128 | &xor( $tmp2, $tmp1);
|
---|
129 | &mov( $tmp4, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4));
|
---|
130 |
|
---|
131 | &add( $tmp2, $tmp4);
|
---|
132 | if (($enc && ($i != 16)) || ((!$enc) && ($i != 1)))
|
---|
133 | { &xor( $tmp1, $tmp1); }
|
---|
134 | else
|
---|
135 | {
|
---|
136 | &comment("Load parameter 0 ($i) enc=$enc");
|
---|
137 | &mov($tmp1,&wparam(0));
|
---|
138 | } # In last loop
|
---|
139 |
|
---|
140 | &xor( $L, $tmp2);
|
---|
141 | # delay
|
---|
142 | }
|
---|
143 |
|
---|
144 | sub n2a
|
---|
145 | {
|
---|
146 | sprintf("%d",$_[0]);
|
---|
147 | }
|
---|
148 |
|
---|