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; 11push(@INC,"${dir}","${dir}../../perlasm"); 12require "x86asm.pl"; 13require "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 34close STDOUT or die "error closing STDOUT: $!"; 35 36sub 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 104sub 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 144sub n2a 145 { 146 sprintf("%d",$_[0]); 147 } 148 149