bootable
bootloader
lk
app
arch
dev
include
kernel
lib
bcache
bio
cbuf
console
debug
font
fs
gfx
gfxconsole
heap
libc
libfdt
openssl
android.testssl
apps
crypto
aes
asn1
bf
bio
bn
buffer
comp
conf
des
asm
crypt586.pl
des-586.pl
des_enc.m4
desboth.pl
readme
t
times
COPYRIGHT
DES.pm
DES.xs
FILES0
INSTALL
Imakefile
KERBEROS
README
VERSION
cbc3_enc.c
cbc_cksm.c
cbc_enc.c
cfb64ede.c
cfb64enc.c
cfb_enc.c
des-lib.com
des.c
des.h
des.pod
des3s.cpp
des_enc.c
des_locl.h
des_old.c
des_old.h
des_old2.c
des_opts.c
des_ver.h
dess.cpp
destest.c
ecb3_enc.c
ecb_enc.c
ede_cbcm_enc.c
enc_read.c
enc_writ.c
fcrypt.c
fcrypt_b.c
makefile.bc
ncbc_enc.c
ofb64ede.c
ofb64enc.c
ofb_enc.c
options.txt
pcbc_enc.c
qud_cksm.c
rand_key.c
read2pwd.c
read_pwd.c
rpc_des.h
rpc_enc.c
rpw.c
set_key.c
speed.c
spr.h
str2key.c
typemap
xcbc_enc.c
dh
dsa
dso
ec
ecdh
ecdsa
engine
err
evp
hmac
jpake
krb5
lhash
md4
md5
mdc2
modes
objects
ocsp
pem
perlasm
pkcs12
pkcs7
pqueue
rand
rc2
rc4
ripemd
rsa
sha
stack
store
threads
ts
txt_db
ui
x509
x509v3
LPdir_nyi.c
LPdir_unix.c
LPdir_vms.c
LPdir_win.c
LPdir_win32.c
LPdir_wince.c
cpt_err.c
cryptlib.c
cryptlib.h
crypto-lib.com
crypto.h
cversion.c
ebcdic.c
ebcdic.h
ex_data.c
ia64cpuid.S
install.com
md32_common.h
mem.c
mem_clr.c
mem_dbg.c
o_dir.c
o_dir.h
o_dir_test.c
o_str.c
o_str.h
o_time.c
o_time.h
opensslconf.h
opensslconf.h.in
opensslv.h
ossl_typ.h
ppccpuid.pl
rules.mk
s390xcap.c
s390xcpuid.S
sparccpuid.S
sparcv9cap.c
symhacks.h
uid.c
x86_64cpuid.pl
x86cpuid.pl
include
patches
ssl
CleanSpec.mk
MODULE_LICENSE_BSD_LIKE
NOTICE
README.android
ThirdPartyProject.prop
android-config.mk
e_os.h
e_os2.h
import_openssl.sh
openssl.config
openssl.version
rules.mk
partition
ptable
text
tga
zlib_inflate
make
platform
project
scripts
target
AndroidBoot.mk
LICENSE
makefile
recovery
scripts
data-ipa-cfg-mgr
data-oss
device
external
filesystems
hardware
init_mss
kernel
mdm-init
oe-core
qcom-opensource
reboot-daemon
shortcut-fe
system
tp-product
tp-proprietary
wlan
README
132 lines
5.7 KiB
Plaintext
132 lines
5.7 KiB
Plaintext
First up, let me say I don't like writing in assembler. It is not portable,
|
|
dependant on the particular CPU architecture release and is generally a pig
|
|
to debug and get right. Having said that, the x86 architecture is probably
|
|
the most important for speed due to number of boxes and since
|
|
it appears to be the worst architecture to to get
|
|
good C compilers for. So due to this, I have lowered myself to do
|
|
assembler for the inner DES routines in libdes :-).
|
|
|
|
The file to implement in assembler is des_enc.c. Replace the following
|
|
4 functions
|
|
des_encrypt1(DES_LONG data[2],des_key_schedule ks, int encrypt);
|
|
des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
|
|
des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
|
|
des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
|
|
|
|
They encrypt/decrypt the 64 bits held in 'data' using
|
|
the 'ks' key schedules. The only difference between the 4 functions is that
|
|
des_encrypt2() does not perform IP() or FP() on the data (this is an
|
|
optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
|
|
perform triple des. The triple DES routines are in here because it does
|
|
make a big difference to have them located near the des_encrypt2 function
|
|
at link time..
|
|
|
|
Now as we all know, there are lots of different operating systems running on
|
|
x86 boxes, and unfortunately they normally try to make sure their assembler
|
|
formating is not the same as the other peoples.
|
|
The 4 main formats I know of are
|
|
Microsoft Windows 95/Windows NT
|
|
Elf Includes Linux and FreeBSD(?).
|
|
a.out The older Linux.
|
|
Solaris Same as Elf but different comments :-(.
|
|
|
|
Now I was not overly keen to write 4 different copies of the same code,
|
|
so I wrote a few perl routines to output the correct assembler, given
|
|
a target assembler type. This code is ugly and is just a hack.
|
|
The libraries are x86unix.pl and x86ms.pl.
|
|
des586.pl, des686.pl and des-som[23].pl are the programs to actually
|
|
generate the assembler.
|
|
|
|
So to generate elf assembler
|
|
perl des-som3.pl elf >dx86-elf.s
|
|
For Windows 95/NT
|
|
perl des-som2.pl win32 >win32.asm
|
|
|
|
[ update 4 Jan 1996 ]
|
|
I have added another way to do things.
|
|
perl des-som3.pl cpp >dx86-cpp.s
|
|
generates a file that will be included by dx86unix.cpp when it is compiled.
|
|
To build for elf, a.out, solaris, bsdi etc,
|
|
cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
|
|
cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
|
|
cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
|
|
cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
|
|
This was done to cut down the number of files in the distribution.
|
|
|
|
Now the ugly part. I acquired my copy of Intels
|
|
"Optimization's For Intel's 32-Bit Processors" and found a few interesting
|
|
things. First, the aim of the exersize is to 'extract' one byte at a time
|
|
from a word and do an array lookup. This involves getting the byte from
|
|
the 4 locations in the word and moving it to a new word and doing the lookup.
|
|
The most obvious way to do this is
|
|
xor eax, eax # clear word
|
|
movb al, cl # get low byte
|
|
xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
|
|
movb al, ch # get next byte
|
|
xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
|
|
shr ecx 16
|
|
which seems ok. For the pentium, this system appears to be the best.
|
|
One has to do instruction interleaving to keep both functional units
|
|
operating, but it is basically very efficient.
|
|
|
|
Now the crunch. When a full register is used after a partial write, eg.
|
|
mov al, cl
|
|
xor edi, DWORD PTR 0x100+des_SP[eax]
|
|
386 - 1 cycle stall
|
|
486 - 1 cycle stall
|
|
586 - 0 cycle stall
|
|
686 - at least 7 cycle stall (page 22 of the above mentioned document).
|
|
|
|
So the technique that produces the best results on a pentium, according to
|
|
the documentation, will produce hideous results on a pentium pro.
|
|
|
|
To get around this, des686.pl will generate code that is not as fast on
|
|
a pentium, should be very good on a pentium pro.
|
|
mov eax, ecx # copy word
|
|
shr ecx, 8 # line up next byte
|
|
and eax, 0fch # mask byte
|
|
xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
|
|
mov eax, ecx # get word
|
|
shr ecx 8 # line up next byte
|
|
and eax, 0fch # mask byte
|
|
xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
|
|
|
|
Due to the execution units in the pentium, this actually works quite well.
|
|
For a pentium pro it should be very good. This is the type of output
|
|
Visual C++ generates.
|
|
|
|
There is a third option. instead of using
|
|
mov al, ch
|
|
which is bad on the pentium pro, one may be able to use
|
|
movzx eax, ch
|
|
which may not incur the partial write penalty. On the pentium,
|
|
this instruction takes 4 cycles so is not worth using but on the
|
|
pentium pro it appears it may be worth while. I need access to one to
|
|
experiment :-).
|
|
|
|
eric (20 Oct 1996)
|
|
|
|
22 Nov 1996 - I have asked people to run the 2 different version on pentium
|
|
pros and it appears that the intel documentation is wrong. The
|
|
mov al,bh is still faster on a pentium pro, so just use the des586.pl
|
|
install des686.pl
|
|
|
|
3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
|
|
functions into des_enc.c because it does make a massive performance
|
|
difference on some boxes to have the functions code located close to
|
|
the des_encrypt2() function.
|
|
|
|
9 Jan 1997 - des-som2.pl is now the correct perl script to use for
|
|
pentiums. It contains an inner loop from
|
|
Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
|
|
273,000 per second. He had a previous version at 250,000 and the best
|
|
I was able to get was 203,000. The content has not changed, this is all
|
|
due to instruction sequencing (and actual instructions choice) which is able
|
|
to keep both functional units of the pentium going.
|
|
We may have lost the ugly register usage restrictions when x86 went 32 bit
|
|
but for the pentium it has been replaced by evil instruction ordering tricks.
|
|
|
|
13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
|
|
raw DES at 281,000 per second on a pentium 100.
|
|
|