#
#  Makefile
#
#  Written by Jari Ruusu, January 27 2006
#
#  Copyright 2001-2006 by Jari Ruusu.
#  Redistribution of this file is permitted under the GNU Public License.
#
#  To compile and install, use commands:  make clean; make
#  This Makefile tries to locate running kernel source directory and
#  steal definitions from kernel Makefile. Note: kernel must be properly
#  configured and compiled in order for this to work.
#  You can override the kernel source directory by defining LINUX_SOURCE
#  like this:  make LINUX_SOURCE=/usr/src/linux-2.2.20aa1
#
#  Both LINUX_SOURCE and KBUILD_OUTPUT must be defined when
#  compiling for 2.6.x kernel with separate object directory.
#

KR:=$(shell uname -r)
ifdef LINUX_SOURCE
	LS:=$(LINUX_SOURCE)
else
	LS:=$(shell  if [ -f /lib/modules/$(KR)/source/Makefile ]; then cd /lib/modules/$(KR)/source && /bin/pwd; \
		else if [ -f /lib/modules/$(KR)/build/include/linux/version.h ]; then cd /lib/modules/$(KR)/build && /bin/pwd; \
		else if [ -f /usr/src/linux/include/linux/version.h ]; then cd /usr/src/linux && /bin/pwd; \
		else if [ -f /usr/src/linux-$(KR)/include/linux/version.h ]; then cd /usr/src/linux-$(KR) && /bin/pwd; \
		else if [ -f /usr/src/kernel-source-$(KR)/include/linux/version.h ]; then cd /usr/src/kernel-source-$(KR) && /bin/pwd; \
		else echo unable-to-guess-source-dir; fi; fi; fi; fi; fi)
endif
ifdef KBUILD_OUTPUT
	OD1:=$(KBUILD_OUTPUT)
else
ifdef LINUX_SOURCE
	OD1:=$(LS)
else
	OD1:=$(shell if [ -f /lib/modules/$(KR)/build/include/linux/version.h ]; then cd /lib/modules/$(KR)/build && /bin/pwd; else echo $(LS); fi)
endif
endif
OD2:=
ifneq ($(LS),$(OD1))
	OD2:= O=$(OD1)
endif
TD:=$(shell /bin/pwd)

USE_KBUILD:=n
MODINST:=y

# Some distros include "" characters in KERNELRELEASE string
KERNELRELEASE_clean:=$(shell echo $(KERNELRELEASE))

EF:=
LF:=-r
CP1:=
PP1:=
VM1:=
VM2:=
VM3:=
SR1:=n
ifeq ($(shell if [ "$(VERSION)$(PATCHLEVEL)0" -lt 260 ]; then echo y; fi),y)
	OD1:=$(LS)
endif
ifeq ($(VERSION).$(PATCHLEVEL),2.4)
	EF += $(kbuild_2_4_nostdinc)
endif
ifeq ($(shell if [ "$(VERSION)$(PATCHLEVEL)0" -ge 260 ]; then echo y; fi),y)
ifeq ($(shell if ! echo " $(CFLAGS) " | grep -q -s "D__KERNEL__"; then echo y; fi),y)
	CFLAGS := $(CPPFLAGS) $(CFLAGS)
endif
	CFLAGS := $(NOSTDINC_FLAGS) $(CFLAGS) $(CFLAGS_MODULE)
	LF:=$(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE)
	CP1:=cd $(OD1) &&
	PP1:=$(TD)/
	MP1:=$(shell if test -e $(OD1)/scripts/mod/modpost; then echo "./scripts/mod/modpost"; else echo "./scripts/modpost"; fi)
	MP1 += $(shell if grep -q -s "define CONFIG_MODVERSIONS 1" $(OD1)/include/linux/autoconf.h; then if grep -q -s "if .*CONFIG_MODVERSIONS.*-m" $(LS)/scripts/Makefile.modpost; then echo -e "\055m"; fi; fi)
	VM1:=k
	VM2:=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE_clean)
	VM3:=$(shell if test -f $(VM2)/block/loop.ko; then echo $(VM2)/block/loop.ko; \
		else if test -f $(VM2)/extra/loop.ko; then echo $(VM2)/extra/loop.ko; \
		else if test -f $(VM2)/kernel/drivers/block/loop.ko; then echo $(VM2)/kernel/drivers/block/loop.ko; \
		fi; fi; fi)
	# some 2.6 kernels need # character in KBUILD_BASENAME and KBUILD_MODNAME
	SR1:=$(shell if grep -q -s "^basename_flags.*KBUILD_BASENAME.*KBUILD_STR" $(LS)/scripts/Makefile.lib; then echo y; fi)
endif

ifneq ($(USE_KBUILD),y)
ifeq ($(SR1),y)
	EF += -D"KBUILD_STR(s)=\#s"
else
	EF += -D"KBUILD_STR(s)=s"
endif
endif

# This is list of modules to build and install
MLIST:=loop_twofish.$(VM1)o loop_serpent.$(VM1)o loop_blowfish.$(VM1)o

# check if depmod supports -F and -b options
ifeq ($(shell if [ "$(VERSION)$(PATCHLEVEL)0" -ge 260 ]; then echo y; fi),y)
	DMOK:=y
else
	DMOK:=$(shell if [ `/sbin/insmod -V 2>&1 | head -n 1 | awk '/^insmod version /{split($$3, a, /\./); printf "%d%03d%03d\n", a[1], a[2], a[3];}'`0 -ge 20020020 ]; then echo y; fi)
endif
ifndef DEPMOD
	DEPMOD:=/sbin/depmod
endif

# check if kernel source has System.map
SYSM:=$(shell if [ -r $(OD1)/System.map ]; then echo y; fi)

RUNDM:=
DMOPTS:=
ifeq ($(DMOK),y)
ifneq "$(strip $(INSTALL_MOD_PATH))" ""
	DMOPTS += -b $(INSTALL_MOD_PATH)
endif
ifeq ($(SYSM),y)
	RUNDM:=y
	DMOPTS += -F $(OD1)/System.map $(KERNELRELEASE_clean)
endif
endif
ifeq ($(KERNELRELEASE_clean),$(KR))
ifeq "$(strip $(INSTALL_MOD_PATH))" ""
	RUNDM:=y
endif
endif

all:
ifeq ($(LS),unable-to-guess-source-dir)
	@echo "Unable to guess linux kernel source directory. Please specify"
	@echo "directory like this:  make LINUX_SOURCE=/usr/src/linux-2.2.20aa1"
	@exit 1
endif
ifeq ($(USE_KBUILD),y)
	rm -r -f tmp-d-kbuild
	mkdir tmp-d-kbuild
	cd tmp-d-kbuild && ln -s ../loop_twofish.c loop_twofish.c && ln -s ../loop_serpent.c loop_serpent.c && ln -s ../loop_blowfish.c loop_blowfish.c
	echo 'obj-m:=loop_twofish.o loop_serpent.o loop_blowfish.o' >>tmp-d-kbuild/Makefile
	cd $(LS) && make M=$(TD)/tmp-d-kbuild modules $(OD2)
ifeq ($(MODINST),y)
	cd $(LS) && make M=$(TD)/tmp-d-kbuild modules_install $(OD2)
endif
else
	cd $(LS) && make SUBDIRS=$(TD) modules Q='@cd $(TD) && if [ "$$@" = "modules" ]; then make modules; fi; # ' $(OD2)
endif

modules: clean $(MLIST)
ifeq ($(MODINST),y)
	mkdir -p $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE_clean)/block
	cp -p $(MLIST) $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE_clean)/block
endif
ifeq ($(RUNDM),y)
	$(DEPMOD) -a $(DMOPTS)
endif
	sync
	@echo "Currently running kernel is  " $(KR)
	@echo "Modules were built for kernel" $(KERNELRELEASE_clean)
ifneq ($(KERNELRELEASE_clean),$(KR))
	@echo "WARNING - THESE MODULES WILL NOT WORK WITH CURRENTLY RUNNING KERNEL"
endif

loop_twofish.$(VM1)o: loop_twofish.c
	$(CP1) $(CC) $(CFLAGS) $(EF) -D"KBUILD_BASENAME=KBUILD_STR(loop_twofish)" -D"KBUILD_MODNAME=KBUILD_STR(loop_twofish)" -c $(PP1)loop_twofish.c -o $(PP1)loop_twofish.o
ifneq "$(VM1)" ""
	$(CP1) $(MP1) vmlinux $(PP1)loop_twofish.o $(VM3) >/dev/null 2>&1
	$(CP1) $(CC) $(CFLAGS) $(EF) -D"KBUILD_BASENAME=KBUILD_STR(loop_twofish_mod)" -D"KBUILD_MODNAME=KBUILD_STR(loop_twofish)" -c $(PP1)loop_twofish.mod.c -o $(PP1)loop_twofish.mod.o
	$(LD) $(LF) loop_twofish.o loop_twofish.mod.o -o loop_twofish.$(VM1)o
	rm -f loop_twofish.o loop_twofish.mod.[co] $(VM3).mod.[co]
endif

loop_serpent.$(VM1)o: loop_serpent.c
	$(CP1) $(CC) $(CFLAGS) $(EF) -D"KBUILD_BASENAME=KBUILD_STR(loop_serpent)" -D"KBUILD_MODNAME=KBUILD_STR(loop_serpent)" -c $(PP1)loop_serpent.c -o $(PP1)loop_serpent.o
ifneq "$(VM1)" ""
	$(CP1) $(MP1) vmlinux $(PP1)loop_serpent.o $(VM3) >/dev/null 2>&1
	$(CP1) $(CC) $(CFLAGS) $(EF) -D"KBUILD_BASENAME=KBUILD_STR(loop_serpent_mod)" -D"KBUILD_MODNAME=KBUILD_STR(loop_serpent)" -c $(PP1)loop_serpent.mod.c -o $(PP1)loop_serpent.mod.o
	$(LD) $(LF) loop_serpent.o loop_serpent.mod.o -o loop_serpent.$(VM1)o
	rm -f loop_serpent.o loop_serpent.mod.[co] $(VM3).mod.[co]
endif

loop_blowfish.$(VM1)o: loop_blowfish.c
	$(CP1) $(CC) $(CFLAGS) $(EF) -D"KBUILD_BASENAME=KBUILD_STR(loop_blowfish)" -D"KBUILD_MODNAME=KBUILD_STR(loop_blowfish)" -c $(PP1)loop_blowfish.c -o $(PP1)loop_blowfish.o
ifneq "$(VM1)" ""
	$(CP1) $(MP1) vmlinux $(PP1)loop_blowfish.o $(VM3) >/dev/null 2>&1
	$(CP1) $(CC) $(CFLAGS) $(EF) -D"KBUILD_BASENAME=KBUILD_STR(loop_blowfish_mod)" -D"KBUILD_MODNAME=KBUILD_STR(loop_blowfish)" -c $(PP1)loop_blowfish.mod.c -o $(PP1)loop_blowfish.mod.o
	$(LD) $(LF) loop_blowfish.o loop_blowfish.mod.o -o loop_blowfish.$(VM1)o
	rm -f loop_blowfish.o loop_blowfish.mod.[co] $(VM3).mod.[co]
endif

clean:
	rm -f *.o *.ko *.mod.c test-file[1234]
	rm -f -r test-dir1 tmp-d-kbuild

TLD:=/dev/loop7
TEST_LE_BLOWFISH_TYPES:=no
TEST_GPG_TYPES:=yes
tests:
	dd if=/dev/zero of=test-file1 bs=1024 count=33
	cp test-file1 test-file3
	echo 09876543210987654321 | /sbin/losetup -p 0 -e AES128 $(TLD) test-file3
	dd if=/dev/zero of=$(TLD) bs=1024 count=33 conv=notrunc
	/sbin/losetup -d $(TLD)
	/sbin/modprobe loop_twofish
	make test-part2 CT=twofish128 LOINIT=0 GK= MD=763ebf26964b3202e4740ced21018f19
	make test-part2 CT=twofish192 LOINIT=0 GK= MD=6d5868395e2bf9de5b5bc9e036646061
	make test-part2 CT=twofish256 LOINIT=0 GK= MD=65332bb73af9ae564d452a21e053f1c5
	make test-part2 CT=twofish128 LOINIT=1 GK= MD=1a814ea93ec65bf0a321177c8f2afbb0
	make test-part2 CT=twofish192 LOINIT=1 GK= MD=941c708664436917cfa2301aac900164
	make test-part2 CT=twofish256 LOINIT=1 GK= MD=5c4ca27adacce34b22d4ffdad9086309
	/sbin/modprobe loop_serpent
	make test-part2 CT=serpent128 LOINIT=0 GK= MD=7d7bc9de37b30179a164e7f9e9361557
	make test-part2 CT=serpent192 LOINIT=0 GK= MD=5c7623e041530f6647ae0b72a78c41fd
	make test-part2 CT=serpent256 LOINIT=0 GK= MD=31851a69091fc7681bfb8bbea4663f3f
	make test-part2 CT=serpent128 LOINIT=2 GK= MD=54bf141d4571bae5b954cd34df09e9a9
	make test-part2 CT=serpent192 LOINIT=2 GK= MD=e48ce972d02749284ae018749821e425
	make test-part2 CT=serpent256 LOINIT=2 GK= MD=260a96d831cfa4c89975327cea217e07
	/sbin/modprobe loop_blowfish
	make test-part2 CT=blowfish128 LOINIT=0 GK= MD=0decbfdab73dea75b7bf14afbc3181b9
	make test-part2 CT=blowfish192 LOINIT=0 GK= MD=031669b257da3e6dc9cf4aba140ef1ad
	make test-part2 CT=blowfish256 LOINIT=0 GK= MD=c7ed54673dedc02a1d30abe4ebec2753
ifeq ($(TEST_LE_BLOWFISH_TYPES),yes)
	# these md5 sums can only be produced on little endian boxes
	make test-part2 CT=blowfish128 LOINIT=1 GK= MD=22c8593065df1250306bfed05c0b486a
	make test-part2 CT=blowfish192 LOINIT=1 GK= MD=31c964f6e830f74a02a90905aa8efb2c
	make test-part2 CT=blowfish256 LOINIT=1 GK= MD=74ada888670d7278be00eb133feae2f5
endif
ifeq ($(TEST_GPG_TYPES),yes)
	mkdir test-dir1
	make test-part2 CT=twofish128 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=ddf13c7d8e98e2e811c909521dc14509
	make test-part2 CT=twofish192 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=b6903ab3c6edcfb7d4304536ede5a7eb
	make test-part2 CT=twofish256 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=da58adcd6354578dfda581239a1e045f
	make test-part2 CT=twofish128 LOINIT=0 GK="-K gpgkey2.asc -G test-dir1" MD=9ade662b89929151f9addadb1c50c473
	make test-part2 CT=twofish192 LOINIT=0 GK="-K gpgkey2.asc -G test-dir1" MD=6282fcb36094212a88ca4e2f3b1d5df3
	make test-part2 CT=twofish256 LOINIT=0 GK="-K gpgkey2.asc -G test-dir1" MD=c9cfd9ede40efc7786c4d20ee64da245
	make test-part2 CT=twofish128 LOINIT=0 GK="-K gpgkey3.asc -G test-dir1" MD=318869c1f51d86912d5784a1dc717b08
	make test-part2 CT=twofish192 LOINIT=0 GK="-K gpgkey3.asc -G test-dir1" MD=ffe7e80743edc5120be7bbcb8076b368
	make test-part2 CT=twofish256 LOINIT=0 GK="-K gpgkey3.asc -G test-dir1" MD=345b77d2e3d318ba27214bbc8313ae0f
	make test-part2 CT=serpent128 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=ac78f204e993e7141baaa30cd1e24221
	make test-part2 CT=serpent192 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=c2a724f1973694cb898996dba3182c55
	make test-part2 CT=serpent256 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=7c2d2f438129e1084cb41a622fb77ca4
	make test-part2 CT=serpent128 LOINIT=0 GK="-K gpgkey2.asc -G test-dir1" MD=b3992dd60a999a3cba18fad15492b8aa
	make test-part2 CT=serpent192 LOINIT=0 GK="-K gpgkey2.asc -G test-dir1" MD=e6cfc39e113943db1d03797dbf5cd5cd
	make test-part2 CT=serpent256 LOINIT=0 GK="-K gpgkey2.asc -G test-dir1" MD=f111de9256b5adf0f12fe1c75c261feb
	make test-part2 CT=serpent128 LOINIT=0 GK="-K gpgkey3.asc -G test-dir1" MD=96f3d5321b00f5bf25852627dc2d48a8
	make test-part2 CT=serpent192 LOINIT=0 GK="-K gpgkey3.asc -G test-dir1" MD=cb9729cb56a8358198dc61995b3a3cd2
	make test-part2 CT=serpent256 LOINIT=0 GK="-K gpgkey3.asc -G test-dir1" MD=b4d9758d5d387fce43a1d436a01d3d68
	make test-part2 CT=blowfish128 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=d1cca0dc44e7af8a628a0978ac0fe26d
	make test-part2 CT=blowfish192 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=e5bbb6648b893d1e1db08423e8806b53
	make test-part2 CT=blowfish256 LOINIT=0 GK="-K gpgkey1.asc -G test-dir1" MD=fdf78c384eb14215061f81e0c098b777
endif
	rm -f -r test-file[1234] test-dir1
	@echo "*** Test results ok ***"

test-part2:
	echo 12345678901234567890 | /sbin/losetup -p 0 -e $(CT) -I $(LOINIT) $(GK) $(TLD) test-file1
	dd if=test-file3 of=$(TLD) bs=1024 count=33 conv=notrunc
	/sbin/losetup -d $(TLD)
	echo 12345678901234567890 | /sbin/losetup -p 0 -e $(CT) -I $(LOINIT) $(GK) $(TLD) test-file1
	dd if=$(TLD) of=test-file4 bs=33792 count=1
	/sbin/losetup -d $(TLD)
	md5sum test-file1 >test-file2
	echo "$(MD)  test-file1" | cmp test-file2 -
	cmp test-file3 test-file4

.PHONY: all clean tests test-part2
