synced with mainstream

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-11-22 12:11:17 +01:00
commit 4fe6aa0961
220 changed files with 54340 additions and 18150 deletions

58
.bzrignore Normal file
View file

@ -0,0 +1,58 @@
00_header
10_*
30_os-prober
40_custom
aclocal.m4
autom4te.cache
build_env.mk
.bzrignore
config.cache
config.h
config.h.in
config.log
config.status
configure
conf/*.mk
*.d
DISTLIST
docs/*.info
docs/stamp-vti
docs/version.texi
*.elf
*.exec
genkernsyms.sh
gensymlist.sh
grub-dumpbios
grub-editenv
grub-emu
grub_emu_init.c
grub_emu_init.h
grub-fstest
grub_fstest_init.c
grub_fstest_init.h
grub-install
grub-mk*
grub-pe2elf
grub-probe
grub_probe_init.c
grub_probe_init.h
grub_script.tab.c
grub_script.tab.h
grub-setup
grub_setup_init.c
grub_setup_init.h
*.img
include/grub/cpu
include/grub/machine
*.lst
Makefile
*.mod
mod-*.c
*.pf2
po/*.mo
po/grub.pot
stamp-h
stamp-h1
stamp-h.in
symlist.c
update-grub_lib

1121
ChangeLog

File diff suppressed because it is too large Load diff

19
INSTALL
View file

@ -16,8 +16,14 @@ configuring the GRUB.
* GNU Bison 2.3 or later
* GNU binutils 2.9.1.0.23 or later
* Other standard GNU/Unix tools
If you use a development snapshot or want to hack on GRUB you may
need the following.
* Ruby 1.6 or later
* Autoconf 2.59 or later
* Python 2.5.2 or later
* Autoconf 2.59d or later
* Automake 1.10.1 or later
Configuring the GRUB
====================
@ -48,11 +54,12 @@ Building the GRUB
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and
type `./autogen.sh' and then `./configure' to configure the
package for your system. If you're using `csh' on an old version
of System V, you might need to type `sh ./configure' instead to
prevent `csh' from trying to execute `configure' itself.
1. `cd' to the directory containing the package's source code. If
you don't use a release tarball you have to type `./autogen.sh'.
Type `./configure' to configure the package for your system.
If you're using `csh' on an old version of System V, you might
need to type `sh ./configure' instead to prevent `csh' from trying
to execute `configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.

View file

@ -41,6 +41,13 @@ includedir = @includedir@
pkgdatadir = $(datadir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`
pkglibdir = $(libdir)/`echo @PACKAGE_TARNAME@/$(target_cpu)-$(platform) | sed '$(transform)'`
XGETTEXT = @XGETTEXT@
MSGMERGE = @MSGMERGE@
MSGFMT = @MSGFMT@
LINGUAS = $(shell tr '\n' ' ' < $(srcdir)/po/LINGUAS)
PACKAGE = @PACKAGE@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@ -59,6 +66,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
MKDIR_P = @MKDIR_P@
mkinstalldirs = $(srcdir)/mkinstalldirs
@ -66,15 +74,15 @@ CC = @CC@
CFLAGS = @CFLAGS@
ASFLAGS = @ASFLAGS@
LDFLAGS = @LDFLAGS@
CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include -Wall -W \
-DGRUB_LIBDIR=\"$(pkglibdir)\"
CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \
-DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\"
TARGET_CC = @TARGET_CC@
TARGET_CFLAGS = @TARGET_CFLAGS@
TARGET_ASFLAGS = @TARGET_ASFLAGS@
TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@
TARGET_APPLE_CC = @TARGET_APPLE_CC@
OBJCONV = @OBJCONV@
TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include \
TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \
-Wall -W
TARGET_LDFLAGS = @TARGET_LDFLAGS@
TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@
@ -100,7 +108,7 @@ AWK = @AWK@
LIBCURSES = @LIBCURSES@
LIBUSB = @LIBUSB@
YACC = @YACC@
UNIFONT_BDF = @UNIFONT_BDF@
FONT_SOURCE = @FONT_SOURCE@
# Options.
enable_grub_emu = @enable_grub_emu@
@ -114,9 +122,7 @@ enable_efiemu = @enable_efiemu@
### General variables.
RMKFILES = $(addprefix conf/,common.rmk i386-coreboot.rmk i386-efi.rmk \
i386-qemu.rmk i386-ieee1275.rmk i386-pc.rmk i386.rmk powerpc-ieee1275.rmk \
sparc64-ieee1275.rmk x86_64-efi.rmk)
RMKFILES = $(wildcard conf/*.rmk)
MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES))
@ -149,9 +155,12 @@ $(addprefix $(srcdir)/,$(MKFILES)): %.mk: %.rmk genmk.rb
include $(srcdir)/conf/$(target_cpu)-$(platform).mk
# For external modules.
-include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk)
### General targets.
CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA)
CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo
pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst
moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
cat $(DEFSYMFILES) /dev/null \
@ -173,28 +182,32 @@ handler.lst: $(HANDLERFILES)
parttool.lst: $(PARTTOOLFILES)
cat $^ /dev/null | sort | uniq > $@
ifneq (true, $(MAKEINFO))
info_INFOS += docs/grub.info
endif
MOSTLYCLEANFILES += vti.tmp
MAINTAINER_CLEANFILES += docs/stamp-vti docs/version.texi
docs/version.texi: docs/stamp-vti
docs/stamp-vti: docs/grub.texi
docs/stamp-vti: docs/grub.texi configure.ac
$(MKDIR_P) docs
(set `$(SHELL) $(srcdir)/docs/mdate-sh $<`; \
echo "@set UPDATED $$1 $$2 $$3"; \
echo "@set UPDATED-MONTH $$2 $$3"; \
echo "@set EDITION $(PACKAGE_VERSION)"; \
echo "@set VERSION $(PACKAGE_VERSION)") > vti.tmp
@cmp -s vti.tmp $(srcdir)/docs/version.texi \
|| (echo "Updating $(srcdir)/docs/version.texi"; \
cp vti.tmp $(srcdir)/docs/version.texi)
@cmp -s vti.tmp $(builddir)/docs/version.texi \
|| (echo "Updating $(builddir)/docs/version.texi"; \
cp vti.tmp $(builddir)/docs/version.texi)
-@rm -f vti.tmp
@cp $(srcdir)/docs/version.texi $@
@cp $(builddir)/docs/version.texi $@
# Use --force until such time as the documentation is cleaned up.
docs/grub.info: docs/grub.texi docs/version.texi docs/fdl.texi
$(MAKEINFO) --no-split --force $< -o $@ || :
$(MKDIR_P) docs
-$(MAKEINFO) -P $(builddir)/docs --no-split --force $< -o $@
ifeq (, $(UNIFONT_BDF))
ifeq (, $(FONT_SOURCE))
else
ifeq ($(enable_grub_mkfont),yes)
@ -205,11 +218,11 @@ pkgdata_DATA += unicode.pf2 ascii.pf2
UNICODE_ARROWS=0x2190-0x2193
UNICODE_LINES=0x2501-0x251B
unicode.pf2: $(UNIFONT_BDF) grub-mkfont
$(builddir)/grub-mkfont -o $@ $(UNIFONT_BDF)
unicode.pf2: $(FONT_SOURCE) grub-mkfont
$(builddir)/grub-mkfont -o $@ $(FONT_SOURCE)
ascii.pf2: $(UNIFONT_BDF) grub-mkfont
$(builddir)/grub-mkfont -o $@ $(UNIFONT_BDF) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
ascii.pf2: $(FONT_SOURCE) grub-mkfont
$(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
endif
endif
@ -230,10 +243,8 @@ build_env.mk: Makefile
echo "COMMON_LDFLAGS=$(COMMON_LDFLAGS)"\
) > $@
pkglib_BUILDDIR += config.h grub_script.tab.h
include_DATA += $(shell find $(srcdir)/include -name \*.h | sed -e "s,^$(srcdir)/,,g") \
include/grub/cpu include/grub/machine
all-local: $(PROGRAMS) $(PKGLIB) $(PKGDATA) $(SCRIPTS) $(INFOS) $(MKFILES)
all-local: $(PROGRAMS) $(PKGLIB) $(PKGDATA) $(SCRIPTS) $(INFOS) $(MKFILES) $(foreach lang, $(LINGUAS), po/$(lang).mo)
install: install-local
@ -246,20 +257,6 @@ install-local: all
dest="`echo $$file | sed 's,.*/,,'`"; \
$(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkglibdir)/$$dest; \
done
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(includedir)
@list='$(include_DATA)'; \
for file in $$list; do \
if test -e "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,include/,,'`"; \
destdir="`echo $$dest | sed 's,[^/]*$$,,g'`"; \
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(includedir)/$$destdir; \
if test -f "$$dir$$file"; then \
$(INSTALL_DATA) $$dir$$file $(DESTDIR)$(includedir)/$$dest; \
elif test -L "$$dir$$file"; then \
rm -rf $(DESTDIR)$(includedir)/$$dest && \
cp -fR $$dir$$file $(DESTDIR)$(includedir)/$$dest; \
fi; \
done
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
@list='$(PKGDATA)'; \
for file in $$list; do \
@ -311,6 +308,13 @@ install-local: all
dest="`echo $$file | sed 's,.*/,,'`"; \
$(INSTALL_DATA) $$dir$$file $(DESTDIR)$(libdir)/grub/$$dest; \
done
$(foreach lang, $(LINGUAS), \
$(shell $(mkinstalldirs) $(DESTDIR)/$(datadir)/locale/$(lang)/LC_MESSAGES) \
@list='po/$(lang).mo'; \
for file in $$list; do \
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
$(INSTALL_DATA) $$dir$$file $(DESTDIR)/$(datadir)/locale/$(lang)/LC_MESSAGES/$(PACKAGE).mo; \
done)
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(infodir)
@list='$(info_INFOS)'; \
for file in $$list; do \
@ -351,11 +355,6 @@ uninstall:
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
rm -f $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
done
@list='$(include_DATA)'; \
for file in $$list; do \
dest="`echo $$file | sed 's,include/,,'`"; \
rm -f $(DESTDIR)$(includedir)/$$dest; \
done
@list='$(lib_SCRIPTS)'; \
for file in $$list; do \
dest="`echo $$file | sed 's,.*/,,'`"; \
@ -446,6 +445,9 @@ check:
.SUFFIX: .c .o .S .d
# Regenerate configure and Makefile automatically.
$(srcdir)/aclocal.m4: configure.ac acinclude.m4
cd $(srcdir) && aclocal
$(srcdir)/configure: configure.ac aclocal.m4
cd $(srcdir) && autoconf
@ -470,6 +472,17 @@ gensymlist.sh: gensymlist.sh.in config.status
genkernsyms.sh: genkernsyms.sh.in config.status
$(SHELL) ./config.status
$(srcdir)/po/$(PACKAGE).pot: po/POTFILES po/POTFILES-shell
cd $(srcdir) && $(XGETTEXT) --from-code=utf-8 -o $@ -f $< --keyword=_
cd $(srcdir) && $(XGETTEXT) --from-code=utf-8 -o $@ -f po/POTFILES-shell -j --language=Shell
$(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po): po/$(PACKAGE).pot
$(MSGMERGE) -U $@ $^
po/%.mo: po/%.po
$(MKDIR_P) $$(dirname $@)
$(MSGFMT) -c --statistics -o $@ $^
.PHONY: all install install-strip uninstall clean mostlyclean distclean
.PHONY: maintainer-clean info dvi dist check

20
NEWS
View file

@ -1,5 +1,15 @@
New in 1.97 - :
* Add support for loading XNU (MacOS X kernel).
* ACPI override support.
* Integrated gptsync.
* Password protection support.
* Partition manipulation tool.
* Add `keystatus' command.
* Unicode fonts are now used by default.
@ -12,9 +22,7 @@ New in 1.97 - :
* Add support for RAID levels 4,6 and 10.
* Add support for lua scripts.
* update-grub is renamed to grub-mkconfig.
* update-grub is replaced by grub-mkconfig.
* When booting from PXE, PXE can be used to load files.
@ -26,8 +34,6 @@ New in 1.97 - :
* Add Cygwin support.
* Add grub-pe2elf to convert PE modules to ELF modules.
* Add x86_64 EFI support.
* Use LZMA compression instead of LZO.
@ -47,13 +53,13 @@ New in 1.97 - :
* grub-mkconfig supports os-prober to add operating systems to the
boot menu.
* The ATA driver supports filesystems bigger than 2TB.
* The ATA driver supports devices bigger than 2 TiB.
* Add support for the UDF, AFS and EXT4 filesystems.
* The ISO9660 filesystem supports the Joliet extension
* Add aout and BSD kernel loaders.
* Add support for loading kernels of FreeBSD, NetBSD and OpenBSD.
* Add new command `sleep'.

View file

@ -92,7 +92,7 @@ else
AC_MSG_ERROR([${CC-cc} cannot compile C source code])
fi
grub_cv_prog_objcopy_absolute=yes
for link_addr in 2000 8000 7C00; do
for link_addr in 0x2000 0x8000 0x7C00; do
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
else
AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])

13
autogen.sh Normal file → Executable file
View file

@ -2,12 +2,19 @@
set -e
aclocal
autoconf
autoheader
echo timestamp > stamp-h.in
for rmk in conf/*.rmk; do
ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`
python util/import_gcry.py lib/libgcrypt/ .
for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do
if test -e $rmk ; then
ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`
fi
done
./gendistlist.sh > DISTLIST
sh gendistlist.sh > DISTLIST
exit 0

View file

@ -552,7 +552,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
grub_free (exclude);
grub_free (load_only);
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table");
"Couldn't allocate table");
}
grub_memcpy (table_dsdt, dsdt, dsdt->length);
}
@ -579,7 +579,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
grub_free (exclude);
grub_free (load_only);
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table structure");
"Couldn't allocate table structure");
}
table->size = curtable->length;
table->addr = grub_malloc (table->size);
@ -588,7 +588,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
{
free_tables ();
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table");
"Couldn't allocate table");
}
table->next = acpi_tables;
acpi_tables = table;
@ -675,7 +675,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
{
free_tables ();
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table structure");
"Couldn't allocate table structure");
}
table->size = size;

View file

@ -1,7 +1,7 @@
/* cpuid.c - test for CPU features */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
* Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
* Based on gcc/gcc/config/i386/driver-i386.c
*
* GRUB is free software: you can redistribute it and/or modify
@ -24,6 +24,7 @@
#include <grub/env.h>
#include <grub/command.h>
#include <grub/extcmd.h>
#include <grub/i386/cpuid.h>
#define cpuid(num,a,b,c,d) \
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
@ -38,14 +39,14 @@ static const struct grub_arg_option options[] =
#define bit_LM (1 << 29)
static unsigned char has_longmode = 0;
unsigned char grub_cpuid_has_longmode = 0;
static grub_err_t
grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
return has_longmode ? GRUB_ERR_NONE
return grub_cpuid_has_longmode ? GRUB_ERR_NONE
: grub_error (GRUB_ERR_TEST_FAILURE, "false");
}
@ -55,7 +56,7 @@ GRUB_MOD_INIT(cpuid)
{
#ifdef __x86_64__
/* grub-emu */
has_longmode = 1;
grub_cpuid_has_longmode = 1;
#else
unsigned int eax, ebx, ecx, edx;
unsigned int max_level;
@ -82,7 +83,7 @@ GRUB_MOD_INIT(cpuid)
goto done;
cpuid (0x80000001, eax, ebx, ecx, edx);
has_longmode = !!(edx & bit_LM);
grub_cpuid_has_longmode = !!(edx & bit_LM);
done:
#endif

View file

@ -336,8 +336,19 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
return 0;
}
/* clear */
static grub_err_t
grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
grub_cls ();
return 0;
}
static grub_command_t cmd_cat, cmd_help, cmd_root;
static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
static grub_command_t cmd_clear;
GRUB_MOD_INIT(minicmd)
{
@ -362,6 +373,9 @@ GRUB_MOD_INIT(minicmd)
cmd_exit =
grub_register_command ("exit", grub_mini_cmd_exit,
0, "exit from GRUB");
cmd_clear =
grub_register_command ("clear", grub_mini_cmd_clear,
0, "clear the screen");
}
GRUB_MOD_FINI(minicmd)
@ -373,4 +387,5 @@ GRUB_MOD_FINI(minicmd)
grub_unregister_command (cmd_rmmod);
grub_unregister_command (cmd_lsmod);
grub_unregister_command (cmd_exit);
grub_unregister_command (cmd_clear);
}

View file

@ -349,8 +349,6 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
grub_memcpy (hashme.prefix, hash_prefix, sizeof (hashme.prefix));
md5 ((char *) &hashme, sizeof (hashme), (char *) xnu_uuid);
xnu_uuid[6] = (xnu_uuid[6] & 0xf) | 0x30;
xnu_uuid[8] = (xnu_uuid[8] & 0x3f) | 0x80;
grub_sprintf (uuid_string,
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
(unsigned int) xnu_uuid[0], (unsigned int) xnu_uuid[1],

View file

@ -28,6 +28,20 @@ ifeq ($(enable_grub_fstest), yes)
bin_UTILITIES += grub-fstest
endif
bin_UTILITIES += grub-mkisofs
grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \
util/mkisofs/hash.c util/mkisofs/joliet.c \
util/mkisofs/match.c util/mkisofs/mkisofs.c \
util/mkisofs/multi.c util/mkisofs/name.c \
util/mkisofs/rock.c util/mkisofs/tree.c \
util/mkisofs/write.c \
\
gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c \
gnulib/error.c gnulib/progname.c
grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \
-I$(srcdir)/util/mkisofs/include \
-Wno-all -Werror
# For grub-fstest.
util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
grub_fstest_SOURCES = util/grub-fstest.c util/hostfs.c util/misc.c \
@ -161,13 +175,6 @@ CLEANFILES += $(grub-mkconfig_SCRIPTS)
grub-mkconfig_DATA += util/grub.d/README
# For grub-dumpbios
grub-dumpbios: util/grub-dumpbios.in config.status
./config.status --file=$@:$<
chmod +x $@
sbin_SCRIPTS += grub-dumpbios
CLEANFILES += grub-dumpbios
# Filing systems.
pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \
ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod \
@ -368,7 +375,7 @@ pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \
configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
read.mod sleep.mod loadenv.mod crc.mod parttool.mod \
msdospart.mod memrw.mod normal.mod sh.mod lua.mod \
msdospart.mod memrw.mod normal.mod sh.mod \
gptsync.mod true.mod probe.mod password.mod \
keystatus.mod
@ -542,23 +549,6 @@ sh_mod_SOURCES = script/sh/main.c script/sh/script.c script/sh/execute.c \
sh_mod_CFLAGS = $(COMMON_CFLAGS)
sh_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For lua.mod.
lua_mod_SOURCES = script/lua/lapi.c script/lua/lcode.c script/lua/ldebug.c \
script/lua/ldo.c script/lua/ldump.c script/lua/lfunc.c \
script/lua/lgc.c script/lua/llex.c script/lua/lmem.c \
script/lua/lobject.c script/lua/lopcodes.c script/lua/lparser.c \
script/lua/lstate.c script/lua/lstring.c script/lua/ltable.c \
script/lua/ltm.c script/lua/lundump.c script/lua/lvm.c \
script/lua/lzio.c script/lua/lauxlib.c script/lua/lbaselib.c \
script/lua/linit.c script/lua/ltablib.c script/lua/lstrlib.c \
script/lua/grub_main.c script/lua/grub_lib.c
lua_mod_CFLAGS = $(COMMON_CFLAGS)
lua_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Extra libraries for lua
# script/lua/lmathlib.c script/lua/loslib.c script/lua/liolib.c
# script/lua/ldblib.c script/lua/loadlib.c
# Common Video Subsystem specific modules.
pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod \
png.mod font.mod gfxterm.mod video_fb.mod

View file

@ -150,11 +150,14 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
grub_emu_LDFLAGS = $(LIBCURSES)
sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/i386/pc/grub-install.in
grub_install_SOURCES = util/grub-install.in
bin_SCRIPTS += grub-mkrescue
grub_mkrescue_SOURCES = util/grub-mkrescue.in
# Modules.
pkglib_MODULES = linux.mod multiboot.mod \
aout.mod play.mod serial.mod ata.mod \
aout.mod play.mod serial.mod \
memdisk.mod pci.mod lspci.mod reboot.mod \
halt.mod datetime.mod date.mod datehook.mod \
lsmmap.mod mmap.mod
@ -218,11 +221,6 @@ play_mod_SOURCES = commands/i386/pc/play.c
play_mod_CFLAGS = $(COMMON_CFLAGS)
play_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ata.mod.
ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For memdisk.mod.
memdisk_mod_SOURCES = disk/memdisk.c
memdisk_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -110,7 +110,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in
# Modules.
pkglib_MODULES = halt.mod reboot.mod suspend.mod \
multiboot.mod aout.mod serial.mod linux.mod \
aout.mod serial.mod linux.mod \
nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \
date.mod datehook.mod lsmmap.mod mmap.mod
@ -126,15 +126,6 @@ mmap_mod_CFLAGS = $(COMMON_CFLAGS)
mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For multiboot.mod.
multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
loader/i386/multiboot_helper.S \
loader/multiboot2.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For aout.mod.
aout_mod_SOURCES = loader/aout.c
aout_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -16,31 +16,31 @@ pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \
# For boot.img.
boot_img_SOURCES = boot/i386/pc/boot.S
boot_img_ASFLAGS = $(COMMON_ASFLAGS)
boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
boot_img_FORMAT = binary
# For pxeboot.img
pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S
pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS)
pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
pxeboot_img_FORMAT = binary
# For diskboot.img.
diskboot_img_SOURCES = boot/i386/pc/diskboot.S
diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)8000
diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8000
diskboot_img_FORMAT = binary
# For lnxboot.img.
lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S
lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)6000
lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x6000
lnxboot_img_FORMAT = binary
# For cdboot.img.
cdboot_img_SOURCES = boot/i386/pc/cdboot.S
cdboot_img_ASFLAGS = $(COMMON_ASFLAGS)
cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
cdboot_img_FORMAT = binary
# For kernel.img.
@ -87,14 +87,15 @@ sbin_UTILITIES += grub-emu
endif
# For grub-mkimage.
grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
grub_mkimage_SOURCES = gnulib/progname.c util/i386/pc/grub-mkimage.c util/misc.c \
util/resolve.c lib/LzmaEnc.c lib/LzFind.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile
# For grub-setup.
util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \
grub_setup_SOURCES = gnulib/progname.c \
util/i386/pc/grub-setup.c util/hostdisk.c \
util/misc.c util/getroot.c kern/device.c kern/disk.c \
kern/err.c kern/misc.c kern/parser.c kern/partition.c \
kern/file.c kern/fs.c kern/env.c fs/fshelp.c \
@ -168,22 +169,21 @@ grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \
grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB)
endif
# Scripts.
sbin_SCRIPTS = grub-install
bin_SCRIPTS = grub-mkrescue
sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/grub-install.in
# For grub-install.
grub_install_SOURCES = util/i386/pc/grub-install.in
bin_SCRIPTS += grub-mkrescue
grub_mkrescue_SOURCES = util/grub-mkrescue.in
# For grub-mkrescue.
grub_mkrescue_SOURCES = util/i386/pc/grub-mkrescue.in
bin_SCRIPTS += grub-mkfloppy
grub_mkfloppy_SOURCES = util/i386/pc/grub-mkfloppy.in
pkglib_MODULES = biosdisk.mod chain.mod \
multiboot.mod reboot.mod halt.mod \
vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \
ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
pkglib_MODULES = biosdisk.mod chain.mod \
multiboot.mod reboot.mod halt.mod \
vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \
vga.mod memdisk.mod pci.mod lspci.mod \
aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
efiemu.mod mmap.mod acpi.mod drivemap.mod
@ -294,11 +294,6 @@ play_mod_SOURCES = commands/i386/pc/play.c
play_mod_CFLAGS = $(COMMON_CFLAGS)
play_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ata.mod.
ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For vga.mod.
vga_mod_SOURCES = term/i386/pc/vga.c
vga_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -14,3 +14,8 @@ pkglib_MODULES += vga_text.mod
vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += ata.mod
ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -9,7 +9,7 @@ script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
# Utilities.
bin_UTILITIES = grub-mkimage
#sbin_UTILITIES = grub-mkdevicemap
sbin_UTILITIES = grub-mkdevicemap
#ifeq ($(enable_grub_emu), yes)
#sbin_UTILITIES += grub-emu
#endif
@ -27,7 +27,8 @@ grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \
# kern/fs.c kern/env.c fs/fshelp.c
# For grub-mkdevicemap.
grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
util/devicemap.c util/misc.c
# For grub-emu.
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
@ -80,10 +81,10 @@ sbin_SCRIPTS = grub-install
grub_install_SOURCES = util/i386/efi/grub-install.in
# Modules.
pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
halt.mod reboot.mod linux.mod pci.mod lspci.mod \
datetime.mod date.mod datehook.mod loadbios.mod \
fixvideo.mod mmap.mod acpi.mod
fixvideo.mod mmap.mod acpi.mod ata.mod
# For kernel.mod.
kernel_mod_EXPORTS = no
@ -128,6 +129,11 @@ acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
acpi_mod_CFLAGS = $(COMMON_CFLAGS)
acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ata.mod
ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For mmap.mod.
mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
mmap/efi/mmap.c

111
config.guess vendored
View file

@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
timestamp='2009-08-19'
timestamp='2009-09-18'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -854,6 +854,20 @@ EOF
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
@ -876,6 +890,9 @@ EOF
frv:Linux:*:*)
echo frv-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux-gnu
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
@ -911,29 +928,12 @@ EOF
or32:Linux:*:*)
echo or32-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-gnu
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@ -942,8 +942,11 @@ EOF
*) echo hppa-unknown-linux-gnu ;;
esac
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
@ -966,58 +969,6 @@ EOF
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^LIBC/{
s: ::g
p
}'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
}
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@ -1247,6 +1198,16 @@ EOF
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
i386)
eval $set_cc_for_build
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
UNAME_PROCESSOR="x86_64"
fi
fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}

9
config.sub vendored
View file

@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
timestamp='2009-08-19'
timestamp='2009-10-07'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@ -287,6 +287,7 @@ case $basic_machine in
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
@ -300,7 +301,7 @@ case $basic_machine in
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
m6811 | m68hc11 | m6812 | m68hc12 | picochip)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
@ -371,7 +372,7 @@ case $basic_machine in
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
@ -1296,7 +1297,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)

View file

@ -31,8 +31,10 @@ dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target
dnl type.
AC_INIT([GRUB],[1.97~beta3],[bug-grub@gnu.org])
AC_PREREQ(2.59)
AC_INIT([GRUB],[1.97],[bug-grub@gnu.org])
AM_INIT_AUTOMAKE()
AM_GNU_GETTEXT()
AC_PREREQ(2.59d)
AC_CONFIG_SRCDIR([include/grub/dl.h])
AC_CONFIG_HEADER([config.h])
@ -98,7 +100,7 @@ case "$target_cpu" in
esac
case "$host_os" in
mingw32) host_os=cygwin ;;
mingw32*) host_os=cygwin ;;
esac
# This normalizes the names, and creates a new variable ("host_kernel")
@ -107,7 +109,7 @@ esac
case "$host_os" in
gnu*) host_kernel=hurd ;;
linux*) host_kernel=linux ;;
freebsd* | kfreebsd*-gnu) host_kernel=freebsd ;;
freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;;
cygwin) host_kernel=windows ;;
esac
@ -134,9 +136,9 @@ if test "x$YACC" = x; then
AC_MSG_ERROR([bison is not found])
fi
for file in /usr/src/unifont.bdf ; do
for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz ; do
if test -e $file ; then
AC_SUBST([UNIFONT_BDF], [$file])
AC_SUBST([FONT_SOURCE], [$file])
break
fi
done
@ -144,6 +146,7 @@ done
AC_PROG_INSTALL
AC_PROG_AWK
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
# These are not a "must".
AC_PATH_PROG(RUBY, ruby)
@ -180,6 +183,13 @@ fi
# Check for functions.
AC_CHECK_FUNCS(posix_memalign memalign asprintf)
# For grub-mkisofs
AC_HEADER_MAJOR
AC_HEADER_DIRENT
AC_CHECK_FUNCS(memmove sbrk strdup lstat getuid getgid)
AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h)
AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h)
#
# Check for target programs.
#
@ -251,6 +261,10 @@ if test "x$TARGET_CFLAGS" = x; then
else
TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
fi
# Some toolchains enable these features by default, but they need
# registers that aren't set up properly in GRUB.
TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-3dnow"
fi
# By default, GCC 4.4 generates .eh_frame sections containing unwind
@ -406,6 +420,9 @@ AC_SUBST(TARGET_ASFLAGS)
AC_SUBST(TARGET_CPPFLAGS)
AC_SUBST(TARGET_LDFLAGS)
# Check for libgcc symbols (must be performed before we add -nostdlib to LDFLAGS)
AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2)
# Set them to their new values for the tests below.
CC="$TARGET_CC"
if test "x$TARGET_APPLE_CC" = x1 ; then
@ -540,7 +557,7 @@ AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"],
AC_CHECK_HEADERS([usb.h], [],
[grub_emu_usb_excuse=["need libusb headers"]])
[fi]
if test x"enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
if test x"$enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
AC_MSG_ERROR([USB support for grub-emu was explicitly requested but can't be compiled])
fi
if test x"$grub_emu_usb_excuse" = x ; then

View file

@ -140,7 +140,7 @@ grub_ata_dumpinfo (struct grub_ata_device *dev, char *info)
if (! dev->atapi)
{
grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
grub_dprintf ("ata", "Sectors: %lld\n", dev->size);
grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size);
}
}
@ -569,7 +569,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
{
struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
grub_dprintf("ata", "grub_ata_readwrite (size=%u, rw=%d)\n", size, rw);
grub_dprintf("ata", "grub_ata_readwrite (size=%llu, rw=%d)\n", (unsigned long long) size, rw);
grub_ata_addressing_t addressing = dev->addr;
grub_size_t batch;
@ -596,7 +596,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
if (size - nsectors < batch)
batch = size - nsectors;
grub_dprintf("ata", "rw=%d, sector=%llu, batch=%u\n", rw, sector, batch);
grub_dprintf("ata", "rw=%d, sector=%llu, batch=%llu\n", rw, (unsigned long long) sector, (unsigned long long) batch);
/* Send read/write command. */
if (grub_ata_setaddress (dev, addressing, sector, batch))
@ -755,7 +755,7 @@ grub_atapi_read (struct grub_scsi *scsi,
{
struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data;
grub_dprintf("ata", "grub_atapi_read (size=%u)\n", size);
grub_dprintf("ata", "grub_atapi_read (size=%llu)\n", (unsigned long long) size);
if (grub_atapi_packet (dev, cmd, size))
return grub_errno;

View file

@ -23,7 +23,6 @@
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/machine/kernel.h>
#include <grub/scsi.h>
#include <grub/scsicmd.h>

View file

@ -15,13 +15,13 @@ set fallback=1
menuentry "GNU (aka GNU/Hurd)" {
set root=(hd0,1)
multiboot /boot/gnumach.gz root=device:hd0s1
module /hurd/ext2fs.static --readonly \
module /hurd/ext2fs.static ext2fs --readonly \
--multiboot-command-line='${kernel-command-line}' \
--host-priv-port='${host-port}' \
--device-master-port='${device-port}' \
--exec-server-task='${exec-task}' -T typed '${root}' \
'$(task-create)' '$(task-resume)'
module /lib/ld.so.1 /hurd/exec '$(exec-task=task-create)'
module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'
}
# For booting GNU/Linux
@ -34,26 +34,26 @@ menuentry "GNU/Linux" {
# For booting FreeBSD
menuentry "FreeBSD (or GNU/kFreeBSD), direct boot" {
set root=(hd0,1,a)
freebsd /boot/kernel/kernel
freebsd_loadenv /boot/device.hints
freebsd_module /boot/splash.bmp type=splash_image_data
set FreeBSD.vfs.root.mountfrom=ufs:ad0s1a
kfreebsd /boot/kernel/kernel
kfreebsd_loadenv /boot/device.hints
kfreebsd_module /boot/splash.bmp type=splash_image_data
set kFreeBSD.vfs.root.mountfrom=ufs:ad0s1a
}
menuentry "FreeBSD (or GNU/kFreeBSD), via /boot/loader" {
set root=(hd0,1,a)
freebsd /boot/loader
kfreebsd /boot/loader
}
# For booting NetBSD
menuentry "NetBSD" {
set root=(hd0,1,a)
netbsd /netbsd
knetbsd /netbsd
}
# For booting OpenBSD
menuentry "OpenBSD" {
set root=(hd0,1,a)
openbsd /bsd
kopenbsd /bsd
}
# For booting Microsoft Windows

View file

@ -1118,6 +1118,8 @@ you forget a command, you can run the command @command{help}
* cmp:: Compare two files
* configfile:: Load a configuration file
* crc:: Calculate CRC32 checksums
* date:: Display or set current date and time
* echo:: Display a line of text
* export:: Export an environment variable
* halt:: Shut down your computer
* help:: Show help messages
@ -1234,6 +1236,62 @@ Display the CRC32 checksum of @var{file}.
@end deffn
@node date
@subsection date
@deffn Command date [[year-]month-day] [hour:minute[:second]]
With no arguments, print the current date and time.
Otherwise, take the current date and time, change any elements specified as
arguments, and set the result as the new date and time. For example, `date
01-01' will set the current month and day to January 1, but leave the year,
hour, minute, and second unchanged.
@end deffn
@node echo
@subsection echo
@deffn Command echo [@option{-n}] [@option{-e}] string @dots{}
Display the requested text and, unless the @option{-n} option is used, a
trailing new line. If there is more than one string, they are separated by
spaces in the output. As usual in GRUB commands, variables may be
substituted using @samp{$@{var@}}.
The @option{-e} option enables interpretation of backslash escapes. The
following sequences are recognised:
@table @code
@item \\
backslash
@item \a
alert (BEL)
@item \c
suppress trailing new line
@item \f
form feed
@item \n
new line
@item \r
carriage return
@item \t
horizontal tab
@item \v
vertical tab
@end table
When interpreting backslash escapes, backslash followed by any other
character will print that character.
@end deffn
@node export
@subsection export

View file

@ -352,9 +352,9 @@ static struct grub_fs grub_cpio_fs = {
};
#ifdef MODE_USTAR
GRUB_MOD_INIT (cpio)
#else
GRUB_MOD_INIT (tar)
#else
GRUB_MOD_INIT (cpio)
#endif
{
grub_fs_register (&grub_cpio_fs);
@ -362,9 +362,9 @@ GRUB_MOD_INIT (tar)
}
#ifdef MODE_USTAR
GRUB_MOD_FINI (cpio)
#else
GRUB_MOD_FINI (tar)
#else
GRUB_MOD_FINI (cpio)
#endif
{
grub_fs_unregister (&grub_cpio_fs);

View file

@ -649,6 +649,9 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir,
if (grub_errno)
return 0;
if (dirent.direntlen == 0)
return 0;
if (dirent.namelen != 0)
{
char filename[dirent.namelen + 1];
@ -924,6 +927,9 @@ static struct grub_fs grub_ext2_fs =
.label = grub_ext2_label,
.uuid = grub_ext2_uuid,
.mtime = grub_ext2_mtime,
#ifdef GRUB_UTIL
.reserved_first_sector = 1,
#endif
.next = 0
};

View file

@ -855,6 +855,9 @@ static struct grub_fs grub_fat_fs =
.close = grub_fat_close,
.label = grub_fat_label,
.uuid = grub_fat_uuid,
#ifdef GRUB_UTIL
.reserved_first_sector = 1,
#endif
.next = 0
};

View file

@ -1021,6 +1021,9 @@ static struct grub_fs grub_hfsplus_fs =
.label = grub_hfsplus_label,
.mtime = grub_hfsplus_mtime,
.uuid = grub_hfsplus_uuid,
#ifdef GRUB_UTIL
.reserved_first_sector = 1,
#endif
.next = 0
};

View file

@ -150,7 +150,7 @@ grub_pxefs_open (struct grub_file *file, const char *name)
if (! data)
return grub_errno;
data->block_size = grub_pxe_blksize;
data->block_size = c.c2.packet_size;
grub_strcpy (data->filename, name);
file_int = grub_malloc (sizeof (*file_int));
@ -205,13 +205,14 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
o.gateway_ip = grub_pxe_gateway_ip;
grub_strcpy ((char *)&o.filename[0], data->filename);
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
o.packet_size = data->block_size;
o.packet_size = grub_pxe_blksize;
grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
if (o.status)
{
grub_error (GRUB_ERR_BAD_FS, "open fails");
return -1;
}
data->block_size = o.packet_size;
data->packet_number = 0;
curr_file = file;
}
@ -219,7 +220,7 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
while (pn >= data->packet_number)
{
c.buffer_size = grub_pxe_blksize;
c.buffer_size = data->block_size;
grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
if (c.status)
{

View file

@ -1081,15 +1081,19 @@ grub_ntfs_uuid (grub_device_t device, char **uuid)
return grub_errno;
}
static struct grub_fs grub_ntfs_fs = {
.name = "ntfs",
.dir = grub_ntfs_dir,
.open = grub_ntfs_open,
.read = grub_ntfs_read,
.close = grub_ntfs_close,
.label = grub_ntfs_label,
.uuid = grub_ntfs_uuid,
.next = 0
static struct grub_fs grub_ntfs_fs =
{
.name = "ntfs",
.dir = grub_ntfs_dir,
.open = grub_ntfs_open,
.read = grub_ntfs_read,
.close = grub_ntfs_close,
.label = grub_ntfs_label,
.uuid = grub_ntfs_uuid,
#ifdef GRUB_UTIL
.reserved_first_sector = 1,
#endif
.next = 0
};
GRUB_MOD_INIT (ntfs)

View file

@ -35,7 +35,7 @@ dir=`dirname $0`
cd $dir
for dir in $DISTDIRS; do
for d in `find $dir -type d | sed '/\/\.svn$/d;\/\.svn\//d' | sort`; do
for d in `find $dir -type d -not -name .svn -not -name .bzr | sort`; do
find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \
-o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \
-o -name '*.info' -o -name 'grub.cfg' -o -name 'README' \

56
gnulib/alloca.h Normal file
View file

@ -0,0 +1,56 @@
/* Memory allocation on the stack.
Copyright (C) 1995, 1999, 2001-2004, 2006-2008 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
means there is a real alloca function. */
#ifndef _GL_ALLOCA_H
#define _GL_ALLOCA_H
/* alloca (N) returns a pointer to N bytes of memory
allocated on the stack, which will last until the function returns.
Use of alloca should be avoided:
- inside arguments of function calls - undefined behaviour,
- in inline functions - the allocation may actually last until the
calling function returns,
- for huge N (say, N >= 65536) - you never know how large (or small)
the stack is, and when the stack cannot fulfill the memory allocation
request, the program just crashes.
*/
#ifndef alloca
# ifdef __GNUC__
# define alloca __builtin_alloca
# elif defined _AIX
# define alloca __alloca
# elif defined _MSC_VER
# include <malloc.h>
# define alloca _alloca
# elif defined __DECC && defined __VMS
# define alloca __ALLOCA
# else
# include <stddef.h>
# ifdef __cplusplus
extern "C"
# endif
void *alloca (size_t);
# endif
#endif
#endif /* _GL_ALLOCA_H */

352
gnulib/error.c Normal file
View file

@ -0,0 +1,352 @@
/* Error handler for noninteractive utilities
Copyright (C) 1990-1998, 2000-2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
#if !_LIBC
# include <config.h>
#endif
#include "error.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !_LIBC && ENABLE_NLS
# include "gettext.h"
# define _(msgid) gettext (msgid)
#endif
#ifdef _LIBC
# include <libintl.h>
# include <stdbool.h>
# include <stdint.h>
# include <wchar.h>
# define mbsrtowcs __mbsrtowcs
#endif
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif
#ifndef _
# define _(String) String
#endif
/* If NULL, error will flush stdout, then print on stderr the program
name, a colon and a space. Otherwise, error will call this
function without parameters instead. */
void (*error_print_progname) (void);
/* This variable is incremented each time `error' is called. */
unsigned int error_message_count;
#ifdef _LIBC
/* In the GNU C library, there is a predefined variable for this. */
# define program_name program_invocation_name
# include <errno.h>
# include <limits.h>
# include <libio/libioP.h>
/* In GNU libc we want do not want to use the common name `error' directly.
Instead make it a weak alias. */
extern void __error (int status, int errnum, const char *message, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
extern void __error_at_line (int status, int errnum, const char *file_name,
unsigned int line_number, const char *message,
...)
__attribute__ ((__format__ (__printf__, 5, 6)));;
# define error __error
# define error_at_line __error_at_line
# include <libio/iolibio.h>
# define fflush(s) INTUSE(_IO_fflush) (s)
# undef putc
# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
# include <bits/libc-lock.h>
#else /* not _LIBC */
# include <fcntl.h>
# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
# ifndef HAVE_DECL_STRERROR_R
"this configure-time declaration test was not run"
# endif
char *strerror_r ();
# endif
/* The calling program should define program_name and set it to the
name of the executing program. */
extern char *program_name;
# if HAVE_STRERROR_R || defined strerror_r
# define __strerror_r strerror_r
# endif /* HAVE_STRERROR_R || defined strerror_r */
#endif /* not _LIBC */
static void
print_errno_message (int errnum)
{
char const *s;
#if defined HAVE_STRERROR_R || _LIBC
char errbuf[1024];
# if STRERROR_R_CHAR_P || _LIBC
s = __strerror_r (errnum, errbuf, sizeof errbuf);
# else
if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
s = errbuf;
else
s = 0;
# endif
#else
s = strerror (errnum);
#endif
#if !_LIBC
if (! s)
s = _("Unknown system error");
#endif
#if _LIBC
__fxprintf (NULL, ": %s", s);
#else
fprintf (stderr, ": %s", s);
#endif
}
static void
error_tail (int status, int errnum, const char *message, va_list args)
{
#if _LIBC
if (_IO_fwide (stderr, 0) > 0)
{
# define ALLOCA_LIMIT 2000
size_t len = strlen (message) + 1;
wchar_t *wmessage = NULL;
mbstate_t st;
size_t res;
const char *tmp;
bool use_malloc = false;
while (1)
{
if (__libc_use_alloca (len * sizeof (wchar_t)))
wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
else
{
if (!use_malloc)
wmessage = NULL;
wchar_t *p = (wchar_t *) realloc (wmessage,
len * sizeof (wchar_t));
if (p == NULL)
{
free (wmessage);
fputws_unlocked (L"out of memory\n", stderr);
return;
}
wmessage = p;
use_malloc = true;
}
memset (&st, '\0', sizeof (st));
tmp = message;
res = mbsrtowcs (wmessage, &tmp, len, &st);
if (res != len)
break;
if (__builtin_expect (len >= SIZE_MAX / 2, 0))
{
/* This really should not happen if everything is fine. */
res = (size_t) -1;
break;
}
len *= 2;
}
if (res == (size_t) -1)
{
/* The string cannot be converted. */
if (use_malloc)
{
free (wmessage);
use_malloc = false;
}
wmessage = (wchar_t *) L"???";
}
__vfwprintf (stderr, wmessage, args);
if (use_malloc)
free (wmessage);
}
else
#endif
vfprintf (stderr, message, args);
va_end (args);
++error_message_count;
if (errnum)
print_errno_message (errnum);
#if _LIBC
__fxprintf (NULL, "\n");
#else
putc ('\n', stderr);
#endif
fflush (stderr);
if (status)
exit (status);
}
/* Print the program name and error message MESSAGE, which is a printf-style
format string with optional args.
If ERRNUM is nonzero, print its corresponding system error message.
Exit with status STATUS if it is nonzero. */
void
error (int status, int errnum, const char *message, ...)
{
va_list args;
#if defined _LIBC && defined __libc_ptf_call
/* We do not want this call to be cut short by a thread
cancellation. Therefore disable cancellation for now. */
int state = PTHREAD_CANCEL_ENABLE;
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
0);
#endif
#if !_LIBC && defined F_GETFL
/* POSIX states that fflush (stdout) after fclose is unspecified; it
is safe in glibc, but not on all other platforms. fflush (NULL)
is always defined, but too draconian. */
if (0 <= fcntl (1, F_GETFL))
#endif
fflush (stdout);
#ifdef _LIBC
_IO_flockfile (stderr);
#endif
if (error_print_progname)
(*error_print_progname) ();
else
{
#if _LIBC
__fxprintf (NULL, "%s: ", program_name);
#else
fprintf (stderr, "%s: ", program_name);
#endif
}
va_start (args, message);
error_tail (status, errnum, message, args);
#ifdef _LIBC
_IO_funlockfile (stderr);
# ifdef __libc_ptf_call
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
# endif
#endif
}
/* Sometimes we want to have at most one error per line. This
variable controls whether this mode is selected or not. */
int error_one_per_line;
void
error_at_line (int status, int errnum, const char *file_name,
unsigned int line_number, const char *message, ...)
{
va_list args;
if (error_one_per_line)
{
static const char *old_file_name;
static unsigned int old_line_number;
if (old_line_number == line_number
&& (file_name == old_file_name
|| strcmp (old_file_name, file_name) == 0))
/* Simply return and print nothing. */
return;
old_file_name = file_name;
old_line_number = line_number;
}
#if defined _LIBC && defined __libc_ptf_call
/* We do not want this call to be cut short by a thread
cancellation. Therefore disable cancellation for now. */
int state = PTHREAD_CANCEL_ENABLE;
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
0);
#endif
#if !_LIBC && defined F_GETFL
/* POSIX states that fflush (stdout) after fclose is unspecified; it
is safe in glibc, but not on all other platforms. fflush (NULL)
is always defined, but too draconian. */
if (0 <= fcntl (1, F_GETFL))
#endif
fflush (stdout);
#ifdef _LIBC
_IO_flockfile (stderr);
#endif
if (error_print_progname)
(*error_print_progname) ();
else
{
#if _LIBC
__fxprintf (NULL, "%s:", program_name);
#else
fprintf (stderr, "%s:", program_name);
#endif
}
#if _LIBC
__fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
file_name, line_number);
#else
fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
file_name, line_number);
#endif
va_start (args, message);
error_tail (status, errnum, message, args);
#ifdef _LIBC
_IO_funlockfile (stderr);
# ifdef __libc_ptf_call
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
# endif
#endif
}
#ifdef _LIBC
/* Make the weak alias. */
# undef error
# undef error_at_line
weak_alias (__error, error)
weak_alias (__error_at_line, error_at_line)
#endif

65
gnulib/error.h Normal file
View file

@ -0,0 +1,65 @@
/* Declaration for error-reporting function
Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _ERROR_H
#define _ERROR_H 1
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
# define __attribute__(Spec) /* empty */
# endif
/* The __-protected variants of `format' and `printf' attributes
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __format__ format
# define __printf__ printf
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Print a message with `fprintf (stderr, FORMAT, ...)';
if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
extern void error (int __status, int __errnum, const char *__format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
extern void error_at_line (int __status, int __errnum, const char *__fname,
unsigned int __lineno, const char *__format, ...)
__attribute__ ((__format__ (__printf__, 5, 6)));
/* If NULL, error will flush stdout, then print on stderr the program
name, a colon and a space. Otherwise, error will call this
function without parameters instead. */
extern void (*error_print_progname) (void);
/* This variable is incremented each time `error' is called. */
extern unsigned int error_message_count;
/* Sometimes we want to have at most one error per line. This
variable controls whether this mode is selected or not. */
extern int error_one_per_line;
#ifdef __cplusplus
}
#endif
#endif /* error.h */

354
gnulib/fnmatch.c Normal file
View file

@ -0,0 +1,354 @@
/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _LIBC
# include <config.h>
#endif
/* Enable GNU extensions in fnmatch.h. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#if ! defined __builtin_expect && __GNUC__ < 3
# define __builtin_expect(expr, expected) (expr)
#endif
#include <fnmatch.h>
#include <alloca.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define WIDE_CHAR_SUPPORT \
(HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \
&& HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY))
/* For platform which support the ISO C amendement 1 functionality we
support user defined character classes. */
#if defined _LIBC || WIDE_CHAR_SUPPORT
# include <wctype.h>
# include <wchar.h>
#endif
/* We need some of the locale data (the collation sequence information)
but there is no interface to get this information in general. Therefore
we support a correct implementation only in glibc. */
#ifdef _LIBC
# include "../locale/localeinfo.h"
# include "../locale/elem-hash.h"
# include "../locale/coll-lookup.h"
# include <shlib-compat.h>
# define CONCAT(a,b) __CONCAT(a,b)
# define mbsrtowcs __mbsrtowcs
# define fnmatch __fnmatch
extern int fnmatch (const char *pattern, const char *string, int flags);
#endif
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
#define NO_LEADING_PERIOD(flags) \
((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself, and have not detected a bug
in the library. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU
# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
# define isblank(c) ((c) == ' ' || (c) == '\t')
# endif
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
# if defined _LIBC || WIDE_CHAR_SUPPORT
/* The GNU C library provides support for user-defined character classes
and the functions from ISO C amendement 1. */
# ifdef CHARCLASS_NAME_MAX
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
# else
/* This shouldn't happen but some implementation might still have this
problem. Use a reasonable default value. */
# define CHAR_CLASS_MAX_LENGTH 256
# endif
# ifdef _LIBC
# define IS_CHAR_CLASS(string) __wctype (string)
# else
# define IS_CHAR_CLASS(string) wctype (string)
# endif
# ifdef _LIBC
# define ISWCTYPE(WC, WT) __iswctype (WC, WT)
# else
# define ISWCTYPE(WC, WT) iswctype (WC, WT)
# endif
# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
/* In this case we are implementing the multibyte character handling. */
# define HANDLE_MULTIBYTE 1
# endif
# else
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
# define IS_CHAR_CLASS(string) \
(STREQ (string, "alpha") || STREQ (string, "upper") \
|| STREQ (string, "lower") || STREQ (string, "digit") \
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|| STREQ (string, "space") || STREQ (string, "print") \
|| STREQ (string, "punct") || STREQ (string, "graph") \
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
# endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
/* Global variable. */
static int posixly_correct;
# ifndef internal_function
/* Inside GNU libc we mark some function in a special way. In other
environments simply ignore the marking. */
# define internal_function
# endif
/* Note that this evaluates C many times. */
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
# define CHAR char
# define UCHAR unsigned char
# define INT int
# define FCT internal_fnmatch
# define EXT ext_match
# define END end_pattern
# define L_(CS) CS
# ifdef _LIBC
# define BTOWC(C) __btowc (C)
# else
# define BTOWC(C) btowc (C)
# endif
# define STRLEN(S) strlen (S)
# define STRCAT(D, S) strcat (D, S)
# ifdef _LIBC
# define MEMPCPY(D, S, N) __mempcpy (D, S, N)
# else
# if HAVE_MEMPCPY
# define MEMPCPY(D, S, N) mempcpy (D, S, N)
# else
# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
# endif
# endif
# define MEMCHR(S, C, N) memchr (S, C, N)
# define STRCOLL(S1, S2) strcoll (S1, S2)
# include "fnmatch_loop.c"
# if HANDLE_MULTIBYTE
# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
# define CHAR wchar_t
# define UCHAR wint_t
# define INT wint_t
# define FCT internal_fnwmatch
# define EXT ext_wmatch
# define END end_wpattern
# define L_(CS) L##CS
# define BTOWC(C) (C)
# ifdef _LIBC
# define STRLEN(S) __wcslen (S)
# define STRCAT(D, S) __wcscat (D, S)
# define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
# else
# define STRLEN(S) wcslen (S)
# define STRCAT(D, S) wcscat (D, S)
# if HAVE_WMEMPCPY
# define MEMPCPY(D, S, N) wmempcpy (D, S, N)
# else
# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N))
# endif
# endif
# define MEMCHR(S, C, N) wmemchr (S, C, N)
# define STRCOLL(S1, S2) wcscoll (S1, S2)
# define WIDE_CHAR_VERSION 1
# undef IS_CHAR_CLASS
/* We have to convert the wide character string in a multibyte string. But
we know that the character class names consist of alphanumeric characters
from the portable character set, and since the wide character encoding
for a member of the portable character set is the same code point as
its single-byte encoding, we can use a simplified method to convert the
string to a multibyte character string. */
static wctype_t
is_char_class (const wchar_t *wcs)
{
char s[CHAR_CLASS_MAX_LENGTH + 1];
char *cp = s;
do
{
/* Test for a printable character from the portable character set. */
# ifdef _LIBC
if (*wcs < 0x20 || *wcs > 0x7e
|| *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
return (wctype_t) 0;
# else
switch (*wcs)
{
case L' ': case L'!': case L'"': case L'#': case L'%':
case L'&': case L'\'': case L'(': case L')': case L'*':
case L'+': case L',': case L'-': case L'.': case L'/':
case L'0': case L'1': case L'2': case L'3': case L'4':
case L'5': case L'6': case L'7': case L'8': case L'9':
case L':': case L';': case L'<': case L'=': case L'>':
case L'?':
case L'A': case L'B': case L'C': case L'D': case L'E':
case L'F': case L'G': case L'H': case L'I': case L'J':
case L'K': case L'L': case L'M': case L'N': case L'O':
case L'P': case L'Q': case L'R': case L'S': case L'T':
case L'U': case L'V': case L'W': case L'X': case L'Y':
case L'Z':
case L'[': case L'\\': case L']': case L'^': case L'_':
case L'a': case L'b': case L'c': case L'd': case L'e':
case L'f': case L'g': case L'h': case L'i': case L'j':
case L'k': case L'l': case L'm': case L'n': case L'o':
case L'p': case L'q': case L'r': case L's': case L't':
case L'u': case L'v': case L'w': case L'x': case L'y':
case L'z': case L'{': case L'|': case L'}': case L'~':
break;
default:
return (wctype_t) 0;
}
# endif
/* Avoid overrunning the buffer. */
if (cp == s + CHAR_CLASS_MAX_LENGTH)
return (wctype_t) 0;
*cp++ = (char) *wcs++;
}
while (*wcs != L'\0');
*cp = '\0';
# ifdef _LIBC
return __wctype (s);
# else
return wctype (s);
# endif
}
# define IS_CHAR_CLASS(string) is_char_class (string)
# include "fnmatch_loop.c"
# endif
int
fnmatch (const char *pattern, const char *string, int flags)
{
# if HANDLE_MULTIBYTE
# define ALLOCA_LIMIT 2000
if (__builtin_expect (MB_CUR_MAX, 1) != 1)
{
mbstate_t ps;
size_t patsize;
size_t strsize;
size_t totsize;
wchar_t *wpattern;
wchar_t *wstring;
int res;
/* Calculate the size needed to convert the strings to
wide characters. */
memset (&ps, '\0', sizeof (ps));
patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1;
if (__builtin_expect (patsize != 0, 1))
{
assert (mbsinit (&ps));
strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1;
if (__builtin_expect (strsize != 0, 1))
{
assert (mbsinit (&ps));
totsize = patsize + strsize;
if (__builtin_expect (! (patsize <= totsize
&& totsize <= SIZE_MAX / sizeof (wchar_t)),
0))
{
errno = ENOMEM;
return -1;
}
/* Allocate room for the wide characters. */
if (__builtin_expect (totsize < ALLOCA_LIMIT, 1))
wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t));
else
{
wpattern = malloc (totsize * sizeof (wchar_t));
if (__builtin_expect (! wpattern, 0))
{
errno = ENOMEM;
return -1;
}
}
wstring = wpattern + patsize;
/* Convert the strings into wide characters. */
mbsrtowcs (wpattern, &pattern, patsize, &ps);
assert (mbsinit (&ps));
mbsrtowcs (wstring, &string, strsize, &ps);
res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1,
flags & FNM_PERIOD, flags);
if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0))
free (wpattern);
return res;
}
}
}
# endif /* HANDLE_MULTIBYTE */
return internal_fnmatch (pattern, string, string + strlen (string),
flags & FNM_PERIOD, flags);
}
# ifdef _LIBC
# undef fnmatch
versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
strong_alias (__fnmatch, __fnmatch_old)
compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
# endif
libc_hidden_ver (__fnmatch, fnmatch)
# endif
#endif /* _LIBC or not __GNU_LIBRARY__. */

65
gnulib/fnmatch.h Normal file
View file

@ -0,0 +1,65 @@
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _FNMATCH_H
#define _FNMATCH_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* We #undef these before defining them because some losing systems
(HP-UX A.08.07 for example) define these in <unistd.h>. */
#undef FNM_PATHNAME
#undef FNM_NOESCAPE
#undef FNM_PERIOD
/* Bits set in the FLAGS argument to `fnmatch'. */
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
#endif
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
#define FNM_NOMATCH 1
/* This value is returned if the implementation does not support
`fnmatch'. Since this is not the case here it will never be
returned but the conformance test suites still require the symbol
to be defined. */
#ifdef _XOPEN_SOURCE
# define FNM_NOSYS (-1)
#endif
/* Match NAME against the file name pattern PATTERN,
returning zero if it matches, FNM_NOMATCH if not. */
extern int fnmatch (const char *__pattern, const char *__name,
int __flags);
#ifdef __cplusplus
}
#endif
#endif /* fnmatch.h */

1211
gnulib/fnmatch_loop.c Normal file

File diff suppressed because it is too large Load diff

1186
gnulib/getopt.c Normal file

File diff suppressed because it is too large Load diff

225
gnulib/getopt.h Normal file
View file

@ -0,0 +1,225 @@
/* Declarations for getopt.
Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _GETOPT_H
#ifndef __need_getopt
# define _GETOPT_H 1
#endif
/* Standalone applications should #define __GETOPT_PREFIX to an
identifier that prefixes the external functions and variables
defined in this header. When this happens, include the
headers that might declare getopt so that they will not cause
confusion if included after this file. Then systematically rename
identifiers so that they do not collide with the system functions
and variables. Renaming avoids problems with some compilers and
linkers. */
#if defined __GETOPT_PREFIX && !defined __need_getopt
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>
# undef __need_getopt
# undef getopt
# undef getopt_long
# undef getopt_long_only
# undef optarg
# undef opterr
# undef optind
# undef optopt
# define __GETOPT_CONCAT(x, y) x ## y
# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
# define getopt __GETOPT_ID (getopt)
# define getopt_long __GETOPT_ID (getopt_long)
# define getopt_long_only __GETOPT_ID (getopt_long_only)
# define optarg __GETOPT_ID (optarg)
# define opterr __GETOPT_ID (opterr)
# define optind __GETOPT_ID (optind)
# define optopt __GETOPT_ID (optopt)
#endif
/* Standalone applications get correct prototypes for getopt_long and
getopt_long_only; they declare "char **argv". libc uses prototypes
with "char *const *argv" that are incorrect because getopt_long and
getopt_long_only can permute argv; this is required for backward
compatibility (e.g., for LSB 2.0.1).
This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
but it caused redefinition warnings if both unistd.h and getopt.h were
included, since unistd.h includes getopt.h having previously defined
__need_getopt.
The only place where __getopt_argv_const is used is in definitions
of getopt_long and getopt_long_only below, but these are visible
only if __need_getopt is not defined, so it is quite safe to rewrite
the conditional as follows:
*/
#if !defined __need_getopt
# if defined __GETOPT_PREFIX
# define __getopt_argv_const /* empty */
# else
# define __getopt_argv_const const
# endif
#endif
/* If __GNU_LIBRARY__ is not already defined, either we are being used
standalone, or this is the first header included in the source file.
If we are being used with glibc, we need to include <features.h>, but
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
not defined, include <ctype.h>, which will pull in <features.h> for us
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
doesn't flood the namespace with stuff the way some other headers do.) */
#if !defined __GNU_LIBRARY__
# include <ctype.h>
#endif
#ifndef __THROW
# ifndef __GNUC_PREREQ
# define __GNUC_PREREQ(maj, min) (0)
# endif
# if defined __cplusplus && __GNUC_PREREQ (2,8)
# define __THROW throw ()
# else
# define __THROW
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
const char *name;
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#endif /* need getopt */
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `optopt' is set to the option letter, and '?' is
returned.
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `optarg'.
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `getopt'.
The argument `--' causes premature termination of argument
scanning, explicitly telling `getopt' that there are no more
options.
If OPTS begins with `-', then non-option arguments are treated as
arguments to the option '\1'. This behavior is specific to the GNU
`getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in
the environment, then do not permute arguments. */
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
__THROW;
#ifndef __need_getopt
extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind)
__THROW;
extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind)
__THROW;
#endif
#ifdef __cplusplus
}
#endif
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
#endif /* getopt.h */

170
gnulib/getopt1.c Normal file
View file

@ -0,0 +1,170 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef _LIBC
# include <getopt.h>
#else
# include <config.h>
# include "getopt.h"
#endif
#include "getopt_int.h"
#include <stdio.h>
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, (char **) argv, options, long_options,
opt_index, 0, 0);
}
int
_getopt_long_r (int argc, char **argv, const char *options,
const struct option *long_options, int *opt_index,
struct _getopt_data *d)
{
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
0, 0, d);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (int argc, char *__getopt_argv_const *argv,
const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, (char **) argv, options, long_options,
opt_index, 1, 0);
}
int
_getopt_long_only_r (int argc, char **argv, const char *options,
const struct option *long_options, int *opt_index,
struct _getopt_data *d)
{
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
1, 0, d);
}
#ifdef TEST
#include <stdio.h>
int
main (int argc, char **argv)
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

130
gnulib/getopt_int.h Normal file
View file

@ -0,0 +1,130 @@
/* Internal declarations for getopt.
Copyright (C) 1989-1994,1996-1999,2001,2003,2004
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _GETOPT_INT_H
#define _GETOPT_INT_H 1
extern int _getopt_internal (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only, int __posixly_correct);
/* Reentrant versions which can handle parsing multiple argument
vectors at the same time. */
/* Data type for reentrant functions. */
struct _getopt_data
{
/* These have exactly the same meaning as the corresponding global
variables, except that they are used for the reentrant
versions of getopt. */
int optind;
int opterr;
int optopt;
char *optarg;
/* Internal members. */
/* True if the internal members have been initialized. */
int __initialized;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
char *__nextchar;
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters, or by calling getopt.
PERMUTE is the default. We permute the contents of ARGV as we
scan, so that eventually all the non-options are at the end.
This allows options to be given in any order, even with programs
that were not written to expect this.
RETURN_IN_ORDER is an option available to programs that were
written to expect options and other ARGV-elements in any order
and that care about the ordering of the two. We describe each
non-option ARGV-element as if it were the argument of an option
with character code 1. Using `-' as the first character of the
list of option characters selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} __ordering;
/* If the POSIXLY_CORRECT environment variable is set
or getopt was called. */
int __posixly_correct;
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first
of them; `last_nonopt' is the index after the last of them. */
int __first_nonopt;
int __last_nonopt;
#if defined _LIBC && defined USE_NONOPTION_FLAGS
int __nonoption_flags_max_len;
int __nonoption_flags_len;
# endif
};
/* The initializer is necessary to set OPTIND and OPTERR to their
default values and to clear the initialization flag. */
#define _GETOPT_DATA_INITIALIZER { 1, 1 }
extern int _getopt_internal_r (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only, int __posixly_correct,
struct _getopt_data *__data);
extern int _getopt_long_r (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
struct _getopt_data *__data);
extern int _getopt_long_only_r (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts,
int *__longind,
struct _getopt_data *__data);
#endif /* getopt_int.h */

270
gnulib/gettext.h Normal file
View file

@ -0,0 +1,270 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */
#if ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
the gettext() and ngettext() macros. This is an alternative to calling
textdomain(), and is useful for libraries. */
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
chokes if dcgettext is defined as a macro. So include it now, to make
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#endif
/* Disabled NLS.
The casts to 'const char *' serve the purpose of producing warnings
for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# define gettext(Msgid) ((const char *) (Msgid))
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \
? ((void) (Msgid2), (const char *) (Msgid1)) \
: ((void) (Msgid1), (const char *) (Msgid2)))
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) \
((void) (Domainname), (const char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) \
((void) (Domainname), (const char *) (Codeset))
#endif
/* A pseudo function call that serves as a marker for the automated
extraction of messages, but does not call gettext(). The run-time
translation is done at a different place in the code.
The argument, String, should be a literal string. Concatenated strings
and other string expressions won't work.
The macro's expansion is not parenthesized, so that it is suitable as
initializer for static 'char[]' or 'const char[]' variables. */
#define gettext_noop(String) String
/* The separator between msgctxt and msgid in a .mo file. */
#define GETTEXT_CONTEXT_GLUE "\004"
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
short and rarely need to change.
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
return translation;
}
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
else
return translation;
}
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
can be arbitrary expressions. But for string literals these macros are
less efficient than those above. */
#include <string.h>
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
}
return msgid;
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

78
gnulib/progname.c Normal file
View file

@ -0,0 +1,78 @@
/* Program name management.
Copyright (C) 2001-2003, 2005-2009 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
/* Specification. */
#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
#include "progname.h"
#include <errno.h> /* get program_invocation_name declaration */
#include <string.h>
/* String containing name the program is called with.
To be initialized by main(). */
const char *program_name = NULL;
/* Set program_name, based on argv[0]. */
void
set_program_name (const char *argv0)
{
/* libtool creates a temporary executable whose name is sometimes prefixed
with "lt-" (depends on the platform). It also makes argv[0] absolute.
But the name of the temporary executable is a detail that should not be
visible to the end user and to the test suite.
Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here. */
const char *slash;
const char *base;
slash = strrchr (argv0, '/');
base = (slash != NULL ? slash + 1 : argv0);
if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
{
argv0 = base;
if (strncmp (base, "lt-", 3) == 0)
{
argv0 = base + 3;
/* On glibc systems, remove the "lt-" prefix from the variable
program_invocation_short_name. */
#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
program_invocation_short_name = (char *) argv0;
#endif
}
}
/* But don't strip off a leading <dirname>/ in general, because when the user
runs
/some/hidden/place/bin/cp foo foo
he should get the error message
/some/hidden/place/bin/cp: `foo' and `foo' are the same file
not
cp: `foo' and `foo' are the same file
*/
program_name = argv0;
/* On glibc systems, the error() function comes from libc and uses the
variable program_invocation_name, not program_name. So set this variable
as well. */
#if HAVE_DECL_PROGRAM_INVOCATION_NAME
program_invocation_name = (char *) argv0;
#endif
}

60
gnulib/progname.h Normal file
View file

@ -0,0 +1,60 @@
/* Program name management.
Copyright (C) 2001-2004, 2006 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _PROGNAME_H
#define _PROGNAME_H
/* Programs using this file should do the following in main():
set_program_name (argv[0]);
*/
#ifdef __cplusplus
extern "C" {
#endif
/* String containing name the program is called with. */
extern const char *program_name;
/* Set program_name, based on argv[0]. */
extern void set_program_name (const char *argv0);
#if ENABLE_RELOCATABLE
/* Set program_name, based on argv[0], and original installation prefix and
directory, for relocatability. */
extern void set_program_name_and_installdir (const char *argv0,
const char *orig_installprefix,
const char *orig_installdir);
#undef set_program_name
#define set_program_name(ARG0) \
set_program_name_and_installdir (ARG0, INSTALLPREFIX, INSTALLDIR)
/* Return the full pathname of the current executable, based on the earlier
call to set_program_name_and_installdir. Return NULL if unknown. */
extern char *get_full_program_name (void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _PROGNAME_H */

View file

@ -68,6 +68,11 @@ struct grub_fs
/* Get writing time of filesystem. */
grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf);
#ifdef GRUB_UTIL
/* Whether this filesystem reserves first sector for DOS-style boot. */
int reserved_first_sector;
#endif
/* The next filesystem. */
struct grub_fs *next;
};

30
include/grub/i18n.h Normal file
View file

@ -0,0 +1,30 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_I18N_H
#define GRUB_I18N_H 1
#ifdef GRUB_UTIL
# include <locale.h>
# include <libintl.h>
# define _(str) gettext(str)
#else
# define _(str) str
#endif
#endif /* GRUB_I18N_H */

View file

@ -39,7 +39,7 @@
#define KEYBOARD_SCANCODE_SET1 0x40
#define KEYBOARD_ISMAKE(x) !((x) & 0x80)
#define KEYBOARD_ISREADY(x) (((x) & 0x01) == 0)
#define KEYBOARD_ISREADY(x) ((x) & 0x01)
#define KEYBOARD_SCANCODE(x) ((x) & 0x7f)
#ifdef GRUB_MACHINE_IEEE1275

View file

@ -0,0 +1 @@
#include <grub/i386/pc/boot.h>

View file

@ -0,0 +1,28 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_INIT_I386_LINUXBIOS_HEADER
#define GRUB_INIT_I386_LINUXBIOS_HEADER 1
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_stop_floppy) (void);
#endif

View file

@ -0,0 +1 @@
#include <grub/cpu/loader.h>

View file

@ -0,0 +1 @@
#include <grub/i386/pc/serial.h>

View file

@ -0,0 +1 @@
#include <grub/i386/pc/time.h>

24
include/grub/i386/cpuid.h Normal file
View file

@ -0,0 +1,24 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_CPU_CPUID_HEADER
#define GRUB_CPU_CPUID_HEADER 1
extern unsigned char grub_cpuid_has_longmode;
#endif

View file

@ -21,10 +21,10 @@
/* The asm part of the multiboot loader. */
void grub_multiboot_real_boot (grub_addr_t entry,
struct grub_multiboot_info *mbi)
struct multiboot_info *mbi)
__attribute__ ((noreturn));
void grub_multiboot2_real_boot (grub_addr_t entry,
struct grub_multiboot_info *mbi)
struct multiboot_info *mbi)
__attribute__ ((noreturn));
extern grub_addr_t grub_multiboot_payload_orig;

View file

@ -22,20 +22,20 @@
#include <grub/types.h>
#include <grub/symbol.h>
enum
{
OBJ_TYPE_ELF,
OBJ_TYPE_MEMDISK,
OBJ_TYPE_CONFIG
};
/* The module header. */
struct grub_module_header
{
/* The type of object. */
grub_int8_t type;
enum
{
OBJ_TYPE_ELF,
OBJ_TYPE_MEMDISK,
OBJ_TYPE_CONFIG
} grub_module_header_types;
grub_uint8_t type;
/* The size of object (including this header). */
grub_target_size_t size;
grub_uint32_t size;
};
/* "gmim" (GRUB Module Info Magic). */

View file

@ -68,7 +68,7 @@ extern void* grub_assert_fail (void);
struct grub_named_list
{
struct grub_named_list *next;
const char *name;
char *name;
};
typedef struct grub_named_list *grub_named_list_t;
@ -91,7 +91,7 @@ void * EXPORT_FUNC(grub_named_list_find) (grub_named_list_t head,
struct grub_prio_list
{
struct grub_prio_list *next;
const char *name;
char *name;
int prio;
};
typedef struct grub_prio_list *grub_prio_list_t;

View file

@ -28,6 +28,7 @@
#define ALIGN_UP(addr, align) \
((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(__FILE__, __LINE__, condition, fmt, ## args)
/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
@ -75,9 +76,11 @@ grub_strncat (char *dest, const char *src, int c)
}
/* Prototypes for aliases. */
#if !defined (GRUB_UTIL) || !defined (APPLE_CC)
#ifndef GRUB_UTIL
int EXPORT_FUNC(memcmp) (const void *s1, const void *s2, grub_size_t n);
void *EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n);
void *EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n);
void *EXPORT_FUNC(memset) (void *s, int c, grub_size_t n);
#endif
int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);

View file

@ -25,105 +25,4 @@
void grub_multiboot (int argc, char *argv[]);
void grub_module (int argc, char *argv[]);
#ifndef ASM_FILE
#include <grub/types.h>
struct grub_multiboot_header
{
/* Must be MULTIBOOT_MAGIC - see above. */
grub_uint32_t magic;
/* Feature flags. */
grub_uint32_t flags;
/* The above fields plus this one must equal 0 mod 2^32. */
grub_uint32_t checksum;
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
grub_uint32_t header_addr;
grub_uint32_t load_addr;
grub_uint32_t load_end_addr;
grub_uint32_t bss_end_addr;
grub_uint32_t entry_addr;
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
grub_uint32_t mode_type;
grub_uint32_t width;
grub_uint32_t height;
grub_uint32_t depth;
};
struct grub_multiboot_info
{
/* Multiboot info version number */
grub_uint32_t flags;
/* Available memory from BIOS */
grub_uint32_t mem_lower;
grub_uint32_t mem_upper;
/* "root" partition */
grub_uint32_t boot_device;
/* Kernel command line */
grub_uint32_t cmdline;
/* Boot-Module list */
grub_uint32_t mods_count;
grub_uint32_t mods_addr;
grub_uint32_t syms[4];
/* Memory Mapping buffer */
grub_uint32_t mmap_length;
grub_uint32_t mmap_addr;
/* Drive Info buffer */
grub_uint32_t drives_length;
grub_uint32_t drives_addr;
/* ROM configuration table */
grub_uint32_t config_table;
/* Boot Loader Name */
grub_uint32_t boot_loader_name;
/* APM table */
grub_uint32_t apm_table;
/* Video */
grub_uint32_t vbe_control_info;
grub_uint32_t vbe_mode_info;
grub_uint16_t vbe_mode;
grub_uint16_t vbe_interface_seg;
grub_uint16_t vbe_interface_off;
grub_uint16_t vbe_interface_len;
};
struct grub_multiboot_mmap_entry
{
grub_uint32_t size;
grub_uint64_t addr;
grub_uint64_t len;
#define GRUB_MULTIBOOT_MEMORY_AVAILABLE 1
#define GRUB_MULTIBOOT_MEMORY_RESERVED 2
grub_uint32_t type;
} __attribute__((packed));
struct grub_mod_list
{
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
grub_uint32_t mod_start;
grub_uint32_t mod_end;
/* Module command line */
grub_uint32_t cmdline;
/* padding to take it to 16 bytes (must be zero) */
grub_uint32_t pad;
};
#endif /* ! ASM_FILE */
#endif /* ! GRUB_MULTIBOOT_HEADER */

View file

@ -30,7 +30,7 @@ typedef grub_uint64_t uint64_t;
#define __WORDSIZE GRUB_TARGET_WORDSIZE
#endif
struct multiboot_tag_header;
struct multiboot2_tag_header;
grub_err_t
grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len);
@ -42,7 +42,7 @@ void
grub_mb2_arch_boot (grub_addr_t entry, void *tags);
void
grub_mb2_arch_unload (struct multiboot_tag_header *tags);
grub_mb2_arch_unload (struct multiboot2_tag_header *tags);
grub_err_t
grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
@ -65,6 +65,6 @@ grub_module2 (int argc, char *argv[]);
#define for_each_tag(tag, tags) \
for (tag = tags; \
tag && tag->key != MULTIBOOT2_TAG_END; \
tag = (struct multiboot_tag_header *)((char *)tag + tag->len))
tag = (struct multiboot2_tag_header *)((char *)tag + tag->len))
#endif /* ! GRUB_MULTIBOOT2_HEADER */

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2007 Free Software Foundation, Inc.
* Copyright (C) 2004,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,9 +16,20 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
void EXPORT_FUNC (memset) (void) __attribute__ ((weak));
void EXPORT_FUNC (__ashldi3) (void) __attribute__ ((weak));
void EXPORT_FUNC (__ashrdi3) (void) __attribute__ ((weak));
void EXPORT_FUNC (__lshrdi3) (void) __attribute__ ((weak));
void EXPORT_FUNC (__trampoline_setup) (void) __attribute__ ((weak));
void EXPORT_FUNC (__ucmpdi2) (void) __attribute__ ((weak));
#include <config.h>
#ifdef HAVE___ASHLDI3
void EXPORT_FUNC (__ashldi3) (void);
#endif
#ifdef HAVE___ASHRDI3
void EXPORT_FUNC (__ashrdi3) (void);
#endif
#ifdef HAVE___LSHRDI3
void EXPORT_FUNC (__lshrdi3) (void);
#endif
#ifdef HAVE___TRAMPOLINE_SETUP
void EXPORT_FUNC (__trampoline_setup) (void);
#endif
#ifdef HAVE___UCMPDI2
void EXPORT_FUNC (__ucmpdi2) (void);
#endif

View file

@ -18,10 +18,12 @@
#include <config.h>
void EXPORT_FUNC (memset) (void);
#ifdef HAVE___BSWAPSI2
typedef int SItype __attribute__ ((mode (SI)));
SItype EXPORT_FUNC (__bswapsi2) (SItype) __attribute__ ((weak));
SItype EXPORT_FUNC (__bswapsi2) (SItype);
#endif
#ifdef HAVE___BSWAPDI2
typedef int DItype __attribute__ ((mode (DI)));
DItype EXPORT_FUNC (__bswapdi2) (DItype) __attribute__ ((weak));
DItype EXPORT_FUNC (__bswapdi2) (DItype);
#endif

View file

@ -16,9 +16,4 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_LUA_LIB_HEADER
#define GRUB_LUA_LIB_HEADER 1
extern luaL_Reg grub_lua_lib[];
#endif
#include <grub/i386/io.h>

View file

@ -1,20 +1,23 @@
/* multiboot.h - multiboot header file. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2007,2009 Free Software Foundation, Inc.
* multiboot.h - Multiboot header file.
* Copyright (C) 2003,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef MULTIBOOT_HEADER
@ -92,4 +95,105 @@
/* Is there video information? */
#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800
#ifndef ASM_FILE
#include <grub/types.h>
struct multiboot_header
{
/* Must be MULTIBOOT_MAGIC - see above. */
grub_uint32_t magic;
/* Feature flags. */
grub_uint32_t flags;
/* The above fields plus this one must equal 0 mod 2^32. */
grub_uint32_t checksum;
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
grub_uint32_t header_addr;
grub_uint32_t load_addr;
grub_uint32_t load_end_addr;
grub_uint32_t bss_end_addr;
grub_uint32_t entry_addr;
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
grub_uint32_t mode_type;
grub_uint32_t width;
grub_uint32_t height;
grub_uint32_t depth;
};
struct multiboot_info
{
/* Multiboot info version number */
grub_uint32_t flags;
/* Available memory from BIOS */
grub_uint32_t mem_lower;
grub_uint32_t mem_upper;
/* "root" partition */
grub_uint32_t boot_device;
/* Kernel command line */
grub_uint32_t cmdline;
/* Boot-Module list */
grub_uint32_t mods_count;
grub_uint32_t mods_addr;
grub_uint32_t syms[4];
/* Memory Mapping buffer */
grub_uint32_t mmap_length;
grub_uint32_t mmap_addr;
/* Drive Info buffer */
grub_uint32_t drives_length;
grub_uint32_t drives_addr;
/* ROM configuration table */
grub_uint32_t config_table;
/* Boot Loader Name */
grub_uint32_t boot_loader_name;
/* APM table */
grub_uint32_t apm_table;
/* Video */
grub_uint32_t vbe_control_info;
grub_uint32_t vbe_mode_info;
grub_uint16_t vbe_mode;
grub_uint16_t vbe_interface_seg;
grub_uint16_t vbe_interface_off;
grub_uint16_t vbe_interface_len;
};
struct multiboot_mmap_entry
{
grub_uint32_t size;
grub_uint64_t addr;
grub_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
grub_uint32_t type;
} __attribute__((packed));
struct multiboot_mod_list
{
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
grub_uint32_t mod_start;
grub_uint32_t mod_end;
/* Module command line */
grub_uint32_t cmdline;
/* padding to take it to 16 bytes (must be zero) */
grub_uint32_t pad;
};
#endif /* ! ASM_FILE */
#endif /* ! MULTIBOOT_HEADER */

View file

@ -40,18 +40,18 @@
/* XXX not portable? */
#if __WORDSIZE == 64
typedef uint64_t multiboot_word;
typedef uint64_t multiboot2_word;
#else
typedef uint32_t multiboot_word;
typedef uint32_t multiboot2_word;
#endif
struct multiboot_header
struct multiboot2_header
{
uint32_t magic;
uint32_t flags;
};
struct multiboot_tag_header
struct multiboot2_tag_header
{
uint32_t key;
uint32_t len;
@ -61,48 +61,48 @@ struct multiboot_tag_header
#define MULTIBOOT2_TAG_RESERVED2 (~0)
#define MULTIBOOT2_TAG_START 1
struct multiboot_tag_start
struct multiboot2_tag_start
{
struct multiboot_tag_header header;
multiboot_word size; /* Total size of all multiboot tags. */
struct multiboot2_tag_header header;
multiboot2_word size; /* Total size of all multiboot tags. */
};
#define MULTIBOOT2_TAG_NAME 2
struct multiboot_tag_name
struct multiboot2_tag_name
{
struct multiboot_tag_header header;
struct multiboot2_tag_header header;
char name[1];
};
#define MULTIBOOT2_TAG_MODULE 3
struct multiboot_tag_module
struct multiboot2_tag_module
{
struct multiboot_tag_header header;
multiboot_word addr;
multiboot_word size;
struct multiboot2_tag_header header;
multiboot2_word addr;
multiboot2_word size;
char type[36];
char cmdline[1];
};
#define MULTIBOOT2_TAG_MEMORY 4
struct multiboot_tag_memory
struct multiboot2_tag_memory
{
struct multiboot_tag_header header;
multiboot_word addr;
multiboot_word size;
multiboot_word type;
struct multiboot2_tag_header header;
multiboot2_word addr;
multiboot2_word size;
multiboot2_word type;
};
#define MULTIBOOT2_TAG_UNUSED 5
struct multiboot_tag_unused
struct multiboot2_tag_unused
{
struct multiboot_tag_header header;
struct multiboot2_tag_header header;
};
#define MULTIBOOT2_TAG_END 0xffff
struct multiboot_tag_end
struct multiboot2_tag_end
{
struct multiboot_tag_header header;
struct multiboot2_tag_header header;
};
#endif /* ! ASM_FILE */

View file

@ -31,7 +31,7 @@ grub_register_command_prio (const char *name,
{
grub_command_t cmd;
cmd = (grub_command_t) grub_malloc (sizeof (*cmd));
cmd = (grub_command_t) grub_zalloc (sizeof (*cmd));
if (! cmd)
return 0;
@ -42,7 +42,6 @@ grub_register_command_prio (const char *name,
cmd->flags = GRUB_COMMAND_FLAG_BOTH;
cmd->prio = prio;
cmd->data = 0;
grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list),
GRUB_AS_PRIO_LIST (cmd));

View file

@ -62,7 +62,10 @@ grub_stop_floppy (void)
void
grub_exit (void)
{
grub_fatal ("grub_exit() is not implemented.\n");
/* We can't use grub_fatal() in this function. This would create an infinite
loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */
while (1)
grub_cpu_idle ();
}
void

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,24 +26,24 @@
grub_size_t grub_lower_mem, grub_upper_mem;
/* A pointer to the MBI in its initial location. */
struct grub_multiboot_info *startup_multiboot_info;
struct multiboot_info *startup_multiboot_info;
/* The MBI has to be copied to our BSS so that it won't be
overwritten. This is its final location. */
static struct grub_multiboot_info kern_multiboot_info;
static struct multiboot_info kern_multiboot_info;
/* Unfortunately we can't use heap at this point. But 32 looks like a sane
limit (used by memtest86). */
static grub_uint8_t mmap_entries[sizeof (struct grub_multiboot_mmap_entry) * 32];
static grub_uint8_t mmap_entries[sizeof (struct multiboot_mmap_entry) * 32];
void
grub_machine_mmap_init ()
{
if (! startup_multiboot_info)
grub_fatal ("Must be loaded using Multiboot specification (is this an old version of coreboot?)");
grub_fatal ("Unable to find Multiboot Information (is CONFIG_MULTIBOOT disabled in coreboot?)");
/* Move MBI to a safe place. */
grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct grub_multiboot_info));
grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct multiboot_info));
if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEM_MAP) == 0)
grub_fatal ("Missing Multiboot memory information");
@ -51,7 +51,8 @@ grub_machine_mmap_init ()
/* Move the memory map to a safe place. */
if (kern_multiboot_info.mmap_length > sizeof (mmap_entries))
{
grub_printf ("WARNING: Memory map size exceeds limit; it will be truncated\n");
grub_printf ("WARNING: Memory map size exceeds limit (0x%x > 0x%x); it will be truncated\n",
kern_multiboot_info.mmap_length, sizeof (mmap_entries));
kern_multiboot_info.mmap_length = sizeof (mmap_entries);
}
grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length);
@ -72,7 +73,7 @@ grub_machine_mmap_init ()
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
{
struct grub_multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr;
struct multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr;
while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length)
{

View file

@ -19,6 +19,7 @@
#include <grub/list.h>
#include <grub/misc.h>
#include <grub/mm.h>
void
grub_list_push (grub_list_t *head, grub_list_t item)
@ -81,7 +82,7 @@ grub_list_insert (grub_list_t *head, grub_list_t item,
void *
grub_named_list_find (grub_named_list_t head, const char *name)
{
grub_named_list_t result = 0;
grub_named_list_t result = NULL;
auto int list_find (grub_named_list_t item);
int list_find (grub_named_list_t item)

View file

@ -223,12 +223,12 @@ grub_strncmp (const char *s1, const char *s2, grub_size_t n)
char *
grub_strchr (const char *s, int c)
{
while (*s)
do
{
if (*s == c)
return (char *) s;
s++;
}
while (*s++);
return 0;
}
@ -236,14 +236,14 @@ grub_strchr (const char *s, int c)
char *
grub_strrchr (const char *s, int c)
{
char *p = 0;
char *p = NULL;
while (*s)
do
{
if (*s == c)
p = (char *) s;
s++;
}
while (*s++);
return p;
}

File diff suppressed because it is too large Load diff

3301
lib/libgcrypt/cipher/ac.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,156 @@
/* arcfour.c - The arcfour stream cipher
* Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
* ISBN 0-471-11709-9. Pages 397 ff.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "g10lib.h"
#include "cipher.h"
static const char *selftest(void);
typedef struct {
int idx_i, idx_j;
byte sbox[256];
} ARCFOUR_context;
static void
do_encrypt_stream( ARCFOUR_context *ctx,
byte *outbuf, const byte *inbuf, unsigned int length )
{
register int i = ctx->idx_i;
register int j = ctx->idx_j;
register byte *sbox = ctx->sbox;
register int t;
while ( length-- )
{
i++;
i = i & 255; /* The and-op seems to be faster than the mod-op. */
j += sbox[i];
j &= 255;
t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
*outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
}
ctx->idx_i = i;
ctx->idx_j = j;
}
static void
encrypt_stream (void *context,
byte *outbuf, const byte *inbuf, unsigned int length)
{
ARCFOUR_context *ctx = (ARCFOUR_context *) context;
do_encrypt_stream (ctx, outbuf, inbuf, length );
_gcry_burn_stack (64);
}
static gcry_err_code_t
do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
{
static int initialized;
static const char* selftest_failed;
int i, j;
byte karr[256];
ARCFOUR_context *ctx = (ARCFOUR_context *) context;
if (!initialized )
{
initialized = 1;
selftest_failed = selftest();
if( selftest_failed )
log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed );
}
if( selftest_failed )
return GPG_ERR_SELFTEST_FAILED;
if( keylen < 40/8 ) /* we want at least 40 bits */
return GPG_ERR_INV_KEYLEN;
ctx->idx_i = ctx->idx_j = 0;
for (i=0; i < 256; i++ )
ctx->sbox[i] = i;
for (i=0; i < 256; i++ )
karr[i] = key[i%keylen];
for (i=j=0; i < 256; i++ )
{
int t;
j = (j + ctx->sbox[i] + karr[i]) % 256;
t = ctx->sbox[i];
ctx->sbox[i] = ctx->sbox[j];
ctx->sbox[j] = t;
}
memset( karr, 0, 256 );
return GPG_ERR_NO_ERROR;
}
static gcry_err_code_t
arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
{
ARCFOUR_context *ctx = (ARCFOUR_context *) context;
gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
_gcry_burn_stack (300);
return rc;
}
static const char*
selftest(void)
{
ARCFOUR_context ctx;
byte scratch[16];
/* Test vector from Cryptlib labeled there: "from the
State/Commerce Department". */
static byte key_1[] =
{ 0x61, 0x8A, 0x63, 0xD2, 0xFB };
static byte plaintext_1[] =
{ 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
static const byte ciphertext_1[] =
{ 0xF1, 0x38, 0x29, 0xC9, 0xDE };
arcfour_setkey( &ctx, key_1, sizeof(key_1));
encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1));
if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1)))
return "Arcfour encryption test 1 failed.";
arcfour_setkey( &ctx, key_1, sizeof(key_1));
encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */
if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1)))
return "Arcfour decryption test 1 failed.";
return NULL;
}
gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
{
"ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
};

View file

@ -0,0 +1,54 @@
/* bithelp.h - Some bit manipulation helpers
* Copyright (C) 1999, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef G10_BITHELP_H
#define G10_BITHELP_H
/****************
* Rotate the 32 bit unsigned integer X by N bits left/right
*/
#if defined(__GNUC__) && defined(__i386__)
static inline u32
rol( u32 x, int n)
{
__asm__("roll %%cl,%0"
:"=r" (x)
:"0" (x),"c" (n));
return x;
}
#else
#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
#endif
#if defined(__GNUC__) && defined(__i386__)
static inline u32
ror(u32 x, int n)
{
__asm__("rorl %%cl,%0"
:"=r" (x)
:"0" (x),"c" (n));
return x;
}
#else
#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
#endif
#endif /*G10_BITHELP_H*/

View file

@ -0,0 +1,605 @@
/* blowfish.c - Blowfish encryption
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
* ISBN 0-471-11709-9. Pages 336 ff.
*/
/* Test values:
* key "abcdefghijklmnopqrstuvwxyz";
* plain "BLOWFISH"
* cipher 32 4E D0 FE F4 13 A2 03
*
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "g10lib.h"
#include "cipher.h"
#define BLOWFISH_BLOCKSIZE 8
#define BLOWFISH_ROUNDS 16
typedef struct {
u32 s0[256];
u32 s1[256];
u32 s2[256];
u32 s3[256];
u32 p[BLOWFISH_ROUNDS+2];
} BLOWFISH_context;
static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen);
static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
/* precomputed S boxes */
static const u32 ks0[256] = {
0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96,
0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16,
0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658,
0x718BCD58,0x82154AEE,0x7B54A41D,0xC25A59B5,0x9C30D539,0x2AF26013,
0xC5D1B023,0x286085F0,0xCA417918,0xB8DB38EF,0x8E79DCB0,0x603A180E,
0x6C9E0E8B,0xB01E8A3E,0xD71577C1,0xBD314B27,0x78AF2FDA,0x55605C60,
0xE65525F3,0xAA55AB94,0x57489862,0x63E81440,0x55CA396A,0x2AAB10B6,
0xB4CC5C34,0x1141E8CE,0xA15486AF,0x7C72E993,0xB3EE1411,0x636FBC2A,
0x2BA9C55D,0x741831F6,0xCE5C3E16,0x9B87931E,0xAFD6BA33,0x6C24CF5C,
0x7A325381,0x28958677,0x3B8F4898,0x6B4BB9AF,0xC4BFE81B,0x66282193,
0x61D809CC,0xFB21A991,0x487CAC60,0x5DEC8032,0xEF845D5D,0xE98575B1,
0xDC262302,0xEB651B88,0x23893E81,0xD396ACC5,0x0F6D6FF3,0x83F44239,
0x2E0B4482,0xA4842004,0x69C8F04A,0x9E1F9B5E,0x21C66842,0xF6E96C9A,
0x670C9C61,0xABD388F0,0x6A51A0D2,0xD8542F68,0x960FA728,0xAB5133A3,
0x6EEF0B6C,0x137A3BE4,0xBA3BF050,0x7EFB2A98,0xA1F1651D,0x39AF0176,
0x66CA593E,0x82430E88,0x8CEE8619,0x456F9FB4,0x7D84A5C3,0x3B8B5EBE,
0xE06F75D8,0x85C12073,0x401A449F,0x56C16AA6,0x4ED3AA62,0x363F7706,
0x1BFEDF72,0x429B023D,0x37D0D724,0xD00A1248,0xDB0FEAD3,0x49F1C09B,
0x075372C9,0x80991B7B,0x25D479D8,0xF6E8DEF7,0xE3FE501A,0xB6794C3B,
0x976CE0BD,0x04C006BA,0xC1A94FB6,0x409F60C4,0x5E5C9EC2,0x196A2463,
0x68FB6FAF,0x3E6C53B5,0x1339B2EB,0x3B52EC6F,0x6DFC511F,0x9B30952C,
0xCC814544,0xAF5EBD09,0xBEE3D004,0xDE334AFD,0x660F2807,0x192E4BB3,
0xC0CBA857,0x45C8740F,0xD20B5F39,0xB9D3FBDB,0x5579C0BD,0x1A60320A,
0xD6A100C6,0x402C7279,0x679F25FE,0xFB1FA3CC,0x8EA5E9F8,0xDB3222F8,
0x3C7516DF,0xFD616B15,0x2F501EC8,0xAD0552AB,0x323DB5FA,0xFD238760,
0x53317B48,0x3E00DF82,0x9E5C57BB,0xCA6F8CA0,0x1A87562E,0xDF1769DB,
0xD542A8F6,0x287EFFC3,0xAC6732C6,0x8C4F5573,0x695B27B0,0xBBCA58C8,
0xE1FFA35D,0xB8F011A0,0x10FA3D98,0xFD2183B8,0x4AFCB56C,0x2DD1D35B,
0x9A53E479,0xB6F84565,0xD28E49BC,0x4BFB9790,0xE1DDF2DA,0xA4CB7E33,
0x62FB1341,0xCEE4C6E8,0xEF20CADA,0x36774C01,0xD07E9EFE,0x2BF11FB4,
0x95DBDA4D,0xAE909198,0xEAAD8E71,0x6B93D5A0,0xD08ED1D0,0xAFC725E0,
0x8E3C5B2F,0x8E7594B7,0x8FF6E2FB,0xF2122B64,0x8888B812,0x900DF01C,
0x4FAD5EA0,0x688FC31C,0xD1CFF191,0xB3A8C1AD,0x2F2F2218,0xBE0E1777,
0xEA752DFE,0x8B021FA1,0xE5A0CC0F,0xB56F74E8,0x18ACF3D6,0xCE89E299,
0xB4A84FE0,0xFD13E0B7,0x7CC43B81,0xD2ADA8D9,0x165FA266,0x80957705,
0x93CC7314,0x211A1477,0xE6AD2065,0x77B5FA86,0xC75442F5,0xFB9D35CF,
0xEBCDAF0C,0x7B3E89A0,0xD6411BD3,0xAE1E7E49,0x00250E2D,0x2071B35E,
0x226800BB,0x57B8E0AF,0x2464369B,0xF009B91E,0x5563911D,0x59DFA6AA,
0x78C14389,0xD95A537F,0x207D5BA2,0x02E5B9C5,0x83260376,0x6295CFA9,
0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915,
0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F,
0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664,
0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A };
static const u32 ks1[256] = {
0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D,
0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1,
0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65,
0x6B8FE4D6,0x99F73FD6,0xA1D29C07,0xEFE830F5,0x4D2D38E6,0xF0255DC1,
0x4CDD2086,0x8470EB26,0x6382E9C6,0x021ECC5E,0x09686B3F,0x3EBAEFC9,
0x3C971814,0x6B6A70A1,0x687F3584,0x52A0E286,0xB79C5305,0xAA500737,
0x3E07841C,0x7FDEAE5C,0x8E7D44EC,0x5716F2B8,0xB03ADA37,0xF0500C0D,
0xF01C1F04,0x0200B3FF,0xAE0CF51A,0x3CB574B2,0x25837A58,0xDC0921BD,
0xD19113F9,0x7CA92FF6,0x94324773,0x22F54701,0x3AE5E581,0x37C2DADC,
0xC8B57634,0x9AF3DDA7,0xA9446146,0x0FD0030E,0xECC8C73E,0xA4751E41,
0xE238CD99,0x3BEA0E2F,0x3280BBA1,0x183EB331,0x4E548B38,0x4F6DB908,
0x6F420D03,0xF60A04BF,0x2CB81290,0x24977C79,0x5679B072,0xBCAF89AF,
0xDE9A771F,0xD9930810,0xB38BAE12,0xDCCF3F2E,0x5512721F,0x2E6B7124,
0x501ADDE6,0x9F84CD87,0x7A584718,0x7408DA17,0xBC9F9ABC,0xE94B7D8C,
0xEC7AEC3A,0xDB851DFA,0x63094366,0xC464C3D2,0xEF1C1847,0x3215D908,
0xDD433B37,0x24C2BA16,0x12A14D43,0x2A65C451,0x50940002,0x133AE4DD,
0x71DFF89E,0x10314E55,0x81AC77D6,0x5F11199B,0x043556F1,0xD7A3C76B,
0x3C11183B,0x5924A509,0xF28FE6ED,0x97F1FBFA,0x9EBABF2C,0x1E153C6E,
0x86E34570,0xEAE96FB1,0x860E5E0A,0x5A3E2AB3,0x771FE71C,0x4E3D06FA,
0x2965DCB9,0x99E71D0F,0x803E89D6,0x5266C825,0x2E4CC978,0x9C10B36A,
0xC6150EBA,0x94E2EA78,0xA5FC3C53,0x1E0A2DF4,0xF2F74EA7,0x361D2B3D,
0x1939260F,0x19C27960,0x5223A708,0xF71312B6,0xEBADFE6E,0xEAC31F66,
0xE3BC4595,0xA67BC883,0xB17F37D1,0x018CFF28,0xC332DDEF,0xBE6C5AA5,
0x65582185,0x68AB9802,0xEECEA50F,0xDB2F953B,0x2AEF7DAD,0x5B6E2F84,
0x1521B628,0x29076170,0xECDD4775,0x619F1510,0x13CCA830,0xEB61BD96,
0x0334FE1E,0xAA0363CF,0xB5735C90,0x4C70A239,0xD59E9E0B,0xCBAADE14,
0xEECC86BC,0x60622CA7,0x9CAB5CAB,0xB2F3846E,0x648B1EAF,0x19BDF0CA,
0xA02369B9,0x655ABB50,0x40685A32,0x3C2AB4B3,0x319EE9D5,0xC021B8F7,
0x9B540B19,0x875FA099,0x95F7997E,0x623D7DA8,0xF837889A,0x97E32D77,
0x11ED935F,0x16681281,0x0E358829,0xC7E61FD6,0x96DEDFA1,0x7858BA99,
0x57F584A5,0x1B227263,0x9B83C3FF,0x1AC24696,0xCDB30AEB,0x532E3054,
0x8FD948E4,0x6DBC3128,0x58EBF2EF,0x34C6FFEA,0xFE28ED61,0xEE7C3C73,
0x5D4A14D9,0xE864B7E3,0x42105D14,0x203E13E0,0x45EEE2B6,0xA3AAABEA,
0xDB6C4F15,0xFACB4FD0,0xC742F442,0xEF6ABBB5,0x654F3B1D,0x41CD2105,
0xD81E799E,0x86854DC7,0xE44B476A,0x3D816250,0xCF62A1F2,0x5B8D2646,
0xFC8883A0,0xC1C7B6A3,0x7F1524C3,0x69CB7492,0x47848A0B,0x5692B285,
0x095BBF00,0xAD19489D,0x1462B174,0x23820E00,0x58428D2A,0x0C55F5EA,
0x1DADF43E,0x233F7061,0x3372F092,0x8D937E41,0xD65FECF1,0x6C223BDB,
0x7CDE3759,0xCBEE7460,0x4085F2A7,0xCE77326E,0xA6078084,0x19F8509E,
0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC,
0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD,
0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20,
0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7 };
static const u32 ks2[256] = {
0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7,
0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF,
0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF,
0x70F4DDD3,0x66A02F45,0xBFBC09EC,0x03BD9785,0x7FAC6DD0,0x31CB8504,
0x96EB27B3,0x55FD3941,0xDA2547E6,0xABCA0A9A,0x28507825,0x530429F4,
0x0A2C86DA,0xE9B66DFB,0x68DC1462,0xD7486900,0x680EC0A4,0x27A18DEE,
0x4F3FFEA2,0xE887AD8C,0xB58CE006,0x7AF4D6B6,0xAACE1E7C,0xD3375FEC,
0xCE78A399,0x406B2A42,0x20FE9E35,0xD9F385B9,0xEE39D7AB,0x3B124E8B,
0x1DC9FAF7,0x4B6D1856,0x26A36631,0xEAE397B2,0x3A6EFA74,0xDD5B4332,
0x6841E7F7,0xCA7820FB,0xFB0AF54E,0xD8FEB397,0x454056AC,0xBA489527,
0x55533A3A,0x20838D87,0xFE6BA9B7,0xD096954B,0x55A867BC,0xA1159A58,
0xCCA92963,0x99E1DB33,0xA62A4A56,0x3F3125F9,0x5EF47E1C,0x9029317C,
0xFDF8E802,0x04272F70,0x80BB155C,0x05282CE3,0x95C11548,0xE4C66D22,
0x48C1133F,0xC70F86DC,0x07F9C9EE,0x41041F0F,0x404779A4,0x5D886E17,
0x325F51EB,0xD59BC0D1,0xF2BCC18F,0x41113564,0x257B7834,0x602A9C60,
0xDFF8E8A3,0x1F636C1B,0x0E12B4C2,0x02E1329E,0xAF664FD1,0xCAD18115,
0x6B2395E0,0x333E92E1,0x3B240B62,0xEEBEB922,0x85B2A20E,0xE6BA0D99,
0xDE720C8C,0x2DA2F728,0xD0127845,0x95B794FD,0x647D0862,0xE7CCF5F0,
0x5449A36F,0x877D48FA,0xC39DFD27,0xF33E8D1E,0x0A476341,0x992EFF74,
0x3A6F6EAB,0xF4F8FD37,0xA812DC60,0xA1EBDDF8,0x991BE14C,0xDB6E6B0D,
0xC67B5510,0x6D672C37,0x2765D43B,0xDCD0E804,0xF1290DC7,0xCC00FFA3,
0xB5390F92,0x690FED0B,0x667B9FFB,0xCEDB7D9C,0xA091CF0B,0xD9155EA3,
0xBB132F88,0x515BAD24,0x7B9479BF,0x763BD6EB,0x37392EB3,0xCC115979,
0x8026E297,0xF42E312D,0x6842ADA7,0xC66A2B3B,0x12754CCC,0x782EF11C,
0x6A124237,0xB79251E7,0x06A1BBE6,0x4BFB6350,0x1A6B1018,0x11CAEDFA,
0x3D25BDD8,0xE2E1C3C9,0x44421659,0x0A121386,0xD90CEC6E,0xD5ABEA2A,
0x64AF674E,0xDA86A85F,0xBEBFE988,0x64E4C3FE,0x9DBC8057,0xF0F7C086,
0x60787BF8,0x6003604D,0xD1FD8346,0xF6381FB0,0x7745AE04,0xD736FCCC,
0x83426B33,0xF01EAB71,0xB0804187,0x3C005E5F,0x77A057BE,0xBDE8AE24,
0x55464299,0xBF582E61,0x4E58F48F,0xF2DDFDA2,0xF474EF38,0x8789BDC2,
0x5366F9C3,0xC8B38E74,0xB475F255,0x46FCD9B9,0x7AEB2661,0x8B1DDF84,
0x846A0E79,0x915F95E2,0x466E598E,0x20B45770,0x8CD55591,0xC902DE4C,
0xB90BACE1,0xBB8205D0,0x11A86248,0x7574A99E,0xB77F19B6,0xE0A9DC09,
0x662D09A1,0xC4324633,0xE85A1F02,0x09F0BE8C,0x4A99A025,0x1D6EFE10,
0x1AB93D1D,0x0BA5A4DF,0xA186F20F,0x2868F169,0xDCB7DA83,0x573906FE,
0xA1E2CE9B,0x4FCD7F52,0x50115E01,0xA70683FA,0xA002B5C4,0x0DE6D027,
0x9AF88C27,0x773F8641,0xC3604C06,0x61A806B5,0xF0177A28,0xC0F586E0,
0x006058AA,0x30DC7D62,0x11E69ED7,0x2338EA63,0x53C2DD94,0xC2C21634,
0xBBCBEE56,0x90BCB6DE,0xEBFC7DA1,0xCE591D76,0x6F05E409,0x4B7C0188,
0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC,
0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8,
0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837,
0xD79A3234,0x92638212,0x670EFA8E,0x406000E0 };
static const u32 ks3[256] = {
0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742,
0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B,
0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79,
0xC6A376D2,0x6549C2C8,0x530FF8EE,0x468DDE7D,0xD5730A1D,0x4CD04DC6,
0x2939BBDB,0xA9BA4650,0xAC9526E8,0xBE5EE304,0xA1FAD5F0,0x6A2D519A,
0x63EF8CE2,0x9A86EE22,0xC089C2B8,0x43242EF6,0xA51E03AA,0x9CF2D0A4,
0x83C061BA,0x9BE96A4D,0x8FE51550,0xBA645BD6,0x2826A2F9,0xA73A3AE1,
0x4BA99586,0xEF5562E9,0xC72FEFD3,0xF752F7DA,0x3F046F69,0x77FA0A59,
0x80E4A915,0x87B08601,0x9B09E6AD,0x3B3EE593,0xE990FD5A,0x9E34D797,
0x2CF0B7D9,0x022B8B51,0x96D5AC3A,0x017DA67D,0xD1CF3ED6,0x7C7D2D28,
0x1F9F25CF,0xADF2B89B,0x5AD6B472,0x5A88F54C,0xE029AC71,0xE019A5E6,
0x47B0ACFD,0xED93FA9B,0xE8D3C48D,0x283B57CC,0xF8D56629,0x79132E28,
0x785F0191,0xED756055,0xF7960E44,0xE3D35E8C,0x15056DD4,0x88F46DBA,
0x03A16125,0x0564F0BD,0xC3EB9E15,0x3C9057A2,0x97271AEC,0xA93A072A,
0x1B3F6D9B,0x1E6321F5,0xF59C66FB,0x26DCF319,0x7533D928,0xB155FDF5,
0x03563482,0x8ABA3CBB,0x28517711,0xC20AD9F8,0xABCC5167,0xCCAD925F,
0x4DE81751,0x3830DC8E,0x379D5862,0x9320F991,0xEA7A90C2,0xFB3E7BCE,
0x5121CE64,0x774FBE32,0xA8B6E37E,0xC3293D46,0x48DE5369,0x6413E680,
0xA2AE0810,0xDD6DB224,0x69852DFD,0x09072166,0xB39A460A,0x6445C0DD,
0x586CDECF,0x1C20C8AE,0x5BBEF7DD,0x1B588D40,0xCCD2017F,0x6BB4E3BB,
0xDDA26A7E,0x3A59FF45,0x3E350A44,0xBCB4CDD5,0x72EACEA8,0xFA6484BB,
0x8D6612AE,0xBF3C6F47,0xD29BE463,0x542F5D9E,0xAEC2771B,0xF64E6370,
0x740E0D8D,0xE75B1357,0xF8721671,0xAF537D5D,0x4040CB08,0x4EB4E2CC,
0x34D2466A,0x0115AF84,0xE1B00428,0x95983A1D,0x06B89FB4,0xCE6EA048,
0x6F3F3B82,0x3520AB82,0x011A1D4B,0x277227F8,0x611560B1,0xE7933FDC,
0xBB3A792B,0x344525BD,0xA08839E1,0x51CE794B,0x2F32C9B7,0xA01FBAC9,
0xE01CC87E,0xBCC7D1F6,0xCF0111C3,0xA1E8AAC7,0x1A908749,0xD44FBD9A,
0xD0DADECB,0xD50ADA38,0x0339C32A,0xC6913667,0x8DF9317C,0xE0B12B4F,
0xF79E59B7,0x43F5BB3A,0xF2D519FF,0x27D9459C,0xBF97222C,0x15E6FC2A,
0x0F91FC71,0x9B941525,0xFAE59361,0xCEB69CEB,0xC2A86459,0x12BAA8D1,
0xB6C1075E,0xE3056A0C,0x10D25065,0xCB03A442,0xE0EC6E0E,0x1698DB3B,
0x4C98A0BE,0x3278E964,0x9F1F9532,0xE0D392DF,0xD3A0342B,0x8971F21E,
0x1B0A7441,0x4BA3348C,0xC5BE7120,0xC37632D8,0xDF359F8D,0x9B992F2E,
0xE60B6F47,0x0FE3F11D,0xE54CDA54,0x1EDAD891,0xCE6279CF,0xCD3E7E6F,
0x1618B166,0xFD2C1D05,0x848FD2C5,0xF6FB2299,0xF523F357,0xA6327623,
0x93A83531,0x56CCCD02,0xACF08162,0x5A75EBB5,0x6E163697,0x88D273CC,
0xDE966292,0x81B949D0,0x4C50901B,0x71C65614,0xE6C6C7BD,0x327A140A,
0x45E1D006,0xC3F27B9A,0xC9AA53FD,0x62A80F00,0xBB25BFE2,0x35BDD2F6,
0x71126905,0xB2040222,0xB6CBCF7C,0xCD769C2B,0x53113EC0,0x1640E3D3,
0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060,
0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C,
0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F,
0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6 };
static const u32 ps[BLOWFISH_ROUNDS+2] = {
0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,
0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,
0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B };
#if BLOWFISH_ROUNDS != 16
static inline u32
function_F( BLOWFISH_context *bc, u32 x )
{
u16 a, b, c, d;
#ifdef WORDS_BIGENDIAN
a = ((byte*)&x)[0];
b = ((byte*)&x)[1];
c = ((byte*)&x)[2];
d = ((byte*)&x)[3];
#else
a = ((byte*)&x)[3];
b = ((byte*)&x)[2];
c = ((byte*)&x)[1];
d = ((byte*)&x)[0];
#endif
return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
}
#endif
#ifdef WORDS_BIGENDIAN
#define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]]) \
^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
#else
#define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]]) \
^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
#endif
#define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0)
static void
do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
#if BLOWFISH_ROUNDS == 16
u32 xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
s0 = bc->s0;
s1 = bc->s1;
s2 = bc->s2;
s3 = bc->s3;
R( xl, xr, 0);
R( xr, xl, 1);
R( xl, xr, 2);
R( xr, xl, 3);
R( xl, xr, 4);
R( xr, xl, 5);
R( xl, xr, 6);
R( xr, xl, 7);
R( xl, xr, 8);
R( xr, xl, 9);
R( xl, xr, 10);
R( xr, xl, 11);
R( xl, xr, 12);
R( xr, xl, 13);
R( xl, xr, 14);
R( xr, xl, 15);
xl ^= p[BLOWFISH_ROUNDS];
xr ^= p[BLOWFISH_ROUNDS+1];
*ret_xl = xr;
*ret_xr = xl;
#else
u32 xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
for(i=0; i < BLOWFISH_ROUNDS; i++ )
{
xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
xr = temp;
}
temp = xl;
xl = xr;
xr = temp;
xr ^= p[BLOWFISH_ROUNDS];
xl ^= p[BLOWFISH_ROUNDS+1];
*ret_xl = xl;
*ret_xr = xr;
#endif
}
static void
decrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
#if BLOWFISH_ROUNDS == 16
u32 xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
s0 = bc->s0;
s1 = bc->s1;
s2 = bc->s2;
s3 = bc->s3;
R( xl, xr, 17);
R( xr, xl, 16);
R( xl, xr, 15);
R( xr, xl, 14);
R( xl, xr, 13);
R( xr, xl, 12);
R( xl, xr, 11);
R( xr, xl, 10);
R( xl, xr, 9);
R( xr, xl, 8);
R( xl, xr, 7);
R( xr, xl, 6);
R( xl, xr, 5);
R( xr, xl, 4);
R( xl, xr, 3);
R( xr, xl, 2);
xl ^= p[1];
xr ^= p[0];
*ret_xl = xr;
*ret_xr = xl;
#else
u32 xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
for (i=BLOWFISH_ROUNDS+1; i > 1; i-- )
{
xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
xr = temp;
}
temp = xl;
xl = xr;
xr = temp;
xr ^= p[1];
xl ^= p[0];
*ret_xl = xl;
*ret_xr = xr;
#endif
}
#undef F
#undef R
static void
do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
{
u32 d1, d2;
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
do_encrypt( bc, &d1, &d2 );
outbuf[0] = (d1 >> 24) & 0xff;
outbuf[1] = (d1 >> 16) & 0xff;
outbuf[2] = (d1 >> 8) & 0xff;
outbuf[3] = d1 & 0xff;
outbuf[4] = (d2 >> 24) & 0xff;
outbuf[5] = (d2 >> 16) & 0xff;
outbuf[6] = (d2 >> 8) & 0xff;
outbuf[7] = d2 & 0xff;
}
static void
encrypt_block (void *context, byte *outbuf, const byte *inbuf)
{
BLOWFISH_context *bc = (BLOWFISH_context *) context;
do_encrypt_block (bc, outbuf, inbuf);
_gcry_burn_stack (64);
}
static void
do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf)
{
u32 d1, d2;
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
decrypt( bc, &d1, &d2 );
outbuf[0] = (d1 >> 24) & 0xff;
outbuf[1] = (d1 >> 16) & 0xff;
outbuf[2] = (d1 >> 8) & 0xff;
outbuf[3] = d1 & 0xff;
outbuf[4] = (d2 >> 24) & 0xff;
outbuf[5] = (d2 >> 16) & 0xff;
outbuf[6] = (d2 >> 8) & 0xff;
outbuf[7] = d2 & 0xff;
}
static void
decrypt_block (void *context, byte *outbuf, const byte *inbuf)
{
BLOWFISH_context *bc = (BLOWFISH_context *) context;
do_decrypt_block (bc, outbuf, inbuf);
_gcry_burn_stack (64);
}
static const char*
selftest(void)
{
BLOWFISH_context c;
byte plain[] = "BLOWFISH";
byte buffer[8];
byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
bf_setkey( (void *) &c,
(const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 );
encrypt_block( (void *) &c, buffer, plain );
if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
return "Blowfish selftest failed (1).";
decrypt_block( (void *) &c, buffer, buffer );
if( memcmp( buffer, plain, 8 ) )
return "Blowfish selftest failed (2).";
bf_setkey( (void *) &c, key3, 8 );
encrypt_block( (void *) &c, buffer, plain3 );
if( memcmp( buffer, cipher3, 8 ) )
return "Blowfish selftest failed (3).";
decrypt_block( (void *) &c, buffer, buffer );
if( memcmp( buffer, plain3, 8 ) )
return "Blowfish selftest failed (4).";
return NULL;
}
static gcry_err_code_t
do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
{
int i, j;
u32 data, datal, datar;
static int initialized;
static const char *selftest_failed;
if( !initialized )
{
initialized = 1;
selftest_failed = selftest();
if( selftest_failed )
log_error ("%s\n", selftest_failed );
}
if( selftest_failed )
return GPG_ERR_SELFTEST_FAILED;
for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
c->p[i] = ps[i];
for(i=0; i < 256; i++ )
{
c->s0[i] = ks0[i];
c->s1[i] = ks1[i];
c->s2[i] = ks2[i];
c->s3[i] = ks3[i];
}
for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ )
{
#ifdef WORDS_BIGENDIAN
((byte*)&data)[0] = key[j];
((byte*)&data)[1] = key[(j+1)%keylen];
((byte*)&data)[2] = key[(j+2)%keylen];
((byte*)&data)[3] = key[(j+3)%keylen];
#else
((byte*)&data)[3] = key[j];
((byte*)&data)[2] = key[(j+1)%keylen];
((byte*)&data)[1] = key[(j+2)%keylen];
((byte*)&data)[0] = key[(j+3)%keylen];
#endif
c->p[i] ^= data;
j = (j+4) % keylen;
}
datal = datar = 0;
for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 )
{
do_encrypt( c, &datal, &datar );
c->p[i] = datal;
c->p[i+1] = datar;
}
for(i=0; i < 256; i += 2 )
{
do_encrypt( c, &datal, &datar );
c->s0[i] = datal;
c->s0[i+1] = datar;
}
for(i=0; i < 256; i += 2 )
{
do_encrypt( c, &datal, &datar );
c->s1[i] = datal;
c->s1[i+1] = datar;
}
for(i=0; i < 256; i += 2 )
{
do_encrypt( c, &datal, &datar );
c->s2[i] = datal;
c->s2[i+1] = datar;
}
for(i=0; i < 256; i += 2 )
{
do_encrypt( c, &datal, &datar );
c->s3[i] = datal;
c->s3[i+1] = datar;
}
/* Check for weak key. A weak key is a key in which a value in
the P-array (here c) occurs more than once per table. */
for(i=0; i < 255; i++ )
{
for( j=i+1; j < 256; j++)
{
if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) ||
(c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) )
return GPG_ERR_WEAK_KEY;
}
}
return GPG_ERR_NO_ERROR;
}
static gcry_err_code_t
bf_setkey (void *context, const byte *key, unsigned keylen)
{
BLOWFISH_context *c = (BLOWFISH_context *) context;
gcry_err_code_t rc = do_bf_setkey (c, key, keylen);
_gcry_burn_stack (64);
return rc;
}
gcry_cipher_spec_t _gcry_cipher_spec_blowfish =
{
"BLOWFISH", NULL, NULL, BLOWFISH_BLOCKSIZE, 128,
sizeof (BLOWFISH_context),
bf_setkey, encrypt_block, decrypt_block
};

View file

@ -0,0 +1,253 @@
/* camellia-glue.c - Glue for the Camellia cipher
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/* I put all the libgcrypt-specific stuff in this file to keep the
camellia.c/camellia.h files exactly as provided by NTT. If they
update their code, this should make it easier to bring the changes
in. - dshaw
There is one small change which needs to be done: Include the
following code at the top of camellia.h: */
#if 0
/* To use Camellia with libraries it is often useful to keep the name
* space of the library clean. The following macro is thus useful:
*
* #define CAMELLIA_EXT_SYM_PREFIX foo_
*
* This prefixes all external symbols with "foo_".
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef CAMELLIA_EXT_SYM_PREFIX
#define CAMELLIA_PREFIX1(x,y) x ## y
#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
#endif /*CAMELLIA_EXT_SYM_PREFIX*/
#endif /* Code sample. */
#include <config.h>
#include "types.h"
#include "g10lib.h"
#include "cipher.h"
#include "camellia.h"
typedef struct
{
int keybitlength;
KEY_TABLE_TYPE keytable;
} CAMELLIA_context;
static const char *selftest(void);
static gcry_err_code_t
camellia_setkey(void *c, const byte *key, unsigned keylen)
{
CAMELLIA_context *ctx=c;
static int initialized=0;
static const char *selftest_failed=NULL;
if(keylen!=16 && keylen!=24 && keylen!=32)
return GPG_ERR_INV_KEYLEN;
if(!initialized)
{
initialized=1;
selftest_failed=selftest();
if(selftest_failed)
log_error("%s\n",selftest_failed);
}
if(selftest_failed)
return GPG_ERR_SELFTEST_FAILED;
ctx->keybitlength=keylen*8;
Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
_gcry_burn_stack
((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
+(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */
+0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */
+3*2*sizeof(void*) /* Function calls. */
);
return 0;
}
static void
camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
{
CAMELLIA_context *ctx=c;
Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
_gcry_burn_stack
(sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+4*sizeof(u32)
+2*sizeof(u32*)+4*sizeof(u32)
+2*2*sizeof(void*) /* Function calls. */
);
}
static void
camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
{
CAMELLIA_context *ctx=c;
Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
_gcry_burn_stack
(sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+4*sizeof(u32)
+2*sizeof(u32*)+4*sizeof(u32)
+2*2*sizeof(void*) /* Function calls. */
);
}
static const char *
selftest(void)
{
CAMELLIA_context ctx;
byte scratch[16];
/* These test vectors are from RFC-3713 */
const byte plaintext[]=
{
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
};
const byte key_128[]=
{
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
};
const byte ciphertext_128[]=
{
0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
};
const byte key_192[]=
{
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
};
const byte ciphertext_192[]=
{
0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
};
const byte key_256[]=
{
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
};
const byte ciphertext_256[]=
{
0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
};
camellia_setkey(&ctx,key_128,sizeof(key_128));
camellia_encrypt(&ctx,scratch,plaintext);
if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
return "CAMELLIA-128 test encryption failed.";
camellia_decrypt(&ctx,scratch,scratch);
if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
return "CAMELLIA-128 test decryption failed.";
camellia_setkey(&ctx,key_192,sizeof(key_192));
camellia_encrypt(&ctx,scratch,plaintext);
if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
return "CAMELLIA-192 test encryption failed.";
camellia_decrypt(&ctx,scratch,scratch);
if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
return "CAMELLIA-192 test decryption failed.";
camellia_setkey(&ctx,key_256,sizeof(key_256));
camellia_encrypt(&ctx,scratch,plaintext);
if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
return "CAMELLIA-256 test encryption failed.";
camellia_decrypt(&ctx,scratch,scratch);
if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
return "CAMELLIA-256 test decryption failed.";
return NULL;
}
/* These oids are from
<http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
retrieved May 1, 2007. */
static gcry_cipher_oid_spec_t camellia128_oids[] =
{
{"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
{"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
{"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
{"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
{ NULL }
};
static gcry_cipher_oid_spec_t camellia192_oids[] =
{
{"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
{"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
{"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
{"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
{ NULL }
};
static gcry_cipher_oid_spec_t camellia256_oids[] =
{
{"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
{"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
{"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
{"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
{ NULL }
};
gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
{
"CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
};
gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
{
"CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
};
gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
{
"CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,81 @@
/* camellia.h ver 1.2.0
*
* Copyright (C) 2006,2007
* NTT (Nippon Telegraph and Telephone Corporation).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HEADER_CAMELLIA_H
#define HEADER_CAMELLIA_H
/* To use Camellia with libraries it is often useful to keep the name
* space of the library clean. The following macro is thus useful:
*
* #define CAMELLIA_EXT_SYM_PREFIX foo_
*
* This prefixes all external symbols with "foo_".
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef CAMELLIA_EXT_SYM_PREFIX
#define CAMELLIA_PREFIX1(x,y) x ## y
#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
#endif /*CAMELLIA_EXT_SYM_PREFIX*/
#ifdef __cplusplus
extern "C" {
#endif
#define CAMELLIA_BLOCK_SIZE 16
#define CAMELLIA_TABLE_BYTE_LEN 272
#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
void Camellia_Ekeygen(const int keyBitLength,
const unsigned char *rawKey,
KEY_TABLE_TYPE keyTable);
void Camellia_EncryptBlock(const int keyBitLength,
const unsigned char *plaintext,
const KEY_TABLE_TYPE keyTable,
unsigned char *cipherText);
void Camellia_DecryptBlock(const int keyBitLength,
const unsigned char *cipherText,
const KEY_TABLE_TYPE keyTable,
unsigned char *plaintext);
#ifdef __cplusplus
}
#endif
#endif /* HEADER_CAMELLIA_H */

View file

@ -0,0 +1,620 @@
/* cast5.c - CAST5 cipher (RFC2144)
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/* Test vectors:
*
* 128-bit key = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A
* plaintext = 01 23 45 67 89 AB CD EF
* ciphertext = 23 8B 4F E5 84 7E 44 B2
*
* 80-bit key = 01 23 45 67 12 34 56 78 23 45
* = 01 23 45 67 12 34 56 78 23 45 00 00 00 00 00 00
* plaintext = 01 23 45 67 89 AB CD EF
* ciphertext = EB 6A 71 1A 2C 02 27 1B
*
* 40-bit key = 01 23 45 67 12
* = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00
* plaintext = 01 23 45 67 89 AB CD EF
* ciphertext = 7A C8 16 D1 6E 9B 30 2E
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
#include "types.h"
#include "cipher.h"
#define CAST5_BLOCKSIZE 8
typedef struct {
u32 Km[16];
byte Kr[16];
} CAST5_context;
static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
static const u32 s1[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
};
static const u32 s2[256] = {
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
};
static const u32 s3[256] = {
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
};
static const u32 s4[256] = {
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
};
static const u32 s5[256] = {
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
};
static const u32 s6[256] = {
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
};
static const u32 s7[256] = {
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
};
static const u32 s8[256] = {
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
};
#if defined(__GNUC__) && defined(__i386__)
static inline u32
rol(int n, u32 x)
{
__asm__("roll %%cl,%0"
:"=r" (x)
:"0" (x),"c" (n));
return x;
}
#else
#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
#endif
#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol((r),I)), \
(((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol((r),I)), \
(((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \
(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
static void
do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
{
u32 l, r, t;
u32 I; /* used by the Fx macros */
u32 *Km;
byte *Kr;
Km = c->Km;
Kr = c->Kr;
/* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
* right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
*/
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
/* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
* Li = Ri-1;
* Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
* Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
* Rounds 2, 5, 8, 11, and 14 use f function Type 2.
* Rounds 3, 6, 9, 12, and 15 use f function Type 3.
*/
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
/* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
* concatenate to form the ciphertext.) */
outbuf[0] = (r >> 24) & 0xff;
outbuf[1] = (r >> 16) & 0xff;
outbuf[2] = (r >> 8) & 0xff;
outbuf[3] = r & 0xff;
outbuf[4] = (l >> 24) & 0xff;
outbuf[5] = (l >> 16) & 0xff;
outbuf[6] = (l >> 8) & 0xff;
outbuf[7] = l & 0xff;
}
static void
encrypt_block (void *context , byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_encrypt_block (c, outbuf, inbuf);
_gcry_burn_stack (20+4*sizeof(void*));
}
static void
do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
{
u32 l, r, t;
u32 I;
u32 *Km;
byte *Kr;
Km = c->Km;
Kr = c->Kr;
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
outbuf[0] = (r >> 24) & 0xff;
outbuf[1] = (r >> 16) & 0xff;
outbuf[2] = (r >> 8) & 0xff;
outbuf[3] = r & 0xff;
outbuf[4] = (l >> 24) & 0xff;
outbuf[5] = (l >> 16) & 0xff;
outbuf[6] = (l >> 8) & 0xff;
outbuf[7] = l & 0xff;
}
static void
decrypt_block (void *context, byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_decrypt_block (c, outbuf, inbuf);
_gcry_burn_stack (20+4*sizeof(void*));
}
static const char*
selftest(void)
{
CAST5_context c;
byte key[16] = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };
byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
byte buffer[8];
cast_setkey( &c, key, 16 );
encrypt_block( &c, buffer, plain );
if( memcmp( buffer, cipher, 8 ) )
return "1";
decrypt_block( &c, buffer, buffer );
if( memcmp( buffer, plain, 8 ) )
return "2";
#if 0 /* full maintenance test */
{
int i;
byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 };
byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
for(i=0; i < 1000000; i++ ) {
cast_setkey( &c, b0, 16 );
encrypt_block( &c, a0, a0 );
encrypt_block( &c, a0+8, a0+8 );
cast_setkey( &c, a0, 16 );
encrypt_block( &c, b0, b0 );
encrypt_block( &c, b0+8, b0+8 );
}
if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
return "3";
}
#endif
return NULL;
}
static void
key_schedule( u32 *x, u32 *z, u32 *k )
{
#define xi(i) ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
#define zi(i) ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)];
k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)];
k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)];
k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)];
x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)];
k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)];
k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)];
k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)];
z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)];
k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)];
k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)];
k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)];
x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)];
k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)];
k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)];
k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)];
#undef xi
#undef zi
}
static gcry_err_code_t
do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
{
static int initialized;
static const char* selftest_failed;
int i;
u32 x[4];
u32 z[4];
u32 k[16];
if( !initialized )
{
initialized = 1;
selftest_failed = selftest();
if( selftest_failed )
log_error ("CAST5 selftest failed (%s).\n", selftest_failed );
}
if( selftest_failed )
return GPG_ERR_SELFTEST_FAILED;
if( keylen != 16 )
return GPG_ERR_INV_KEYLEN;
x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7];
x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11];
x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
key_schedule( x, z, k );
for(i=0; i < 16; i++ )
c->Km[i] = k[i];
key_schedule( x, z, k );
for(i=0; i < 16; i++ )
c->Kr[i] = k[i] & 0x1f;
memset(&x,0, sizeof x);
memset(&z,0, sizeof z);
memset(&k,0, sizeof k);
#undef xi
#undef zi
return GPG_ERR_NO_ERROR;
}
static gcry_err_code_t
cast_setkey (void *context, const byte *key, unsigned keylen )
{
CAST5_context *c = (CAST5_context *) context;
gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
_gcry_burn_stack (96+7*sizeof(void*));
return rc;
}
gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
{
"CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
cast_setkey, encrypt_block, decrypt_block
};

File diff suppressed because it is too large Load diff

297
lib/libgcrypt/cipher/crc.c Normal file
View file

@ -0,0 +1,297 @@
/* crc.c - Cyclic redundancy checks.
* Copyright (C) 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
#include "memory.h"
#include "cipher.h"
#include "bithelp.h"
/* Table of CRCs of all 8-bit messages. Generated by running code
from RFC 1952 modified to print out the table. */
static u32 crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*
* The following function was extracted from RFC 1952 by Simon
* Josefsson, for the Shishi project, and modified to be compatible
* with the modified CRC-32 used by RFC 1510, and subsequently
* modified for GNU Libgcrypt to allow it to be used for calculating
* both unmodified CRC-32 and modified CRC-32 values. Original
* copyright and notice from the document follows:
*
* Copyright (c) 1996 L. Peter Deutsch
*
* Permission is granted to copy and distribute this document for
* any purpose and without charge, including translations into
* other languages and incorporation into compilations, provided
* that the copyright notice and this notice are preserved, and
* that any substantive changes or deletions from the original are
* clearly marked.
*
* The copyright on RFCs, and consequently the function below, are
* supposedly also retroactively claimed by the Internet Society
* (according to rfc-editor@rfc-editor.org), with the following
* copyright notice:
*
* Copyright (C) The Internet Society. All Rights Reserved.
*
* This document and translations of it may be copied and furnished
* to others, and derivative works that comment on or otherwise
* explain it or assist in its implementation may be prepared,
* copied, published and distributed, in whole or in part, without
* restriction of any kind, provided that the above copyright
* notice and this paragraph are included on all such copies and
* derivative works. However, this document itself may not be
* modified in any way, such as by removing the copyright notice or
* references to the Internet Society or other Internet
* organizations, except as needed for the purpose of developing
* Internet standards in which case the procedures for copyrights
* defined in the Internet Standards process must be followed, or
* as required to translate it into languages other than English.
*
* The limited permissions granted above are perpetual and will not be
* revoked by the Internet Society or its successors or assigns.
*
* This document and the information contained herein is provided
* on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
* ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
* OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
*/
static u32
update_crc32 (u32 crc, const void *buf_arg, size_t len)
{
const char *buf = buf_arg;
size_t n;
for (n = 0; n < len; n++)
crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8);
return crc;
}
typedef struct
{
u32 CRC;
byte buf[4];
}
CRC_CONTEXT;
/* CRC32 */
static void
crc32_init (void *context)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
ctx->CRC = 0 ^ 0xffffffffL;
}
static void
crc32_write (void *context, const void *inbuf, size_t inlen)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
if (!inbuf)
return;
ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen);
}
static byte *
crc32_read (void *context)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
return ctx->buf;
}
static void
crc32_final (void *context)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
ctx->CRC ^= 0xffffffffL;
ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
ctx->buf[2] = (ctx->CRC >> 8) & 0xFF;
ctx->buf[3] = (ctx->CRC ) & 0xFF;
}
/* CRC32 a'la RFC 1510 */
static void
crc32rfc1510_init (void *context)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
ctx->CRC = 0;
}
static void
crc32rfc1510_final (void *context)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
ctx->buf[2] = (ctx->CRC >> 8) & 0xFF;
ctx->buf[3] = (ctx->CRC ) & 0xFF;
}
/* CRC24 a'la RFC 2440 */
/*
* The following CRC 24 routines are adapted from RFC 2440, which has
* the following copyright notice:
*
* Copyright (C) The Internet Society (1998). All Rights Reserved.
*
* This document and translations of it may be copied and furnished
* to others, and derivative works that comment on or otherwise
* explain it or assist in its implementation may be prepared,
* copied, published and distributed, in whole or in part, without
* restriction of any kind, provided that the above copyright notice
* and this paragraph are included on all such copies and derivative
* works. However, this document itself may not be modified in any
* way, such as by removing the copyright notice or references to
* the Internet Society or other Internet organizations, except as
* needed for the purpose of developing Internet standards in which
* case the procedures for copyrights defined in the Internet
* Standards process must be followed, or as required to translate
* it into languages other than English.
*
* The limited permissions granted above are perpetual and will not be
* revoked by the Internet Society or its successors or assigns.
*
* This document and the information contained herein is provided on
* an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
* ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
* OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#define CRC24_INIT 0xb704ceL
#define CRC24_POLY 0x1864cfbL
static void
crc24rfc2440_init (void *context)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
ctx->CRC = CRC24_INIT;
}
static void
crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
{
const unsigned char *inbuf = inbuf_arg;
int i;
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
if (!inbuf)
return;
while (inlen--) {
ctx->CRC ^= (*inbuf++) << 16;
for (i = 0; i < 8; i++) {
ctx->CRC <<= 1;
if (ctx->CRC & 0x1000000)
ctx->CRC ^= CRC24_POLY;
}
}
}
static void
crc24rfc2440_final (void *context)
{
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
ctx->buf[0] = (ctx->CRC >> 16) & 0xFF;
ctx->buf[1] = (ctx->CRC >> 8) & 0xFF;
ctx->buf[2] = (ctx->CRC ) & 0xFF;
}
gcry_md_spec_t _gcry_digest_spec_crc32 =
{
"CRC32", NULL, 0, NULL, 4,
crc32_init, crc32_write, crc32_final, crc32_read,
sizeof (CRC_CONTEXT)
};
gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
{
"CRC32RFC1510", NULL, 0, NULL, 4,
crc32rfc1510_init, crc32_write,
crc32rfc1510_final, crc32_read,
sizeof (CRC_CONTEXT)
};
gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
{
"CRC24RFC2440", NULL, 0, NULL, 3,
crc24rfc2440_init, crc24rfc2440_write,
crc24rfc2440_final, crc32_read,
sizeof (CRC_CONTEXT)
};

1196
lib/libgcrypt/cipher/des.c Normal file

File diff suppressed because it is too large Load diff

1181
lib/libgcrypt/cipher/dsa.c Normal file

File diff suppressed because it is too large Load diff

1390
lib/libgcrypt/cipher/ecc.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,846 @@
/* Elgamal.c - Elgamal Public Key encryption
* Copyright (C) 1998, 2000, 2001, 2002, 2003,
* 2008 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
* ISBN 0-471-11709-9. Pages 476 ff.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
#include "mpi.h"
#include "cipher.h"
typedef struct
{
gcry_mpi_t p; /* prime */
gcry_mpi_t g; /* group generator */
gcry_mpi_t y; /* g^x mod p */
} ELG_public_key;
typedef struct
{
gcry_mpi_t p; /* prime */
gcry_mpi_t g; /* group generator */
gcry_mpi_t y; /* g^x mod p */
gcry_mpi_t x; /* secret exponent */
} ELG_secret_key;
static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors);
static int check_secret_key (ELG_secret_key *sk);
static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
ELG_public_key *pkey);
static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b,
ELG_secret_key *skey);
static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
ELG_secret_key *skey);
static int verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
ELG_public_key *pkey);
static void (*progress_cb) (void *, const char *, int, int, int);
static void *progress_cb_data;
void
_gcry_register_pk_elg_progress (void (*cb) (void *, const char *,
int, int, int),
void *cb_data)
{
progress_cb = cb;
progress_cb_data = cb_data;
}
static void
progress (int c)
{
if (progress_cb)
progress_cb (progress_cb_data, "pk_elg", c, 0, 0);
}
/****************
* Michael Wiener's table on subgroup sizes to match field sizes.
* (floating around somewhere, probably based on the paper from
* Eurocrypt 96, page 332)
*/
static unsigned int
wiener_map( unsigned int n )
{
static struct { unsigned int p_n, q_n; } t[] =
{ /* p q attack cost */
{ 512, 119 }, /* 9 x 10^17 */
{ 768, 145 }, /* 6 x 10^21 */
{ 1024, 165 }, /* 7 x 10^24 */
{ 1280, 183 }, /* 3 x 10^27 */
{ 1536, 198 }, /* 7 x 10^29 */
{ 1792, 212 }, /* 9 x 10^31 */
{ 2048, 225 }, /* 8 x 10^33 */
{ 2304, 237 }, /* 5 x 10^35 */
{ 2560, 249 }, /* 3 x 10^37 */
{ 2816, 259 }, /* 1 x 10^39 */
{ 3072, 269 }, /* 3 x 10^40 */
{ 3328, 279 }, /* 8 x 10^41 */
{ 3584, 288 }, /* 2 x 10^43 */
{ 3840, 296 }, /* 4 x 10^44 */
{ 4096, 305 }, /* 7 x 10^45 */
{ 4352, 313 }, /* 1 x 10^47 */
{ 4608, 320 }, /* 2 x 10^48 */
{ 4864, 328 }, /* 2 x 10^49 */
{ 5120, 335 }, /* 3 x 10^50 */
{ 0, 0 }
};
int i;
for(i=0; t[i].p_n; i++ )
{
if( n <= t[i].p_n )
return t[i].q_n;
}
/* Not in table - use an arbitrary high number. */
return n / 8 + 200;
}
static int
test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
{
ELG_public_key pk;
gcry_mpi_t test = gcry_mpi_new ( 0 );
gcry_mpi_t out1_a = gcry_mpi_new ( nbits );
gcry_mpi_t out1_b = gcry_mpi_new ( nbits );
gcry_mpi_t out2 = gcry_mpi_new ( nbits );
int failed = 0;
pk.p = sk->p;
pk.g = sk->g;
pk.y = sk->y;
gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
do_encrypt ( out1_a, out1_b, test, &pk );
decrypt ( out2, out1_a, out1_b, sk );
if ( mpi_cmp( test, out2 ) )
failed |= 1;
sign ( out1_a, out1_b, test, sk );
if ( !verify( out1_a, out1_b, test, &pk ) )
failed |= 2;
gcry_mpi_release ( test );
gcry_mpi_release ( out1_a );
gcry_mpi_release ( out1_b );
gcry_mpi_release ( out2 );
if (failed && !nodie)
log_fatal ("Elgamal test key for %s %s failed\n",
(failed & 1)? "encrypt+decrypt":"",
(failed & 2)? "sign+verify":"");
if (failed && DBG_CIPHER)
log_debug ("Elgamal test key for %s %s failed\n",
(failed & 1)? "encrypt+decrypt":"",
(failed & 2)? "sign+verify":"");
return failed;
}
/****************
* Generate a random secret exponent k from prime p, so that k is
* relatively prime to p-1. With SMALL_K set, k will be selected for
* better encryption performance - this must never be used signing!
*/
static gcry_mpi_t
gen_k( gcry_mpi_t p, int small_k )
{
gcry_mpi_t k = mpi_alloc_secure( 0 );
gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) );
gcry_mpi_t p_1 = mpi_copy(p);
unsigned int orig_nbits = mpi_get_nbits(p);
unsigned int nbits, nbytes;
char *rndbuf = NULL;
if (small_k)
{
/* Using a k much lesser than p is sufficient for encryption and
* it greatly improves the encryption performance. We use
* Wiener's table and add a large safety margin. */
nbits = wiener_map( orig_nbits ) * 3 / 2;
if( nbits >= orig_nbits )
BUG();
}
else
nbits = orig_nbits;
nbytes = (nbits+7)/8;
if( DBG_CIPHER )
log_debug("choosing a random k ");
mpi_sub_ui( p_1, p, 1);
for(;;)
{
if( !rndbuf || nbits < 32 )
{
gcry_free(rndbuf);
rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
}
else
{
/* Change only some of the higher bits. We could improve
this by directly requesting more memory at the first call
to get_random_bytes() and use this the here maybe it is
easier to do this directly in random.c Anyway, it is
highly inlikely that we will ever reach this code. */
char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
memcpy( rndbuf, pp, 4 );
gcry_free(pp);
}
_gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
for(;;)
{
if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */
{
if( DBG_CIPHER )
progress('+');
break; /* no */
}
if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
{
if( DBG_CIPHER )
progress('-');
break; /* no */
}
if (gcry_mpi_gcd( temp, k, p_1 ))
goto found; /* okay, k is relative prime to (p-1) */
mpi_add_ui( k, k, 1 );
if( DBG_CIPHER )
progress('.');
}
}
found:
gcry_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
mpi_free(p_1);
mpi_free(temp);
return k;
}
/****************
* Generate a key pair with a key of size NBITS
* Returns: 2 structures filled with all needed values
* and an array with n-1 factors of (p-1)
*/
static void
generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
{
gcry_mpi_t p; /* the prime */
gcry_mpi_t p_min1;
gcry_mpi_t g;
gcry_mpi_t x; /* the secret exponent */
gcry_mpi_t y;
unsigned int qbits;
unsigned int xbits;
byte *rndbuf;
p_min1 = gcry_mpi_new ( nbits );
qbits = wiener_map( nbits );
if( qbits & 1 ) /* better have a even one */
qbits++;
g = mpi_alloc(1);
p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors );
mpi_sub_ui(p_min1, p, 1);
/* Select a random number which has these properties:
* 0 < x < p-1
* This must be a very good random number because this is the
* secret part. The prime is public and may be shared anyway,
* so a random generator level of 1 is used for the prime.
*
* I don't see a reason to have a x of about the same size
* as the p. It should be sufficient to have one about the size
* of q or the later used k plus a large safety margin. Decryption
* will be much faster with such an x.
*/
xbits = qbits * 3 / 2;
if( xbits >= nbits )
BUG();
x = gcry_mpi_snew ( xbits );
if( DBG_CIPHER )
log_debug("choosing a random x of size %u", xbits );
rndbuf = NULL;
do
{
if( DBG_CIPHER )
progress('.');
if( rndbuf )
{ /* Change only some of the higher bits */
if( xbits < 16 ) /* should never happen ... */
{
gcry_free(rndbuf);
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
GCRY_VERY_STRONG_RANDOM );
}
else
{
char *r = gcry_random_bytes_secure( 2,
GCRY_VERY_STRONG_RANDOM );
memcpy(rndbuf, r, 2 );
gcry_free(r);
}
}
else
{
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
GCRY_VERY_STRONG_RANDOM );
}
_gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
mpi_clear_highbit( x, xbits+1 );
}
while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
gcry_free(rndbuf);
y = gcry_mpi_new (nbits);
gcry_mpi_powm( y, g, x, p );
if( DBG_CIPHER )
{
progress('\n');
log_mpidump("elg p= ", p );
log_mpidump("elg g= ", g );
log_mpidump("elg y= ", y );
log_mpidump("elg x= ", x );
}
/* Copy the stuff to the key structures */
sk->p = p;
sk->g = g;
sk->y = y;
sk->x = x;
gcry_mpi_release ( p_min1 );
/* Now we can test our keys (this should never fail!) */
test_keys ( sk, nbits - 64, 0 );
}
/* Generate a key pair with a key of size NBITS not using a random
value for the secret key but the one given as X. This is useful to
implement a passphrase based decryption for a public key based
encryption. It has appliactions in backup systems.
Returns: A structure filled with all needed values and an array
with n-1 factors of (p-1). */
static gcry_err_code_t
generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
gcry_mpi_t **ret_factors )
{
gcry_mpi_t p; /* The prime. */
gcry_mpi_t p_min1; /* The prime minus 1. */
gcry_mpi_t g; /* The generator. */
gcry_mpi_t y; /* g^x mod p. */
unsigned int qbits;
unsigned int xbits;
sk->p = NULL;
sk->g = NULL;
sk->y = NULL;
sk->x = NULL;
/* Do a quick check to see whether X is suitable. */
xbits = mpi_get_nbits (x);
if ( xbits < 64 || xbits >= nbits )
return GPG_ERR_INV_VALUE;
p_min1 = gcry_mpi_new ( nbits );
qbits = wiener_map ( nbits );
if ( (qbits & 1) ) /* Better have an even one. */
qbits++;
g = mpi_alloc (1);
p = _gcry_generate_elg_prime ( 0, nbits, qbits, g, ret_factors );
mpi_sub_ui (p_min1, p, 1);
if (DBG_CIPHER)
log_debug ("using a supplied x of size %u", xbits );
if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
{
gcry_mpi_release ( p_min1 );
gcry_mpi_release ( p );
gcry_mpi_release ( g );
return GPG_ERR_INV_VALUE;
}
y = gcry_mpi_new (nbits);
gcry_mpi_powm ( y, g, x, p );
if ( DBG_CIPHER )
{
progress ('\n');
log_mpidump ("elg p= ", p );
log_mpidump ("elg g= ", g );
log_mpidump ("elg y= ", y );
log_mpidump ("elg x= ", x );
}
/* Copy the stuff to the key structures */
sk->p = p;
sk->g = g;
sk->y = y;
sk->x = gcry_mpi_copy (x);
gcry_mpi_release ( p_min1 );
/* Now we can test our keys. */
if ( test_keys ( sk, nbits - 64, 1 ) )
{
gcry_mpi_release ( sk->p ); sk->p = NULL;
gcry_mpi_release ( sk->g ); sk->g = NULL;
gcry_mpi_release ( sk->y ); sk->y = NULL;
gcry_mpi_release ( sk->x ); sk->x = NULL;
return GPG_ERR_BAD_SECKEY;
}
return 0;
}
/****************
* Test whether the secret key is valid.
* Returns: if this is a valid key.
*/
static int
check_secret_key( ELG_secret_key *sk )
{
int rc;
gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
gcry_mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y );
mpi_free( y );
return rc;
}
static void
do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
{
gcry_mpi_t k;
/* Note: maybe we should change the interface, so that it
* is possible to check that input is < p and return an
* error code.
*/
k = gen_k( pkey->p, 1 );
gcry_mpi_powm( a, pkey->g, k, pkey->p );
/* b = (y^k * input) mod p
* = ((y^k mod p) * (input mod p)) mod p
* and because input is < p
* = ((y^k mod p) * input) mod p
*/
gcry_mpi_powm( b, pkey->y, k, pkey->p );
gcry_mpi_mulm( b, b, input, pkey->p );
#if 0
if( DBG_CIPHER )
{
log_mpidump("elg encrypted y= ", pkey->y);
log_mpidump("elg encrypted p= ", pkey->p);
log_mpidump("elg encrypted k= ", k);
log_mpidump("elg encrypted M= ", input);
log_mpidump("elg encrypted a= ", a);
log_mpidump("elg encrypted b= ", b);
}
#endif
mpi_free(k);
}
static void
decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
{
gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
/* output = b/(a^x) mod p */
gcry_mpi_powm( t1, a, skey->x, skey->p );
mpi_invm( t1, t1, skey->p );
mpi_mulm( output, b, t1, skey->p );
#if 0
if( DBG_CIPHER )
{
log_mpidump("elg decrypted x= ", skey->x);
log_mpidump("elg decrypted p= ", skey->p);
log_mpidump("elg decrypted a= ", a);
log_mpidump("elg decrypted b= ", b);
log_mpidump("elg decrypted M= ", output);
}
#endif
mpi_free(t1);
}
/****************
* Make an Elgamal signature out of INPUT
*/
static void
sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
{
gcry_mpi_t k;
gcry_mpi_t t = mpi_alloc( mpi_get_nlimbs(a) );
gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
gcry_mpi_t p_1 = mpi_copy(skey->p);
/*
* b = (t * inv) mod (p-1)
* b = (t * inv(k,(p-1),(p-1)) mod (p-1)
* b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
*
*/
mpi_sub_ui(p_1, p_1, 1);
k = gen_k( skey->p, 0 /* no small K ! */ );
gcry_mpi_powm( a, skey->g, k, skey->p );
mpi_mul(t, skey->x, a );
mpi_subm(t, input, t, p_1 );
mpi_invm(inv, k, p_1 );
mpi_mulm(b, t, inv, p_1 );
#if 0
if( DBG_CIPHER )
{
log_mpidump("elg sign p= ", skey->p);
log_mpidump("elg sign g= ", skey->g);
log_mpidump("elg sign y= ", skey->y);
log_mpidump("elg sign x= ", skey->x);
log_mpidump("elg sign k= ", k);
log_mpidump("elg sign M= ", input);
log_mpidump("elg sign a= ", a);
log_mpidump("elg sign b= ", b);
}
#endif
mpi_free(k);
mpi_free(t);
mpi_free(inv);
mpi_free(p_1);
}
/****************
* Returns true if the signature composed of A and B is valid.
*/
static int
verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
{
int rc;
gcry_mpi_t t1;
gcry_mpi_t t2;
gcry_mpi_t base[4];
gcry_mpi_t ex[4];
if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
return 0; /* assertion 0 < a < p failed */
t1 = mpi_alloc( mpi_get_nlimbs(a) );
t2 = mpi_alloc( mpi_get_nlimbs(a) );
#if 0
/* t1 = (y^a mod p) * (a^b mod p) mod p */
gcry_mpi_powm( t1, pkey->y, a, pkey->p );
gcry_mpi_powm( t2, a, b, pkey->p );
mpi_mulm( t1, t1, t2, pkey->p );
/* t2 = g ^ input mod p */
gcry_mpi_powm( t2, pkey->g, input, pkey->p );
rc = !mpi_cmp( t1, t2 );
#elif 0
/* t1 = (y^a mod p) * (a^b mod p) mod p */
base[0] = pkey->y; ex[0] = a;
base[1] = a; ex[1] = b;
base[2] = NULL; ex[2] = NULL;
mpi_mulpowm( t1, base, ex, pkey->p );
/* t2 = g ^ input mod p */
gcry_mpi_powm( t2, pkey->g, input, pkey->p );
rc = !mpi_cmp( t1, t2 );
#else
/* t1 = g ^ - input * y ^ a * a ^ b mod p */
mpi_invm(t2, pkey->g, pkey->p );
base[0] = t2 ; ex[0] = input;
base[1] = pkey->y; ex[1] = a;
base[2] = a; ex[2] = b;
base[3] = NULL; ex[3] = NULL;
mpi_mulpowm( t1, base, ex, pkey->p );
rc = !mpi_cmp_ui( t1, 1 );
#endif
mpi_free(t1);
mpi_free(t2);
return rc;
}
/*********************************************
************** interface ******************
*********************************************/
static gpg_err_code_t
elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
const gcry_sexp_t genparms,
gcry_mpi_t *skey, gcry_mpi_t **retfactors,
gcry_sexp_t *r_extrainfo)
{
gpg_err_code_t ec;
ELG_secret_key sk;
gcry_mpi_t xvalue = NULL;
gcry_sexp_t l1;
(void)algo;
(void)evalue;
(void)r_extrainfo;
if (genparms)
{
/* Parse the optional xvalue element. */
l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
if (l1)
{
xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
gcry_sexp_release (l1);
if (!xvalue)
return GPG_ERR_BAD_MPI;
}
}
if (xvalue)
ec = generate_using_x (&sk, nbits, xvalue, retfactors);
else
{
generate (&sk, nbits, retfactors);
ec = 0;
}
skey[0] = sk.p;
skey[1] = sk.g;
skey[2] = sk.y;
skey[3] = sk.x;
return ec;
}
static gcry_err_code_t
elg_generate (int algo, unsigned int nbits, unsigned long evalue,
gcry_mpi_t *skey, gcry_mpi_t **retfactors)
{
ELG_secret_key sk;
(void)algo;
(void)evalue;
generate (&sk, nbits, retfactors);
skey[0] = sk.p;
skey[1] = sk.g;
skey[2] = sk.y;
skey[3] = sk.x;
return GPG_ERR_NO_ERROR;
}
static gcry_err_code_t
elg_check_secret_key (int algo, gcry_mpi_t *skey)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
ELG_secret_key sk;
(void)algo;
if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
err = GPG_ERR_BAD_MPI;
else
{
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
if (! check_secret_key (&sk))
err = GPG_ERR_BAD_SECKEY;
}
return err;
}
static gcry_err_code_t
elg_encrypt (int algo, gcry_mpi_t *resarr,
gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
ELG_public_key pk;
(void)algo;
(void)flags;
if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
err = GPG_ERR_BAD_MPI;
else
{
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.p));
resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.p));
do_encrypt (resarr[0], resarr[1], data, &pk);
}
return err;
}
static gcry_err_code_t
elg_decrypt (int algo, gcry_mpi_t *result,
gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
ELG_secret_key sk;
(void)algo;
(void)flags;
if ((! data[0]) || (! data[1])
|| (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
err = GPG_ERR_BAD_MPI;
else
{
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
*result = mpi_alloc_secure (mpi_get_nlimbs (sk.p));
decrypt (*result, data[0], data[1], &sk);
}
return err;
}
static gcry_err_code_t
elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
ELG_secret_key sk;
(void)algo;
if ((! data)
|| (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
err = GPG_ERR_BAD_MPI;
else
{
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
sign (resarr[0], resarr[1], data, &sk);
}
return err;
}
static gcry_err_code_t
elg_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
int (*cmp) (void *, gcry_mpi_t), void *opaquev)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
ELG_public_key pk;
(void)algo;
(void)cmp;
(void)opaquev;
if ((! data[0]) || (! data[1]) || (! hash)
|| (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
err = GPG_ERR_BAD_MPI;
else
{
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
if (! verify (data[0], data[1], hash, &pk))
err = GPG_ERR_BAD_SIGNATURE;
}
return err;
}
static unsigned int
elg_get_nbits (int algo, gcry_mpi_t *pkey)
{
(void)algo;
return mpi_get_nbits (pkey[0]);
}
static const char *elg_names[] =
{
"elg",
"openpgp-elg",
"openpgp-elg-sig",
NULL,
};
gcry_pk_spec_t _gcry_pubkey_spec_elg =
{
"ELG", elg_names,
"pgy", "pgyx", "ab", "rs", "pgy",
GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
elg_generate,
elg_check_secret_key,
elg_encrypt,
elg_decrypt,
elg_sign,
elg_verify,
elg_get_nbits
};
pk_extra_spec_t _gcry_pubkey_extraspec_elg =
{
NULL,
elg_generate_ext,
NULL
};

View file

@ -0,0 +1,94 @@
/* hash-common.c - Common code for hash algorithms
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include "g10lib.h"
#include "hash-common.h"
/* Run a selftest for hash algorithm ALGO. If the resulting digest
matches EXPECT/EXPECTLEN and everything else is fine as well,
return NULL. If an error occurs, return a static text string
describing the error.
DATAMODE controls what will be hashed according to this table:
0 - Hash the supplied DATA of DATALEN.
1 - Hash one million times a 'a'. DATA and DATALEN are ignored.
*/
const char *
_gcry_hash_selftest_check_one (int algo,
int datamode, const void *data, size_t datalen,
const void *expect, size_t expectlen)
{
const char *result = NULL;
gcry_error_t err = 0;
gcry_md_hd_t hd;
unsigned char *digest;
if (_gcry_md_get_algo_dlen (algo) != expectlen)
return "digest size does not match expected size";
err = _gcry_md_open (&hd, algo, 0);
if (err)
return "gcry_md_open failed";
switch (datamode)
{
case 0:
_gcry_md_write (hd, data, datalen);
break;
case 1: /* Hash one million times an "a". */
{
char aaa[1000];
int i;
/* Write in odd size chunks so that we test the buffering. */
memset (aaa, 'a', 1000);
for (i = 0; i < 1000; i++)
_gcry_md_write (hd, aaa, 1000);
}
break;
default:
result = "invalid DATAMODE";
}
if (!result)
{
digest = _gcry_md_read (hd, algo);
if ( memcmp (digest, expect, expectlen) )
result = "digest mismatch";
}
_gcry_md_close (hd);
return result;
}

View file

@ -0,0 +1,33 @@
/* hash-common.h - Declarations of common code for hash algorithms.
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GCRY_HASH_COMMON_H
#define GCRY_HASH_COMMON_H
const char * _gcry_hash_selftest_check_one
/**/ (int algo,
int datamode, const void *data, size_t datalen,
const void *expect, size_t expectlen);
#endif /*GCRY_HASH_COMMON_H*/

View file

@ -0,0 +1,732 @@
/* hmac-tests.c - HMAC selftests.
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
Although algorithm self-tests are usually implemented in the module
implementing the algorithm, the case for HMAC is different because
HMAC is implemnetd on a higher level using a special feature of the
gcry_md_ functions. It would be possible to do this also in the
digest algorithm modules, but that would blow up the code too much
and spread the hmac tests over several modules.
Thus we implement all HMAC tests in this test module and provide a
function to run the tests.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include "g10lib.h"
#include "cipher.h"
#include "hmac256.h"
/* Check one HMAC with digest ALGO using the regualr HAMC
API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
and (EXPECT,EXPECTLEN) the expected result. Returns NULL on
succdess or a string describing the failure. */
static const char *
check_one (int algo,
const void *data, size_t datalen,
const void *key, size_t keylen,
const void *expect, size_t expectlen)
{
gcry_md_hd_t hd;
const unsigned char *digest;
/* printf ("HMAC algo %d\n", algo); */
if (_gcry_md_get_algo_dlen (algo) != expectlen)
return "invalid tests data";
if (_gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC))
return "gcry_md_open failed";
if (_gcry_md_setkey (hd, key, keylen))
{
_gcry_md_close (hd);
return "gcry_md_setkey failed";
}
_gcry_md_write (hd, data, datalen);
digest = _gcry_md_read (hd, algo);
if (!digest)
{
_gcry_md_close (hd);
return "gcry_md_read failed";
}
if (memcmp (digest, expect, expectlen))
{
/* int i; */
/* fputs (" {", stdout); */
/* for (i=0; i < expectlen-1; i++) */
/* { */
/* if (i && !(i % 8)) */
/* fputs ("\n ", stdout); */
/* printf (" 0x%02x,", digest[i]); */
/* } */
/* printf (" 0x%02x } },\n", digest[i]); */
_gcry_md_close (hd);
return "does not match";
}
_gcry_md_close (hd);
return NULL;
}
static gpg_err_code_t
selftests_sha1 (int extended, selftest_report_func_t report)
{
const char *what;
const char *errtxt;
unsigned char key[128];
int i, j;
what = "FIPS-198a, A.1";
for (i=0; i < 64; i++)
key[i] = i;
errtxt = check_one (GCRY_MD_SHA1,
"Sample #1", 9,
key, 64,
"\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
"\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a", 20);
if (errtxt)
goto failed;
if (extended)
{
what = "FIPS-198a, A.2";
for (i=0, j=0x30; i < 20; i++)
key[i] = j++;
errtxt = check_one (GCRY_MD_SHA1,
"Sample #2", 9,
key, 20,
"\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
"\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20);
if (errtxt)
goto failed;
what = "FIPS-198a, A.3";
for (i=0, j=0x50; i < 100; i++)
key[i] = j++;
errtxt = check_one (GCRY_MD_SHA1,
"Sample #3", 9,
key, 100,
"\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
"\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 );
if (errtxt)
goto failed;
what = "FIPS-198a, A.4";
for (i=0, j=0x70; i < 49; i++)
key[i] = j++;
errtxt = check_one (GCRY_MD_SHA1,
"Sample #4", 9,
key, 49,
"\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
"\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 );
if (errtxt)
goto failed;
}
return 0; /* Succeeded. */
failed:
if (report)
report ("hmac", GCRY_MD_SHA1, what, errtxt);
return GPG_ERR_SELFTEST_FAILED;
}
static gpg_err_code_t
selftests_sha224 (int extended, selftest_report_func_t report)
{
static struct
{
const char * const desc;
const char * const data;
const char * const key;
const char expect[28];
} tv[] =
{
{ "data-28 key-4",
"what do ya want for nothing?",
"Jefe",
{ 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00,
0x8f, 0xd0, 0x5e, 0x44 } },
{ "data-9 key-20",
"Hi There",
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b",
{ 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
0x53, 0x68, 0x4b, 0x22 } },
{ "data-50 key-20",
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa",
{ 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6,
0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64,
0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1,
0xec, 0x83, 0x33, 0xea } },
{ "data-50 key-26",
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd",
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
{ 0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac,
0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82, 0x62, 0x7c,
0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d,
0xe7, 0xaf, 0xec, 0x5a } },
{ "data-54 key-131",
"Test Using Larger Than Block-Size Key - Hash Key First",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad,
0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2,
0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27,
0x3f, 0xa6, 0x87, 0x0e } },
{ "data-152 key-131",
"This is a test using a larger than block-size key and a larger "
"than block-size data. The key needs to be hashed before being "
"used by the HMAC algorithm.",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02,
0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd,
0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9,
0xf6, 0xf5, 0x65, 0xd1 } },
{ NULL }
};
const char *what;
const char *errtxt;
int tvidx;
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
what = tv[tvidx].desc;
errtxt = check_one (GCRY_MD_SHA224,
tv[tvidx].data, strlen (tv[tvidx].data),
tv[tvidx].key, strlen (tv[tvidx].key),
tv[tvidx].expect, DIM (tv[tvidx].expect) );
if (errtxt)
goto failed;
if (!extended)
break;
}
return 0; /* Succeeded. */
failed:
if (report)
report ("hmac", GCRY_MD_SHA224, what, errtxt);
return GPG_ERR_SELFTEST_FAILED;
}
static gpg_err_code_t
selftests_sha256 (int extended, selftest_report_func_t report)
{
static struct
{
const char * const desc;
const char * const data;
const char * const key;
const char expect[32];
} tv[] =
{
{ "data-28 key-4",
"what do ya want for nothing?",
"Jefe",
{ 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
{ "data-9 key-20",
"Hi There",
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b",
{ 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
{ "data-50 key-20",
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa",
{ 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
{ "data-50 key-26",
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd",
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
{ 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
{ "data-54 key-131",
"Test Using Larger Than Block-Size Key - Hash Key First",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
{ "data-152 key-131",
"This is a test using a larger than block-size key and a larger "
"than block-size data. The key needs to be hashed before being "
"used by the HMAC algorithm.",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
{ NULL }
};
const char *what;
const char *errtxt;
int tvidx;
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
hmac256_context_t hmachd;
const unsigned char *digest;
size_t dlen;
what = tv[tvidx].desc;
errtxt = check_one (GCRY_MD_SHA256,
tv[tvidx].data, strlen (tv[tvidx].data),
tv[tvidx].key, strlen (tv[tvidx].key),
tv[tvidx].expect, DIM (tv[tvidx].expect) );
if (errtxt)
goto failed;
hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
if (!hmachd)
{
errtxt = "_gcry_hmac256_new failed";
goto failed;
}
_gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
digest = _gcry_hmac256_finalize (hmachd, &dlen);
if (!digest)
{
errtxt = "_gcry_hmac256_finalize failed";
_gcry_hmac256_release (hmachd);
goto failed;
}
if (dlen != DIM (tv[tvidx].expect)
|| memcmp (digest, tv[tvidx].expect, DIM (tv[tvidx].expect)))
{
errtxt = "does not match in second implementation";
_gcry_hmac256_release (hmachd);
goto failed;
}
_gcry_hmac256_release (hmachd);
if (!extended)
break;
}
return 0; /* Succeeded. */
failed:
if (report)
report ("hmac", GCRY_MD_SHA256, what, errtxt);
return GPG_ERR_SELFTEST_FAILED;
}
static gpg_err_code_t
selftests_sha384 (int extended, selftest_report_func_t report)
{
static struct
{
const char * const desc;
const char * const data;
const char * const key;
const char expect[48];
} tv[] =
{
{ "data-28 key-4",
"what do ya want for nothing?",
"Jefe",
{ 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 } },
{ "data-9 key-20",
"Hi There",
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b",
{ 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 } },
{ "data-50 key-20",
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa",
{ 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 } },
{ "data-50 key-26",
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd",
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
{ 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb } },
{ "data-54 key-131",
"Test Using Larger Than Block-Size Key - Hash Key First",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 } },
{ "data-152 key-131",
"This is a test using a larger than block-size key and a larger "
"than block-size data. The key needs to be hashed before being "
"used by the HMAC algorithm.",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e } },
{ NULL }
};
const char *what;
const char *errtxt;
int tvidx;
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
what = tv[tvidx].desc;
errtxt = check_one (GCRY_MD_SHA384,
tv[tvidx].data, strlen (tv[tvidx].data),
tv[tvidx].key, strlen (tv[tvidx].key),
tv[tvidx].expect, DIM (tv[tvidx].expect) );
if (errtxt)
goto failed;
if (!extended)
break;
}
return 0; /* Succeeded. */
failed:
if (report)
report ("hmac", GCRY_MD_SHA384, what, errtxt);
return GPG_ERR_SELFTEST_FAILED;
}
static gpg_err_code_t
selftests_sha512 (int extended, selftest_report_func_t report)
{
static struct
{
const char * const desc;
const char * const data;
const char * const key;
const char expect[64];
} tv[] =
{
{ "data-28 key-4",
"what do ya want for nothing?",
"Jefe",
{ 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 } },
{ "data-9 key-20",
"Hi There",
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b",
{ 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 } },
{ "data-50 key-20",
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa",
{ 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb } },
{ "data-50 key-26",
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd",
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
{ 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd } },
{ "data-54 key-131",
"Test Using Larger Than Block-Size Key - Hash Key First",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 } },
{ "data-152 key-131",
"This is a test using a larger than block-size key and a larger "
"than block-size data. The key needs to be hashed before being "
"used by the HMAC algorithm.",
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa",
{ 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 } },
{ NULL }
};
const char *what;
const char *errtxt;
int tvidx;
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
what = tv[tvidx].desc;
errtxt = check_one (GCRY_MD_SHA512,
tv[tvidx].data, strlen (tv[tvidx].data),
tv[tvidx].key, strlen (tv[tvidx].key),
tv[tvidx].expect, DIM (tv[tvidx].expect) );
if (errtxt)
goto failed;
if (!extended)
break;
}
return 0; /* Succeeded. */
failed:
if (report)
report ("hmac", GCRY_MD_SHA512, what, errtxt);
return GPG_ERR_SELFTEST_FAILED;
}
/* Run a full self-test for ALGO and return 0 on success. */
static gpg_err_code_t
run_selftests (int algo, int extended, selftest_report_func_t report)
{
gpg_err_code_t ec;
switch (algo)
{
case GCRY_MD_SHA1:
ec = selftests_sha1 (extended, report);
break;
case GCRY_MD_SHA224:
ec = selftests_sha224 (extended, report);
break;
case GCRY_MD_SHA256:
ec = selftests_sha256 (extended, report);
break;
case GCRY_MD_SHA384:
ec = selftests_sha384 (extended, report);
break;
case GCRY_MD_SHA512:
ec = selftests_sha512 (extended, report);
break;
default:
ec = GPG_ERR_DIGEST_ALGO;
break;
}
return ec;
}
/* Run the selftests for HMAC with digest algorithm ALGO with optional
reporting function REPORT. */
gpg_error_t
_gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report)
{
gcry_err_code_t ec = 0;
if (!gcry_md_test_algo (algo))
{
ec = run_selftests (algo, extended, report);
}
else
{
ec = GPG_ERR_DIGEST_ALGO;
if (report)
report ("hmac", algo, "module", "algorithm not available");
}
return gpg_error (ec);
}

1375
lib/libgcrypt/cipher/md.c Normal file

File diff suppressed because it is too large Load diff

328
lib/libgcrypt/cipher/md4.c Normal file
View file

@ -0,0 +1,328 @@
/* md4.c - MD4 Message-Digest Algorithm
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Based on md5.c in libgcrypt, but rewritten to compute md4 checksums
* using a public domain md4 implementation with the following comments:
*
* Modified by Wei Dai from Andrew M. Kuchling's md4.c
* The original code and all modifications are in the public domain.
*
* This is the original introductory comment:
*
* md4.c : MD4 hash algorithm.
*
* Part of the Python Cryptography Toolkit, version 1.1
*
* Distribute and use freely; there are no restrictions on further
* dissemination and usage except those imposed by the laws of your
* country of residence.
*
*/
/* MD4 test suite:
* MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
* MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
* MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
* MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
* MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
* MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
* 043f8582f241db351ce627e153e7f0e4
* MD4 ("123456789012345678901234567890123456789012345678901234567890123456
* 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
#include "memory.h"
#include "cipher.h"
#include "bithelp.h"
typedef struct {
u32 A,B,C,D; /* chaining variables */
u32 nblocks;
byte buf[64];
int count;
} MD4_CONTEXT;
static void
md4_init( void *context )
{
MD4_CONTEXT *ctx = context;
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
ctx->nblocks = 0;
ctx->count = 0;
}
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
/****************
* transform 64 bytes
*/
static void
transform ( MD4_CONTEXT *ctx, const unsigned char *data )
{
u32 in[16];
register u32 A = ctx->A;
register u32 B = ctx->B;
register u32 C = ctx->C;
register u32 D = ctx->D;
#ifdef WORDS_BIGENDIAN
{
int i;
byte *p2, *p1;
for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 )
{
p2[3] = *p1++;
p2[2] = *p1++;
p2[1] = *p1++;
p2[0] = *p1++;
}
}
#else
memcpy (in, data, 64);
#endif
/* Round 1. */
#define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
function(A,B,C,D, 0, 3);
function(D,A,B,C, 1, 7);
function(C,D,A,B, 2,11);
function(B,C,D,A, 3,19);
function(A,B,C,D, 4, 3);
function(D,A,B,C, 5, 7);
function(C,D,A,B, 6,11);
function(B,C,D,A, 7,19);
function(A,B,C,D, 8, 3);
function(D,A,B,C, 9, 7);
function(C,D,A,B,10,11);
function(B,C,D,A,11,19);
function(A,B,C,D,12, 3);
function(D,A,B,C,13, 7);
function(C,D,A,B,14,11);
function(B,C,D,A,15,19);
#undef function
/* Round 2. */
#define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
function(A,B,C,D, 0, 3);
function(D,A,B,C, 4, 5);
function(C,D,A,B, 8, 9);
function(B,C,D,A,12,13);
function(A,B,C,D, 1, 3);
function(D,A,B,C, 5, 5);
function(C,D,A,B, 9, 9);
function(B,C,D,A,13,13);
function(A,B,C,D, 2, 3);
function(D,A,B,C, 6, 5);
function(C,D,A,B,10, 9);
function(B,C,D,A,14,13);
function(A,B,C,D, 3, 3);
function(D,A,B,C, 7, 5);
function(C,D,A,B,11, 9);
function(B,C,D,A,15,13);
#undef function
/* Round 3. */
#define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
function(A,B,C,D, 0, 3);
function(D,A,B,C, 8, 9);
function(C,D,A,B, 4,11);
function(B,C,D,A,12,15);
function(A,B,C,D, 2, 3);
function(D,A,B,C,10, 9);
function(C,D,A,B, 6,11);
function(B,C,D,A,14,15);
function(A,B,C,D, 1, 3);
function(D,A,B,C, 9, 9);
function(C,D,A,B, 5,11);
function(B,C,D,A,13,15);
function(A,B,C,D, 3, 3);
function(D,A,B,C,11, 9);
function(C,D,A,B, 7,11);
function(B,C,D,A,15,15);
/* Put checksum in context given as argument. */
ctx->A += A;
ctx->B += B;
ctx->C += C;
ctx->D += D;
}
/* The routine updates the message-digest context to
* account for the presence of each of the characters inBuf[0..inLen-1]
* in the message whose digest is being computed.
*/
static void
md4_write ( void *context, const void *inbuf_arg, size_t inlen)
{
const unsigned char *inbuf = inbuf_arg;
MD4_CONTEXT *hd = context;
if( hd->count == 64 ) /* flush the buffer */
{
transform( hd, hd->buf );
_gcry_burn_stack (80+6*sizeof(void*));
hd->count = 0;
hd->nblocks++;
}
if( !inbuf )
return;
if( hd->count )
{
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
md4_write( hd, NULL, 0 );
if( !inlen )
return;
}
_gcry_burn_stack (80+6*sizeof(void*));
while( inlen >= 64 )
{
transform( hd, inbuf );
hd->count = 0;
hd->nblocks++;
inlen -= 64;
inbuf += 64;
}
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
}
/* The routine final terminates the message-digest computation and
* ends with the desired message digest in mdContext->digest[0...15].
* The handle is prepared for a new MD4 cycle.
* Returns 16 bytes representing the digest.
*/
static void
md4_final( void *context )
{
MD4_CONTEXT *hd = context;
u32 t, msb, lsb;
byte *p;
md4_write(hd, NULL, 0); /* flush */;
t = hd->nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
if( (lsb += hd->count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
lsb <<= 3;
msb <<= 3;
msb |= t >> 29;
if( hd->count < 56 ) /* enough room */
{
hd->buf[hd->count++] = 0x80; /* pad */
while( hd->count < 56 )
hd->buf[hd->count++] = 0; /* pad */
}
else /* need one extra block */
{
hd->buf[hd->count++] = 0x80; /* pad character */
while( hd->count < 64 )
hd->buf[hd->count++] = 0;
md4_write(hd, NULL, 0); /* flush */;
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
hd->buf[56] = lsb ;
hd->buf[57] = lsb >> 8;
hd->buf[58] = lsb >> 16;
hd->buf[59] = lsb >> 24;
hd->buf[60] = msb ;
hd->buf[61] = msb >> 8;
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform( hd, hd->buf );
_gcry_burn_stack (80+6*sizeof(void*));
p = hd->buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
*p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
#else /* little endian */
#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
#endif
X(A);
X(B);
X(C);
X(D);
#undef X
}
static byte *
md4_read (void *context)
{
MD4_CONTEXT *hd = context;
return hd->buf;
}
static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
static gcry_md_oid_spec_t oid_spec_md4[] =
{
/* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
{ "1.2.840.113549.2.4" },
{ NULL },
};
gcry_md_spec_t _gcry_digest_spec_md4 =
{
"MD4", asn, DIM (asn), oid_spec_md4,16,
md4_init, md4_write, md4_final, md4_read,
sizeof (MD4_CONTEXT)
};

355
lib/libgcrypt/cipher/md5.c Normal file
View file

@ -0,0 +1,355 @@
/* md5.c - MD5 Message-Digest Algorithm
* Copyright (C) 1995,1996,1998,1999,2001,2002,
* 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* According to the definition of MD5 in RFC 1321 from April 1992.
* NOTE: This is *not* the same file as the one from glibc.
* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
* heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
*/
/* Test values:
* "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
* "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
* "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
* "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
#include "memory.h"
#include "cipher.h"
#include "bithelp.h"
typedef struct {
u32 A,B,C,D; /* chaining variables */
u32 nblocks;
byte buf[64];
int count;
} MD5_CONTEXT;
static void
md5_init( void *context )
{
MD5_CONTEXT *ctx = context;
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
ctx->nblocks = 0;
ctx->count = 0;
}
/* These are the four functions used in the four steps of the MD5 algorithm
and defined in the RFC 1321. The first function is a little bit optimized
(as found in Colin Plumbs public domain implementation). */
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
#define FF(b, c, d) (d ^ (b & (c ^ d)))
#define FG(b, c, d) FF (d, b, c)
#define FH(b, c, d) (b ^ c ^ d)
#define FI(b, c, d) (c ^ (b | ~d))
/****************
* transform n*64 bytes
*/
static void
transform ( MD5_CONTEXT *ctx, const unsigned char *data )
{
u32 correct_words[16];
register u32 A = ctx->A;
register u32 B = ctx->B;
register u32 C = ctx->C;
register u32 D = ctx->D;
u32 *cwp = correct_words;
#ifdef WORDS_BIGENDIAN
{
int i;
byte *p2, *p1;
for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 )
{
p2[3] = *p1++;
p2[2] = *p1++;
p2[1] = *p1++;
p2[0] = *p1++;
}
}
#else
memcpy( correct_words, data, 64 );
#endif
#define OP(a, b, c, d, s, T) \
do \
{ \
a += FF (b, c, d) + (*cwp++) + T; \
a = rol(a, s); \
a += b; \
} \
while (0)
/* Before we start, one word about the strange constants.
They are defined in RFC 1321 as
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/
/* Round 1. */
OP (A, B, C, D, 7, 0xd76aa478);
OP (D, A, B, C, 12, 0xe8c7b756);
OP (C, D, A, B, 17, 0x242070db);
OP (B, C, D, A, 22, 0xc1bdceee);
OP (A, B, C, D, 7, 0xf57c0faf);
OP (D, A, B, C, 12, 0x4787c62a);
OP (C, D, A, B, 17, 0xa8304613);
OP (B, C, D, A, 22, 0xfd469501);
OP (A, B, C, D, 7, 0x698098d8);
OP (D, A, B, C, 12, 0x8b44f7af);
OP (C, D, A, B, 17, 0xffff5bb1);
OP (B, C, D, A, 22, 0x895cd7be);
OP (A, B, C, D, 7, 0x6b901122);
OP (D, A, B, C, 12, 0xfd987193);
OP (C, D, A, B, 17, 0xa679438e);
OP (B, C, D, A, 22, 0x49b40821);
#undef OP
#define OP(f, a, b, c, d, k, s, T) \
do \
{ \
a += f (b, c, d) + correct_words[k] + T; \
a = rol(a, s); \
a += b; \
} \
while (0)
/* Round 2. */
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
OP (FG, D, A, B, C, 10, 9, 0x02441453);
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
/* Round 3. */
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
/* Round 4. */
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
/* Put checksum in context given as argument. */
ctx->A += A;
ctx->B += B;
ctx->C += C;
ctx->D += D;
}
/* The routine updates the message-digest context to
* account for the presence of each of the characters inBuf[0..inLen-1]
* in the message whose digest is being computed.
*/
static void
md5_write( void *context, const void *inbuf_arg , size_t inlen)
{
const unsigned char *inbuf = inbuf_arg;
MD5_CONTEXT *hd = context;
if( hd->count == 64 ) /* flush the buffer */
{
transform( hd, hd->buf );
_gcry_burn_stack (80+6*sizeof(void*));
hd->count = 0;
hd->nblocks++;
}
if( !inbuf )
return;
if( hd->count )
{
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
md5_write( hd, NULL, 0 );
if( !inlen )
return;
}
_gcry_burn_stack (80+6*sizeof(void*));
while( inlen >= 64 )
{
transform( hd, inbuf );
hd->count = 0;
hd->nblocks++;
inlen -= 64;
inbuf += 64;
}
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
}
/* The routine final terminates the message-digest computation and
* ends with the desired message digest in mdContext->digest[0...15].
* The handle is prepared for a new MD5 cycle.
* Returns 16 bytes representing the digest.
*/
static void
md5_final( void *context)
{
MD5_CONTEXT *hd = context;
u32 t, msb, lsb;
byte *p;
md5_write(hd, NULL, 0); /* flush */;
t = hd->nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
if( (lsb += hd->count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
lsb <<= 3;
msb <<= 3;
msb |= t >> 29;
if( hd->count < 56 ) /* enough room */
{
hd->buf[hd->count++] = 0x80; /* pad */
while( hd->count < 56 )
hd->buf[hd->count++] = 0; /* pad */
}
else /* need one extra block */
{
hd->buf[hd->count++] = 0x80; /* pad character */
while( hd->count < 64 )
hd->buf[hd->count++] = 0;
md5_write(hd, NULL, 0); /* flush */;
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
hd->buf[56] = lsb ;
hd->buf[57] = lsb >> 8;
hd->buf[58] = lsb >> 16;
hd->buf[59] = lsb >> 24;
hd->buf[60] = msb ;
hd->buf[61] = msb >> 8;
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform( hd, hd->buf );
_gcry_burn_stack (80+6*sizeof(void*));
p = hd->buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
*p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
#else /* little endian */
#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
#endif
X(A);
X(B);
X(C);
X(D);
#undef X
}
static byte *
md5_read( void *context )
{
MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
return hd->buf;
}
static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
static gcry_md_oid_spec_t oid_spec_md5[] =
{
/* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */
{ "1.2.840.113549.1.1.4" },
/* RSADSI digestAlgorithm MD5 */
{ "1.2.840.113549.2.5" },
{ NULL },
};
gcry_md_spec_t _gcry_digest_spec_md5 =
{
"MD5", asn, DIM (asn), oid_spec_md5, 16,
md5_init, md5_write, md5_final, md5_read,
sizeof (MD5_CONTEXT)
};

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,345 @@
/* rfc2268.c - The cipher described in rfc2268; aka Ron's Cipher 2.
* Copyright (C) 2003 Nikos Mavroyanopoulos
* Copyright (C) 2004 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
* as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
* direct use by Libgcrypt by Werner Koch. This implementation is
* only useful for pkcs#12 descryption.
*
* The implementation here is based on Peter Gutmann's RRC.2 paper.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
#include "types.h"
#include "cipher.h"
#define RFC2268_BLOCKSIZE 8
typedef struct
{
u16 S[64];
} RFC2268_context;
static const unsigned char rfc2268_sbox[] = {
217, 120, 249, 196, 25, 221, 181, 237,
40, 233, 253, 121, 74, 160, 216, 157,
198, 126, 55, 131, 43, 118, 83, 142,
98, 76, 100, 136, 68, 139, 251, 162,
23, 154, 89, 245, 135, 179, 79, 19,
97, 69, 109, 141, 9, 129, 125, 50,
189, 143, 64, 235, 134, 183, 123, 11,
240, 149, 33, 34, 92, 107, 78, 130,
84, 214, 101, 147, 206, 96, 178, 28,
115, 86, 192, 20, 167, 140, 241, 220,
18, 117, 202, 31, 59, 190, 228, 209,
66, 61, 212, 48, 163, 60, 182, 38,
111, 191, 14, 218, 70, 105, 7, 87,
39, 242, 29, 155, 188, 148, 67, 3,
248, 17, 199, 246, 144, 239, 62, 231,
6, 195, 213, 47, 200, 102, 30, 215,
8, 232, 234, 222, 128, 82, 238, 247,
132, 170, 114, 172, 53, 77, 106, 42,
150, 26, 210, 113, 90, 21, 73, 116,
75, 159, 208, 94, 4, 24, 164, 236,
194, 224, 65, 110, 15, 81, 203, 204,
36, 145, 175, 80, 161, 244, 112, 57,
153, 124, 58, 133, 35, 184, 180, 122,
252, 2, 54, 91, 37, 85, 151, 49,
45, 93, 250, 152, 227, 138, 146, 174,
5, 223, 41, 16, 103, 108, 186, 201,
211, 0, 230, 207, 225, 158, 168, 44,
99, 22, 1, 63, 88, 226, 137, 169,
13, 56, 52, 27, 171, 51, 255, 176,
187, 72, 12, 95, 185, 177, 205, 46,
197, 243, 219, 71, 229, 165, 156, 119,
10, 166, 32, 104, 254, 127, 193, 173
};
#define rotl16(x,n) (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
#define rotr16(x,n) (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
static const char *selftest (void);
static void
do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
{
RFC2268_context *ctx = context;
register int i, j;
u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
word0 = (word0 << 8) | inbuf[1];
word0 = (word0 << 8) | inbuf[0];
word1 = (word1 << 8) | inbuf[3];
word1 = (word1 << 8) | inbuf[2];
word2 = (word2 << 8) | inbuf[5];
word2 = (word2 << 8) | inbuf[4];
word3 = (word3 << 8) | inbuf[7];
word3 = (word3 << 8) | inbuf[6];
for (i = 0; i < 16; i++)
{
j = i * 4;
/* For some reason I cannot combine those steps. */
word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
word0 = rotl16(word0, 1);
word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
word1 = rotl16(word1, 2);
word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
word2 = rotl16(word2, 3);
word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
word3 = rotl16(word3, 5);
if (i == 4 || i == 10)
{
word0 += ctx->S[word3 & 63];
word1 += ctx->S[word0 & 63];
word2 += ctx->S[word1 & 63];
word3 += ctx->S[word2 & 63];
}
}
outbuf[0] = word0 & 255;
outbuf[1] = word0 >> 8;
outbuf[2] = word1 & 255;
outbuf[3] = word1 >> 8;
outbuf[4] = word2 & 255;
outbuf[5] = word2 >> 8;
outbuf[6] = word3 & 255;
outbuf[7] = word3 >> 8;
}
static void
do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
{
RFC2268_context *ctx = context;
register int i, j;
u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
word0 = (word0 << 8) | inbuf[1];
word0 = (word0 << 8) | inbuf[0];
word1 = (word1 << 8) | inbuf[3];
word1 = (word1 << 8) | inbuf[2];
word2 = (word2 << 8) | inbuf[5];
word2 = (word2 << 8) | inbuf[4];
word3 = (word3 << 8) | inbuf[7];
word3 = (word3 << 8) | inbuf[6];
for (i = 15; i >= 0; i--)
{
j = i * 4;
word3 = rotr16(word3, 5);
word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
word2 = rotr16(word2, 3);
word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
word1 = rotr16(word1, 2);
word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
word0 = rotr16(word0, 1);
word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
if (i == 5 || i == 11)
{
word3 = word3 - ctx->S[word2 & 63];
word2 = word2 - ctx->S[word1 & 63];
word1 = word1 - ctx->S[word0 & 63];
word0 = word0 - ctx->S[word3 & 63];
}
}
outbuf[0] = word0 & 255;
outbuf[1] = word0 >> 8;
outbuf[2] = word1 & 255;
outbuf[3] = word1 >> 8;
outbuf[4] = word2 & 255;
outbuf[5] = word2 >> 8;
outbuf[6] = word3 & 255;
outbuf[7] = word3 >> 8;
}
static gpg_err_code_t
setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
{
static int initialized;
static const char *selftest_failed;
RFC2268_context *ctx = context;
unsigned int i;
unsigned char *S, x;
int len;
int bits = keylen * 8;
if (!initialized)
{
initialized = 1;
selftest_failed = selftest ();
if (selftest_failed)
log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
}
if (selftest_failed)
return GPG_ERR_SELFTEST_FAILED;
if (keylen < 40 / 8) /* We want at least 40 bits. */
return GPG_ERR_INV_KEYLEN;
S = (unsigned char *) ctx->S;
for (i = 0; i < keylen; i++)
S[i] = key[i];
for (i = keylen; i < 128; i++)
S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
S[0] = rfc2268_sbox[S[0]];
/* Phase 2 - reduce effective key size to "bits". This was not
* discussed in Gutmann's paper. I've copied that from the public
* domain code posted in sci.crypt. */
if (with_phase2)
{
len = (bits + 7) >> 3;
i = 128 - len;
x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
S[i] = x;
while (i--)
{
x = rfc2268_sbox[x ^ S[i + len]];
S[i] = x;
}
}
/* Make the expanded key, endian independent. */
for (i = 0; i < 64; i++)
ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
return 0;
}
static gpg_err_code_t
do_setkey (void *context, const unsigned char *key, unsigned int keylen)
{
return setkey_core (context, key, keylen, 1);
}
static const char *
selftest (void)
{
RFC2268_context ctx;
unsigned char scratch[16];
/* Test vectors from Peter Gutmann's paper. */
static unsigned char key_1[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char plaintext_1[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const unsigned char ciphertext_1[] =
{ 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
static unsigned char key_2[] =
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};
static unsigned char plaintext_2[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static unsigned char ciphertext_2[] =
{ 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
/* This one was checked against libmcrypt's RFC2268. */
static unsigned char key_3[] =
{ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char plaintext_3[] =
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static unsigned char ciphertext_3[] =
{ 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
/* First test. */
setkey_core (&ctx, key_1, sizeof(key_1), 0);
do_encrypt (&ctx, scratch, plaintext_1);
if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
return "RFC2268 encryption test 1 failed.";
setkey_core (&ctx, key_1, sizeof(key_1), 0);
do_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
return "RFC2268 decryption test 1 failed.";
/* Second test. */
setkey_core (&ctx, key_2, sizeof(key_2), 0);
do_encrypt (&ctx, scratch, plaintext_2);
if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
return "RFC2268 encryption test 2 failed.";
setkey_core (&ctx, key_2, sizeof(key_2), 0);
do_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
return "RFC2268 decryption test 2 failed.";
/* Third test. */
setkey_core(&ctx, key_3, sizeof(key_3), 0);
do_encrypt(&ctx, scratch, plaintext_3);
if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
return "RFC2268 encryption test 3 failed.";
setkey_core (&ctx, key_3, sizeof(key_3), 0);
do_decrypt (&ctx, scratch, scratch);
if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
return "RFC2268 decryption test 3 failed.";
return NULL;
}
static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
{
/*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
/* pbeWithSHAAnd40BitRC2_CBC */
{ "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
{ NULL }
};
gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
"RFC2268_40", NULL, oids_rfc2268_40,
RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
do_setkey, do_encrypt, do_decrypt
};

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,37 @@
/* rmd.h - RIPE-MD hash functions
* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef G10_RMD_H
#define G10_RMD_H
/* We need this here because random.c must have direct access. */
typedef struct
{
u32 h0,h1,h2,h3,h4;
u32 nblocks;
byte buf[64];
int count;
} RMD160_CONTEXT;
void _gcry_rmd160_init ( void *context );
void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
#endif /*G10_RMD_H*/

View file

@ -0,0 +1,572 @@
/* rmd160.c - RIPE-MD160
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
#include "memory.h"
#include "rmd.h"
#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
#include "bithelp.h"
/*********************************
* RIPEMD-160 is not patented, see (as of 25.10.97)
* http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
* Note that the code uses Little Endian byteorder, which is good for
* 386 etc, but we must add some conversion when used on a big endian box.
*
*
* Pseudo-code for RIPEMD-160
*
* RIPEMD-160 is an iterative hash function that operates on 32-bit words.
* The round function takes as input a 5-word chaining variable and a 16-word
* message block and maps this to a new chaining variable. All operations are
* defined on 32-bit words. Padding is identical to that of MD4.
*
*
* RIPEMD-160: definitions
*
*
* nonlinear functions at bit level: exor, mux, -, mux, -
*
* f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
* f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
* f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
* f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
* f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
*
*
* added constants (hexadecimal)
*
* K(j) = 0x00000000 (0 <= j <= 15)
* K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
* K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
* K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
* K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
* K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
* K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
* K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
* K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
* K'(j) = 0x00000000 (64 <= j <= 79)
*
*
* selection of message word
*
* r(j) = j (0 <= j <= 15)
* r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
* r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
* r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
* r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
* r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
* r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
* r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
* r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
* r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
*
*
* amount for rotate left (rol)
*
* s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
* s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
* s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
* s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
* s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
* s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
* s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
* s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
* s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
* s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
*
*
* initial value (hexadecimal)
*
* h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
* h4 = 0xC3D2E1F0;
*
*
* RIPEMD-160: pseudo-code
*
* It is assumed that the message after padding consists of t 16-word blocks
* that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
* The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
* shift (rotate) over s positions.
*
*
* for i := 0 to t-1 {
* A := h0; B := h1; C := h2; D = h3; E = h4;
* A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
* for j := 0 to 79 {
* T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
* A := E; E := D; D := rol_10(C); C := B; B := T;
* T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
[+] K'(j)) [+] E';
* A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
* }
* T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
* h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
* }
*/
/* Some examples:
* "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
* "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
* "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
* "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
* "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
* "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
* "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
* 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
* 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
*/
void
_gcry_rmd160_init (void *context)
{
RMD160_CONTEXT *hd = context;
hd->h0 = 0x67452301;
hd->h1 = 0xEFCDAB89;
hd->h2 = 0x98BADCFE;
hd->h3 = 0x10325476;
hd->h4 = 0xC3D2E1F0;
hd->nblocks = 0;
hd->count = 0;
}
/****************
* Transform the message X which consists of 16 32-bit-words
*/
static void
transform ( RMD160_CONTEXT *hd, const unsigned char *data )
{
register u32 a,b,c,d,e;
u32 aa,bb,cc,dd,ee,t;
#ifdef WORDS_BIGENDIAN
u32 x[16];
{
int i;
byte *p2, *p1;
for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 )
{
p2[3] = *p1++;
p2[2] = *p1++;
p2[1] = *p1++;
p2[0] = *p1++;
}
}
#else
/* This version is better because it is always aligned;
* The performance penalty on a 586-100 is about 6% which
* is acceptable - because the data is more local it might
* also be possible that this is faster on some machines.
* This function (when compiled with -02 on gcc 2.7.2)
* executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
* [measured with a 4MB data and "gpgm --print-md rmd160"] */
u32 x[16];
memcpy( x, data, 64 );
#endif
#define K0 0x00000000
#define K1 0x5A827999
#define K2 0x6ED9EBA1
#define K3 0x8F1BBCDC
#define K4 0xA953FD4E
#define KK0 0x50A28BE6
#define KK1 0x5C4DD124
#define KK2 0x6D703EF3
#define KK3 0x7A6D76E9
#define KK4 0x00000000
#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
a = rol(t,s) + e; \
c = rol(c,10); \
} while(0)
/* left lane */
a = hd->h0;
b = hd->h1;
c = hd->h2;
d = hd->h3;
e = hd->h4;
R( a, b, c, d, e, F0, K0, 0, 11 );
R( e, a, b, c, d, F0, K0, 1, 14 );
R( d, e, a, b, c, F0, K0, 2, 15 );
R( c, d, e, a, b, F0, K0, 3, 12 );
R( b, c, d, e, a, F0, K0, 4, 5 );
R( a, b, c, d, e, F0, K0, 5, 8 );
R( e, a, b, c, d, F0, K0, 6, 7 );
R( d, e, a, b, c, F0, K0, 7, 9 );
R( c, d, e, a, b, F0, K0, 8, 11 );
R( b, c, d, e, a, F0, K0, 9, 13 );
R( a, b, c, d, e, F0, K0, 10, 14 );
R( e, a, b, c, d, F0, K0, 11, 15 );
R( d, e, a, b, c, F0, K0, 12, 6 );
R( c, d, e, a, b, F0, K0, 13, 7 );
R( b, c, d, e, a, F0, K0, 14, 9 );
R( a, b, c, d, e, F0, K0, 15, 8 );
R( e, a, b, c, d, F1, K1, 7, 7 );
R( d, e, a, b, c, F1, K1, 4, 6 );
R( c, d, e, a, b, F1, K1, 13, 8 );
R( b, c, d, e, a, F1, K1, 1, 13 );
R( a, b, c, d, e, F1, K1, 10, 11 );
R( e, a, b, c, d, F1, K1, 6, 9 );
R( d, e, a, b, c, F1, K1, 15, 7 );
R( c, d, e, a, b, F1, K1, 3, 15 );
R( b, c, d, e, a, F1, K1, 12, 7 );
R( a, b, c, d, e, F1, K1, 0, 12 );
R( e, a, b, c, d, F1, K1, 9, 15 );
R( d, e, a, b, c, F1, K1, 5, 9 );
R( c, d, e, a, b, F1, K1, 2, 11 );
R( b, c, d, e, a, F1, K1, 14, 7 );
R( a, b, c, d, e, F1, K1, 11, 13 );
R( e, a, b, c, d, F1, K1, 8, 12 );
R( d, e, a, b, c, F2, K2, 3, 11 );
R( c, d, e, a, b, F2, K2, 10, 13 );
R( b, c, d, e, a, F2, K2, 14, 6 );
R( a, b, c, d, e, F2, K2, 4, 7 );
R( e, a, b, c, d, F2, K2, 9, 14 );
R( d, e, a, b, c, F2, K2, 15, 9 );
R( c, d, e, a, b, F2, K2, 8, 13 );
R( b, c, d, e, a, F2, K2, 1, 15 );
R( a, b, c, d, e, F2, K2, 2, 14 );
R( e, a, b, c, d, F2, K2, 7, 8 );
R( d, e, a, b, c, F2, K2, 0, 13 );
R( c, d, e, a, b, F2, K2, 6, 6 );
R( b, c, d, e, a, F2, K2, 13, 5 );
R( a, b, c, d, e, F2, K2, 11, 12 );
R( e, a, b, c, d, F2, K2, 5, 7 );
R( d, e, a, b, c, F2, K2, 12, 5 );
R( c, d, e, a, b, F3, K3, 1, 11 );
R( b, c, d, e, a, F3, K3, 9, 12 );
R( a, b, c, d, e, F3, K3, 11, 14 );
R( e, a, b, c, d, F3, K3, 10, 15 );
R( d, e, a, b, c, F3, K3, 0, 14 );
R( c, d, e, a, b, F3, K3, 8, 15 );
R( b, c, d, e, a, F3, K3, 12, 9 );
R( a, b, c, d, e, F3, K3, 4, 8 );
R( e, a, b, c, d, F3, K3, 13, 9 );
R( d, e, a, b, c, F3, K3, 3, 14 );
R( c, d, e, a, b, F3, K3, 7, 5 );
R( b, c, d, e, a, F3, K3, 15, 6 );
R( a, b, c, d, e, F3, K3, 14, 8 );
R( e, a, b, c, d, F3, K3, 5, 6 );
R( d, e, a, b, c, F3, K3, 6, 5 );
R( c, d, e, a, b, F3, K3, 2, 12 );
R( b, c, d, e, a, F4, K4, 4, 9 );
R( a, b, c, d, e, F4, K4, 0, 15 );
R( e, a, b, c, d, F4, K4, 5, 5 );
R( d, e, a, b, c, F4, K4, 9, 11 );
R( c, d, e, a, b, F4, K4, 7, 6 );
R( b, c, d, e, a, F4, K4, 12, 8 );
R( a, b, c, d, e, F4, K4, 2, 13 );
R( e, a, b, c, d, F4, K4, 10, 12 );
R( d, e, a, b, c, F4, K4, 14, 5 );
R( c, d, e, a, b, F4, K4, 1, 12 );
R( b, c, d, e, a, F4, K4, 3, 13 );
R( a, b, c, d, e, F4, K4, 8, 14 );
R( e, a, b, c, d, F4, K4, 11, 11 );
R( d, e, a, b, c, F4, K4, 6, 8 );
R( c, d, e, a, b, F4, K4, 15, 5 );
R( b, c, d, e, a, F4, K4, 13, 6 );
aa = a; bb = b; cc = c; dd = d; ee = e;
/* right lane */
a = hd->h0;
b = hd->h1;
c = hd->h2;
d = hd->h3;
e = hd->h4;
R( a, b, c, d, e, F4, KK0, 5, 8);
R( e, a, b, c, d, F4, KK0, 14, 9);
R( d, e, a, b, c, F4, KK0, 7, 9);
R( c, d, e, a, b, F4, KK0, 0, 11);
R( b, c, d, e, a, F4, KK0, 9, 13);
R( a, b, c, d, e, F4, KK0, 2, 15);
R( e, a, b, c, d, F4, KK0, 11, 15);
R( d, e, a, b, c, F4, KK0, 4, 5);
R( c, d, e, a, b, F4, KK0, 13, 7);
R( b, c, d, e, a, F4, KK0, 6, 7);
R( a, b, c, d, e, F4, KK0, 15, 8);
R( e, a, b, c, d, F4, KK0, 8, 11);
R( d, e, a, b, c, F4, KK0, 1, 14);
R( c, d, e, a, b, F4, KK0, 10, 14);
R( b, c, d, e, a, F4, KK0, 3, 12);
R( a, b, c, d, e, F4, KK0, 12, 6);
R( e, a, b, c, d, F3, KK1, 6, 9);
R( d, e, a, b, c, F3, KK1, 11, 13);
R( c, d, e, a, b, F3, KK1, 3, 15);
R( b, c, d, e, a, F3, KK1, 7, 7);
R( a, b, c, d, e, F3, KK1, 0, 12);
R( e, a, b, c, d, F3, KK1, 13, 8);
R( d, e, a, b, c, F3, KK1, 5, 9);
R( c, d, e, a, b, F3, KK1, 10, 11);
R( b, c, d, e, a, F3, KK1, 14, 7);
R( a, b, c, d, e, F3, KK1, 15, 7);
R( e, a, b, c, d, F3, KK1, 8, 12);
R( d, e, a, b, c, F3, KK1, 12, 7);
R( c, d, e, a, b, F3, KK1, 4, 6);
R( b, c, d, e, a, F3, KK1, 9, 15);
R( a, b, c, d, e, F3, KK1, 1, 13);
R( e, a, b, c, d, F3, KK1, 2, 11);
R( d, e, a, b, c, F2, KK2, 15, 9);
R( c, d, e, a, b, F2, KK2, 5, 7);
R( b, c, d, e, a, F2, KK2, 1, 15);
R( a, b, c, d, e, F2, KK2, 3, 11);
R( e, a, b, c, d, F2, KK2, 7, 8);
R( d, e, a, b, c, F2, KK2, 14, 6);
R( c, d, e, a, b, F2, KK2, 6, 6);
R( b, c, d, e, a, F2, KK2, 9, 14);
R( a, b, c, d, e, F2, KK2, 11, 12);
R( e, a, b, c, d, F2, KK2, 8, 13);
R( d, e, a, b, c, F2, KK2, 12, 5);
R( c, d, e, a, b, F2, KK2, 2, 14);
R( b, c, d, e, a, F2, KK2, 10, 13);
R( a, b, c, d, e, F2, KK2, 0, 13);
R( e, a, b, c, d, F2, KK2, 4, 7);
R( d, e, a, b, c, F2, KK2, 13, 5);
R( c, d, e, a, b, F1, KK3, 8, 15);
R( b, c, d, e, a, F1, KK3, 6, 5);
R( a, b, c, d, e, F1, KK3, 4, 8);
R( e, a, b, c, d, F1, KK3, 1, 11);
R( d, e, a, b, c, F1, KK3, 3, 14);
R( c, d, e, a, b, F1, KK3, 11, 14);
R( b, c, d, e, a, F1, KK3, 15, 6);
R( a, b, c, d, e, F1, KK3, 0, 14);
R( e, a, b, c, d, F1, KK3, 5, 6);
R( d, e, a, b, c, F1, KK3, 12, 9);
R( c, d, e, a, b, F1, KK3, 2, 12);
R( b, c, d, e, a, F1, KK3, 13, 9);
R( a, b, c, d, e, F1, KK3, 9, 12);
R( e, a, b, c, d, F1, KK3, 7, 5);
R( d, e, a, b, c, F1, KK3, 10, 15);
R( c, d, e, a, b, F1, KK3, 14, 8);
R( b, c, d, e, a, F0, KK4, 12, 8);
R( a, b, c, d, e, F0, KK4, 15, 5);
R( e, a, b, c, d, F0, KK4, 10, 12);
R( d, e, a, b, c, F0, KK4, 4, 9);
R( c, d, e, a, b, F0, KK4, 1, 12);
R( b, c, d, e, a, F0, KK4, 5, 5);
R( a, b, c, d, e, F0, KK4, 8, 14);
R( e, a, b, c, d, F0, KK4, 7, 6);
R( d, e, a, b, c, F0, KK4, 6, 8);
R( c, d, e, a, b, F0, KK4, 2, 13);
R( b, c, d, e, a, F0, KK4, 13, 6);
R( a, b, c, d, e, F0, KK4, 14, 5);
R( e, a, b, c, d, F0, KK4, 0, 15);
R( d, e, a, b, c, F0, KK4, 3, 13);
R( c, d, e, a, b, F0, KK4, 9, 11);
R( b, c, d, e, a, F0, KK4, 11, 11);
t = hd->h1 + d + cc;
hd->h1 = hd->h2 + e + dd;
hd->h2 = hd->h3 + a + ee;
hd->h3 = hd->h4 + b + aa;
hd->h4 = hd->h0 + c + bb;
hd->h0 = t;
}
/* Update the message digest with the contents
* of INBUF with length INLEN.
*/
static void
rmd160_write ( void *context, const void *inbuf_arg, size_t inlen)
{
const unsigned char *inbuf = inbuf_arg;
RMD160_CONTEXT *hd = context;
if( hd->count == 64 ) /* flush the buffer */
{
transform( hd, hd->buf );
_gcry_burn_stack (108+5*sizeof(void*));
hd->count = 0;
hd->nblocks++;
}
if( !inbuf )
return;
if( hd->count )
{
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
rmd160_write( hd, NULL, 0 );
if( !inlen )
return;
}
while( inlen >= 64 )
{
transform( hd, inbuf );
hd->count = 0;
hd->nblocks++;
inlen -= 64;
inbuf += 64;
}
_gcry_burn_stack (108+5*sizeof(void*));
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
}
/****************
* Apply the rmd160 transform function on the buffer which must have
* a length 64 bytes. Do not use this function together with the
* other functions, use rmd160_init to initialize internal variables.
* Returns: 16 bytes in buffer with the mixed contentes of buffer.
*/
void
_gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte )
{
char *p = blockof64byte;
transform ( hd, blockof64byte );
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
X(0);
X(1);
X(2);
X(3);
X(4);
#undef X
}
/* The routine terminates the computation
*/
static void
rmd160_final( void *context )
{
RMD160_CONTEXT *hd = context;
u32 t, msb, lsb;
byte *p;
rmd160_write(hd, NULL, 0); /* flush */;
t = hd->nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
if( (lsb += hd->count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
lsb <<= 3;
msb <<= 3;
msb |= t >> 29;
if( hd->count < 56 ) /* enough room */
{
hd->buf[hd->count++] = 0x80; /* pad */
while( hd->count < 56 )
hd->buf[hd->count++] = 0; /* pad */
}
else /* need one extra block */
{
hd->buf[hd->count++] = 0x80; /* pad character */
while( hd->count < 64 )
hd->buf[hd->count++] = 0;
rmd160_write(hd, NULL, 0); /* flush */;
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
hd->buf[56] = lsb ;
hd->buf[57] = lsb >> 8;
hd->buf[58] = lsb >> 16;
hd->buf[59] = lsb >> 24;
hd->buf[60] = msb ;
hd->buf[61] = msb >> 8;
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform( hd, hd->buf );
_gcry_burn_stack (108+5*sizeof(void*));
p = hd->buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
*p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
#else /* little endian */
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
#endif
X(0);
X(1);
X(2);
X(3);
X(4);
#undef X
}
static byte *
rmd160_read( void *context )
{
RMD160_CONTEXT *hd = context;
return hd->buf;
}
/****************
* Shortcut functions which puts the hash value of the supplied buffer
* into outbuf which must have a size of 20 bytes.
*/
void
_gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
{
RMD160_CONTEXT hd;
_gcry_rmd160_init ( &hd );
rmd160_write ( &hd, buffer, length );
rmd160_final ( &hd );
memcpy ( outbuf, hd.buf, 20 );
}
static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
static gcry_md_oid_spec_t oid_spec_rmd160[] =
{
/* rsaSignatureWithripemd160 */
{ "1.3.36.3.3.1.2" },
/* TeleTrust hash algorithm. */
{ "1.3.36.3.2.1" },
{ NULL }
};
gcry_md_spec_t _gcry_digest_spec_rmd160 =
{
"RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
_gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
sizeof (RMD160_CONTEXT)
};

1379
lib/libgcrypt/cipher/rsa.c Normal file

File diff suppressed because it is too large Load diff

478
lib/libgcrypt/cipher/seed.c Normal file
View file

@ -0,0 +1,478 @@
/* SEED for libgcrypt
* Copyright (C) 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* --
* This implementation was provided for libgcrypt in public domain
* by Hye-Shik Chang <perky@FreeBSD.org>, July 2006.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "types.h" /* for byte and u32 typedefs */
#include "g10lib.h"
#include "cipher.h"
#define NUMKC 16
#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
#define PUTU32(ct, st) { (ct)[0] = (byte)((st) >> 24); \
(ct)[1] = (byte)((st) >> 16); \
(ct)[2] = (byte)((st) >> 8); \
(ct)[3] = (byte)(st); }
union wordbuf
{
u32 w;
byte b[4];
};
#ifdef WORDS_BIGENDIAN
#define b0 b[3]
#define b1 b[2]
#define b2 b[1]
#define b3 b[0]
#else
#define b0 b[0]
#define b1 b[1]
#define b2 b[2]
#define b3 b[3]
#endif
static const char *selftest(void);
typedef struct
{
u32 keyschedule[32];
} SEED_context;
static const u32 SS0[256] = {
0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c,
0x2c8ca0ac, 0x25052124, 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, 0x28082028, 0x04444044,
0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310,
0x12c2d2d0, 0x2ecee2ec, 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, 0x2ccce0ec, 0x15859194,
0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc,
0x32c2f2f0, 0x19c9d1d8, 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, 0x20406060, 0x10405050,
0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210,
0x2f8fa3ac, 0x15c5d1d4, 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, 0x1f0f131c, 0x19899198,
0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388,
0x0e0e020c, 0x2b8ba3a8, 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, 0x3f8fb3bc, 0x2fcfe3ec,
0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120,
0x2b4b6368, 0x26466264, 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, 0x3a4a7278, 0x07474344,
0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114,
0x22022220, 0x38083038, 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, 0x35053134, 0x0bcbc3c8,
0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158,
0x02828280, 0x04c4c0c4, 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, 0x0f0f030c, 0x0e8e828c,
0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c,
0x2d0d212c, 0x00404040, 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, 0x3b0b3338, 0x1cccd0dc,
0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328,
0x25456164, 0x3acaf2f8, 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, 0x31013130, 0x2acae2e8,
0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128,
0x07070304, 0x33033330, 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298,
};
static const u32 SS1[256] = {
0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2,
0xb03383b3, 0xb83888b0, 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, 0xc003c3c3, 0x60224262,
0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0,
0x34360632, 0x480b4b43, 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, 0xc002c2c2, 0x44054541,
0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1,
0x0c0d0d01, 0xdc1fcfd3, 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, 0x40024242, 0xd414c4d0,
0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20,
0xa82a8aa2, 0x34340430, 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, 0x54174753, 0xac2e8ea2,
0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82,
0x682a4a62, 0xb03181b1, 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xd81bcbd3,
0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3,
0xa82b8ba3, 0xd010c0d0, 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, 0x94168692, 0x783b4b73,
0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22,
0xb83a8ab2, 0x6c2e4e62, 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, 0x14150511, 0xf83bcbf3,
0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0,
0xe82acae2, 0x08090901, 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, 0xf83acaf2, 0x00010101,
0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1,
0x48084840, 0x78394971, 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, 0x74374773, 0x54144450,
0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2,
0xc809c9c1, 0xfc3dcdf1, 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, 0x0c0e0e02, 0x50104050,
0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353,
0x080a0a02, 0x84078783, 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3,
};
static const u32 SS2[256] = {
0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d,
0xa0ac2c8c, 0x21242505, 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, 0x20282808, 0x40440444,
0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303,
0xd2d012c2, 0xe2ec2ece, 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, 0xe0ec2ccc, 0x91941585,
0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc,
0xf2f032c2, 0xd1d819c9, 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, 0x60602040, 0x50501040,
0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202,
0xa3ac2f8f, 0xd1d415c5, 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, 0x131c1f0f, 0x91981989,
0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b,
0x020c0e0e, 0xa3a82b8b, 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, 0xb3bc3f8f, 0xe3ec2fcf,
0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101,
0x63682b4b, 0x62642646, 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, 0x72783a4a, 0x43440747,
0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505,
0x22202202, 0x30383808, 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, 0x31343505, 0xc3c80bcb,
0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949,
0x82800282, 0xc0c404c4, 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, 0x030c0f0f, 0x828c0e8e,
0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d,
0x212c2d0d, 0x40400040, 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, 0x33383b0b, 0xd0dc1ccc,
0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b,
0x61642545, 0xf2f83aca, 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, 0x31303101, 0xe2e82aca,
0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909,
0x03040707, 0x33303303, 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a,
};
static const u32 SS3[256] = {
0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e,
0x83b3b033, 0x88b0b838, 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, 0xc3c3c003, 0x42626022,
0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c,
0x06323436, 0x4b43480b, 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, 0xc2c2c002, 0x45414405,
0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839,
0x0d010c0d, 0xcfd3dc1f, 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, 0x42424002, 0xc4d0d414,
0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c,
0x8aa2a82a, 0x04303434, 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, 0x47535417, 0x8ea2ac2e,
0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a,
0x4a62682a, 0x81b1b031, 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xcbd3d81b,
0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023,
0x8ba3a82b, 0xc0d0d010, 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, 0x86929416, 0x4b73783b,
0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e,
0x8ab2b83a, 0x4e626c2e, 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, 0x05111415, 0xcbf3f83b,
0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434,
0xcae2e82a, 0x09010809, 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, 0xcaf2f83a, 0x01010001,
0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425,
0x48404808, 0x49717839, 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, 0x47737437, 0x44505414,
0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a,
0xc9c1c809, 0xcdf1fc3d, 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, 0x0e020c0e, 0x40505010,
0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013,
0x0a02080a, 0x87838407, 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437,
};
static const u32 KC[NUMKC] = {
0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b,
};
/* Perform the key setup.
*/
static gcry_err_code_t
do_setkey (SEED_context *ctx, const byte *key, const unsigned keylen)
{
static int initialized = 0;
static const char *selftest_failed=0;
u32 x1, x2, x3, x4;
union wordbuf t0, t1;
u32 *keyout = ctx->keyschedule;
int i;
if (!initialized)
{
initialized = 1;
selftest_failed = selftest ();
if( selftest_failed )
log_error ("%s\n", selftest_failed );
}
if (selftest_failed)
return GPG_ERR_SELFTEST_FAILED;
if (keylen != 16)
return GPG_ERR_INV_KEYLEN;
x1 = GETU32 (key);
x2 = GETU32 (key+4);
x3 = GETU32 (key+8);
x4 = GETU32 (key+12);
for (i = 0; i < NUMKC; i++)
{
t0.w = x1 + x3 - KC[i];
t1.w = x2 + KC[i] - x4;
*(keyout++) = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];
*(keyout++) = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];
if (i % 2 == 0)
{
t0.w = x1;
x1 = (x1>>8) ^ (x2<<24);
x2 = (x2>>8) ^ (t0.w<<24);
}
else
{
t0.w = x3;
x3 = (x3<<8) ^ (x4>>24);
x4 = (x4<<8) ^ (t0.w>>24);
}
}
return 0;
}
static gcry_err_code_t
seed_setkey (void *context, const byte *key, const unsigned keylen)
{
SEED_context *ctx = context;
int rc = do_setkey (ctx, key, keylen);
_gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2);
return rc;
}
#define OP(X1, X2, X3, X4, rbase) \
t0.w = X3 ^ ctx->keyschedule[rbase]; \
t1.w = X4 ^ ctx->keyschedule[rbase+1]; \
t1.w ^= t0.w; \
t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
t0.w += t1.w; \
t0.w = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3]; \
t1.w += t0.w; \
t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
t0.w += t1.w; \
X1 ^= t0.w; \
X2 ^= t1.w;
/* Encrypt one block. inbuf and outbuf may be the same. */
static void
do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf)
{
u32 x1, x2, x3, x4;
union wordbuf t0, t1;
x1 = GETU32 (inbuf);
x2 = GETU32 (inbuf+4);
x3 = GETU32 (inbuf+8);
x4 = GETU32 (inbuf+12);
OP (x1, x2, x3, x4, 0);
OP (x3, x4, x1, x2, 2);
OP (x1, x2, x3, x4, 4);
OP (x3, x4, x1, x2, 6);
OP (x1, x2, x3, x4, 8);
OP (x3, x4, x1, x2, 10);
OP (x1, x2, x3, x4, 12);
OP (x3, x4, x1, x2, 14);
OP (x1, x2, x3, x4, 16);
OP (x3, x4, x1, x2, 18);
OP (x1, x2, x3, x4, 20);
OP (x3, x4, x1, x2, 22);
OP (x1, x2, x3, x4, 24);
OP (x3, x4, x1, x2, 26);
OP (x1, x2, x3, x4, 28);
OP (x3, x4, x1, x2, 30);
PUTU32 (outbuf, x3);
PUTU32 (outbuf+4, x4);
PUTU32 (outbuf+8, x1);
PUTU32 (outbuf+12, x2);
}
static void
seed_encrypt (void *context, byte *outbuf, const byte *inbuf)
{
SEED_context *ctx = context;
do_encrypt (ctx, outbuf, inbuf);
_gcry_burn_stack (4*6);
}
/* Decrypt one block. inbuf and outbuf may be the same. */
static void
do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf)
{
u32 x1, x2, x3, x4;
union wordbuf t0, t1;
x1 = GETU32 (inbuf);
x2 = GETU32 (inbuf+4);
x3 = GETU32 (inbuf+8);
x4 = GETU32 (inbuf+12);
OP (x1, x2, x3, x4, 30);
OP (x3, x4, x1, x2, 28);
OP (x1, x2, x3, x4, 26);
OP (x3, x4, x1, x2, 24);
OP (x1, x2, x3, x4, 22);
OP (x3, x4, x1, x2, 20);
OP (x1, x2, x3, x4, 18);
OP (x3, x4, x1, x2, 16);
OP (x1, x2, x3, x4, 14);
OP (x3, x4, x1, x2, 12);
OP (x1, x2, x3, x4, 10);
OP (x3, x4, x1, x2, 8);
OP (x1, x2, x3, x4, 6);
OP (x3, x4, x1, x2, 4);
OP (x1, x2, x3, x4, 2);
OP (x3, x4, x1, x2, 0);
PUTU32 (outbuf, x3);
PUTU32 (outbuf+4, x4);
PUTU32 (outbuf+8, x1);
PUTU32 (outbuf+12, x2);
}
static void
seed_decrypt (void *context, byte *outbuf, const byte *inbuf)
{
SEED_context *ctx = context;
do_decrypt (ctx, outbuf, inbuf);
_gcry_burn_stack (4*6);
}
/* Test a single encryption and decryption with each key size. */
static const char*
selftest (void)
{
SEED_context ctx;
byte scratch[16];
/* The test vector is taken from the appendix section B.3 of RFC4269.
*/
static const byte plaintext[16] = {
0x83, 0xA2, 0xF8, 0xA2, 0x88, 0x64, 0x1F, 0xB9,
0xA4, 0xE9, 0xA5, 0xCC, 0x2F, 0x13, 0x1C, 0x7D
};
static const byte key[16] = {
0x47, 0x06, 0x48, 0x08, 0x51, 0xE6, 0x1B, 0xE8,
0x5D, 0x74, 0xBF, 0xB3, 0xFD, 0x95, 0x61, 0x85
};
static const byte ciphertext[16] = {
0xEE, 0x54, 0xD1, 0x3E, 0xBC, 0xAE, 0x70, 0x6D,
0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A,
};
seed_setkey (&ctx, key, sizeof(key));
seed_encrypt (&ctx, scratch, plaintext);
if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
return "SEED test encryption failed.";
seed_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext, sizeof (plaintext)))
return "SEED test decryption failed.";
return NULL;
}
static gcry_cipher_oid_spec_t seed_oids[] =
{
{ "1.2.410.200004.1.3", GCRY_CIPHER_MODE_ECB },
{ "1.2.410.200004.1.4", GCRY_CIPHER_MODE_CBC },
{ "1.2.410.200004.1.5", GCRY_CIPHER_MODE_CFB },
{ "1.2.410.200004.1.6", GCRY_CIPHER_MODE_OFB },
{ NULL }
};
gcry_cipher_spec_t _gcry_cipher_spec_seed =
{
"SEED", NULL, seed_oids, 16, 128, sizeof (SEED_context),
seed_setkey, seed_encrypt, seed_decrypt,
};

View file

@ -0,0 +1,978 @@
/* serpent.c - Implementation of the Serpent encryption algorithm.
* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#include <string.h>
#include <stdio.h>
#include "types.h"
#include "g10lib.h"
#include "cipher.h"
#include "bithelp.h"
/* Number of rounds per Serpent encrypt/decrypt operation. */
#define ROUNDS 32
/* Magic number, used during generating of the subkeys. */
#define PHI 0x9E3779B9
/* Serpent works on 128 bit blocks. */
typedef u32 serpent_block_t[4];
/* Serpent key, provided by the user. If the original key is shorter
than 256 bits, it is padded. */
typedef u32 serpent_key_t[8];
/* The key schedule consists of 33 128 bit subkeys. */
typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
/* A Serpent context. */
typedef struct serpent_context
{
serpent_subkeys_t keys; /* Generated subkeys. */
} serpent_context_t;
/* A prototype. */
static const char *serpent_test (void);
#define byte_swap_32(x) \
(0 \
| (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
| (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
/* These are the S-Boxes of Serpent. They are copied from Serpents
reference implementation (the optimized one, contained in
`floppy2') and are therefore:
Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
To quote the Serpent homepage
(http://www.cl.cam.ac.uk/~rja14/serpent.html):
"Serpent is now completely in the public domain, and we impose no
restrictions on its use. This was announced on the 21st August at
the First AES Candidate Conference. The optimised implementations
in the submission package are now under the GNU PUBLIC LICENSE
(GPL), although some comments in the code still say otherwise. You
are welcome to use Serpent for any application." */
#define SBOX0(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t05, t06, t07, t08, t09; \
u32 t11, t12, t13, t14, t15, t17, t01; \
t01 = b ^ c ; \
t02 = a | d ; \
t03 = a ^ b ; \
z = t02 ^ t01; \
t05 = c | z ; \
t06 = a ^ d ; \
t07 = b | c ; \
t08 = d & t05; \
t09 = t03 & t07; \
y = t09 ^ t08; \
t11 = t09 & y ; \
t12 = c ^ d ; \
t13 = t07 ^ t11; \
t14 = b & t06; \
t15 = t06 ^ t13; \
w = ~ t15; \
t17 = w ^ t14; \
x = t12 ^ t17; \
}
#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t08, t09, t10; \
u32 t12, t13, t14, t15, t17, t18, t01; \
t01 = c ^ d ; \
t02 = a | b ; \
t03 = b | c ; \
t04 = c & t01; \
t05 = t02 ^ t01; \
t06 = a | t04; \
y = ~ t05; \
t08 = b ^ d ; \
t09 = t03 & t08; \
t10 = d | y ; \
x = t09 ^ t06; \
t12 = a | t05; \
t13 = x ^ t12; \
t14 = t03 ^ t10; \
t15 = a ^ c ; \
z = t14 ^ t13; \
t17 = t05 & t13; \
t18 = t14 | t17; \
w = t15 ^ t18; \
}
#define SBOX1(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t07, t08; \
u32 t10, t11, t12, t13, t16, t17, t01; \
t01 = a | d ; \
t02 = c ^ d ; \
t03 = ~ b ; \
t04 = a ^ c ; \
t05 = a | t03; \
t06 = d & t04; \
t07 = t01 & t02; \
t08 = b | t06; \
y = t02 ^ t05; \
t10 = t07 ^ t08; \
t11 = t01 ^ t10; \
t12 = y ^ t11; \
t13 = b & d ; \
z = ~ t10; \
x = t13 ^ t12; \
t16 = t10 | x ; \
t17 = t05 & t16; \
w = c ^ t17; \
}
#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t07, t08; \
u32 t09, t10, t11, t14, t15, t17, t01; \
t01 = a ^ b ; \
t02 = b | d ; \
t03 = a & c ; \
t04 = c ^ t02; \
t05 = a | t04; \
t06 = t01 & t05; \
t07 = d | t03; \
t08 = b ^ t06; \
t09 = t07 ^ t06; \
t10 = t04 | t03; \
t11 = d & t08; \
y = ~ t09; \
x = t10 ^ t11; \
t14 = a | y ; \
t15 = t06 ^ x ; \
z = t01 ^ t04; \
t17 = c ^ t15; \
w = t14 ^ t17; \
}
#define SBOX2(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t05, t06, t07, t08; \
u32 t09, t10, t12, t13, t14, t01; \
t01 = a | c ; \
t02 = a ^ b ; \
t03 = d ^ t01; \
w = t02 ^ t03; \
t05 = c ^ w ; \
t06 = b ^ t05; \
t07 = b | t05; \
t08 = t01 & t06; \
t09 = t03 ^ t07; \
t10 = t02 | t09; \
x = t10 ^ t08; \
t12 = a | d ; \
t13 = t09 ^ x ; \
t14 = b ^ t13; \
z = ~ t09; \
y = t12 ^ t14; \
}
#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t06, t07, t08, t09; \
u32 t10, t11, t12, t15, t16, t17, t01; \
t01 = a ^ d ; \
t02 = c ^ d ; \
t03 = a & c ; \
t04 = b | t02; \
w = t01 ^ t04; \
t06 = a | c ; \
t07 = d | w ; \
t08 = ~ d ; \
t09 = b & t06; \
t10 = t08 | t03; \
t11 = b & t07; \
t12 = t06 & t02; \
z = t09 ^ t10; \
x = t12 ^ t11; \
t15 = c & z ; \
t16 = w ^ x ; \
t17 = t10 ^ t15; \
y = t16 ^ t17; \
}
#define SBOX3(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t07, t08; \
u32 t09, t10, t11, t13, t14, t15, t01; \
t01 = a ^ c ; \
t02 = a | d ; \
t03 = a & d ; \
t04 = t01 & t02; \
t05 = b | t03; \
t06 = a & b ; \
t07 = d ^ t04; \
t08 = c | t06; \
t09 = b ^ t07; \
t10 = d & t05; \
t11 = t02 ^ t10; \
z = t08 ^ t09; \
t13 = d | z ; \
t14 = a | t07; \
t15 = b & t13; \
y = t08 ^ t11; \
w = t14 ^ t15; \
x = t05 ^ t04; \
}
#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t07, t09; \
u32 t11, t12, t13, t14, t16, t01; \
t01 = c | d ; \
t02 = a | d ; \
t03 = c ^ t02; \
t04 = b ^ t02; \
t05 = a ^ d ; \
t06 = t04 & t03; \
t07 = b & t01; \
y = t05 ^ t06; \
t09 = a ^ t03; \
w = t07 ^ t03; \
t11 = w | t05; \
t12 = t09 & t11; \
t13 = a & y ; \
t14 = t01 ^ t05; \
x = b ^ t12; \
t16 = b | t13; \
z = t14 ^ t16; \
}
#define SBOX4(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t08, t09; \
u32 t10, t11, t12, t13, t14, t15, t16, t01; \
t01 = a | b ; \
t02 = b | c ; \
t03 = a ^ t02; \
t04 = b ^ d ; \
t05 = d | t03; \
t06 = d & t01; \
z = t03 ^ t06; \
t08 = z & t04; \
t09 = t04 & t05; \
t10 = c ^ t06; \
t11 = b & c ; \
t12 = t04 ^ t08; \
t13 = t11 | t03; \
t14 = t10 ^ t09; \
t15 = a & t05; \
t16 = t11 | t12; \
y = t13 ^ t08; \
x = t15 ^ t16; \
w = ~ t14; \
}
#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t07, t09; \
u32 t10, t11, t12, t13, t15, t01; \
t01 = b | d ; \
t02 = c | d ; \
t03 = a & t01; \
t04 = b ^ t02; \
t05 = c ^ d ; \
t06 = ~ t03; \
t07 = a & t04; \
x = t05 ^ t07; \
t09 = x | t06; \
t10 = a ^ t07; \
t11 = t01 ^ t09; \
t12 = d ^ t04; \
t13 = c | t10; \
z = t03 ^ t12; \
t15 = a ^ t04; \
y = t11 ^ t13; \
w = t15 ^ t09; \
}
#define SBOX5(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t07, t08, t09; \
u32 t10, t11, t12, t13, t14, t01; \
t01 = b ^ d ; \
t02 = b | d ; \
t03 = a & t01; \
t04 = c ^ t02; \
t05 = t03 ^ t04; \
w = ~ t05; \
t07 = a ^ t01; \
t08 = d | w ; \
t09 = b | t05; \
t10 = d ^ t08; \
t11 = b | t07; \
t12 = t03 | w ; \
t13 = t07 | t10; \
t14 = t01 ^ t11; \
y = t09 ^ t13; \
x = t07 ^ t08; \
z = t12 ^ t14; \
}
#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t07, t08, t09; \
u32 t10, t12, t13, t15, t16, t01; \
t01 = a & d ; \
t02 = c ^ t01; \
t03 = a ^ d ; \
t04 = b & t02; \
t05 = a & c ; \
w = t03 ^ t04; \
t07 = a & w ; \
t08 = t01 ^ w ; \
t09 = b | t05; \
t10 = ~ b ; \
x = t08 ^ t09; \
t12 = t10 | t07; \
t13 = w | x ; \
z = t02 ^ t12; \
t15 = t02 ^ t13; \
t16 = b ^ d ; \
y = t16 ^ t15; \
}
#define SBOX6(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t07, t08, t09, t10; \
u32 t11, t12, t13, t15, t17, t18, t01; \
t01 = a & d ; \
t02 = b ^ c ; \
t03 = a ^ d ; \
t04 = t01 ^ t02; \
t05 = b | c ; \
x = ~ t04; \
t07 = t03 & t05; \
t08 = b & x ; \
t09 = a | c ; \
t10 = t07 ^ t08; \
t11 = b | d ; \
t12 = c ^ t11; \
t13 = t09 ^ t10; \
y = ~ t13; \
t15 = x & t03; \
z = t12 ^ t07; \
t17 = a ^ b ; \
t18 = y ^ t15; \
w = t17 ^ t18; \
}
#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t07, t08, t09; \
u32 t12, t13, t14, t15, t16, t17, t01; \
t01 = a ^ c ; \
t02 = ~ c ; \
t03 = b & t01; \
t04 = b | t02; \
t05 = d | t03; \
t06 = b ^ d ; \
t07 = a & t04; \
t08 = a | t02; \
t09 = t07 ^ t05; \
x = t06 ^ t08; \
w = ~ t09; \
t12 = b & w ; \
t13 = t01 & t05; \
t14 = t01 ^ t12; \
t15 = t07 ^ t13; \
t16 = d | t02; \
t17 = a ^ x ; \
z = t17 ^ t15; \
y = t16 ^ t14; \
}
#define SBOX7(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t05, t06, t08, t09, t10; \
u32 t11, t13, t14, t15, t16, t17, t01; \
t01 = a & c ; \
t02 = ~ d ; \
t03 = a & t02; \
t04 = b | t01; \
t05 = a & b ; \
t06 = c ^ t04; \
z = t03 ^ t06; \
t08 = c | z ; \
t09 = d | t05; \
t10 = a ^ t08; \
t11 = t04 & z ; \
x = t09 ^ t10; \
t13 = b ^ x ; \
t14 = t01 ^ x ; \
t15 = c ^ t05; \
t16 = t11 | t13; \
t17 = t02 | t14; \
w = t15 ^ t17; \
y = a ^ t16; \
}
#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
{ \
u32 t02, t03, t04, t06, t07, t08, t09; \
u32 t10, t11, t13, t14, t15, t16, t01; \
t01 = a & b ; \
t02 = a | b ; \
t03 = c | t01; \
t04 = d & t02; \
z = t03 ^ t04; \
t06 = b ^ t04; \
t07 = d ^ z ; \
t08 = ~ t07; \
t09 = t06 | t08; \
t10 = b ^ d ; \
t11 = a | d ; \
x = a ^ t09; \
t13 = c ^ t06; \
t14 = c & t11; \
t15 = d | x ; \
t16 = t01 | t10; \
w = t13 ^ t15; \
y = t14 ^ t16; \
}
/* XOR BLOCK1 into BLOCK0. */
#define BLOCK_XOR(block0, block1) \
{ \
block0[0] ^= block1[0]; \
block0[1] ^= block1[1]; \
block0[2] ^= block1[2]; \
block0[3] ^= block1[3]; \
}
/* Copy BLOCK_SRC to BLOCK_DST. */
#define BLOCK_COPY(block_dst, block_src) \
{ \
block_dst[0] = block_src[0]; \
block_dst[1] = block_src[1]; \
block_dst[2] = block_src[2]; \
block_dst[3] = block_src[3]; \
}
/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
INDEX, writing the output to the block found in ARRAY1 at index
INDEX. */
#define SBOX(which, array0, array1, index) \
SBOX##which (array0[index + 0], array0[index + 1], \
array0[index + 2], array0[index + 3], \
array1[index + 0], array1[index + 1], \
array1[index + 2], array1[index + 3]);
/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
index INDEX, writing the output to the block found in ARRAY1 at
index INDEX. */
#define SBOX_INVERSE(which, array0, array1, index) \
SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \
array0[index + 2], array0[index + 3], \
array1[index + 0], array1[index + 1], \
array1[index + 2], array1[index + 3]);
/* Apply the linear transformation to BLOCK. */
#define LINEAR_TRANSFORMATION(block) \
{ \
block[0] = rol (block[0], 13); \
block[2] = rol (block[2], 3); \
block[1] = block[1] ^ block[0] ^ block[2]; \
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
block[1] = rol (block[1], 1); \
block[3] = rol (block[3], 7); \
block[0] = block[0] ^ block[1] ^ block[3]; \
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
block[0] = rol (block[0], 5); \
block[2] = rol (block[2], 22); \
}
/* Apply the inverse linear transformation to BLOCK. */
#define LINEAR_TRANSFORMATION_INVERSE(block) \
{ \
block[2] = ror (block[2], 22); \
block[0] = ror (block[0] , 5); \
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
block[0] = block[0] ^ block[1] ^ block[3]; \
block[3] = ror (block[3], 7); \
block[1] = ror (block[1], 1); \
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
block[1] = block[1] ^ block[0] ^ block[2]; \
block[2] = ror (block[2], 3); \
block[0] = ror (block[0], 13); \
}
/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage.
This macro increments `round'. */
#define ROUND(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round++; \
SBOX (which, block, block_tmp, 0); \
LINEAR_TRANSFORMATION (block_tmp); \
BLOCK_COPY (block, block_tmp); \
}
/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
storage. The result will be stored in BLOCK_TMP. This macro
increments `round'. */
#define ROUND_LAST(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round++; \
SBOX (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkeys[round]); \
round++; \
}
/* Apply an inverse Serpent round to BLOCK, using the SBOX number
WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as
temporary storage. This macro increments `round'. */
#define ROUND_INVERSE(which, subkey, block, block_tmp) \
{ \
LINEAR_TRANSFORMATION_INVERSE (block); \
SBOX_INVERSE (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkey[round]); \
round--; \
BLOCK_COPY (block, block_tmp); \
}
/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
storage. The result will be stored in BLOCK_TMP. This macro
increments `round'. */
#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round--; \
SBOX_INVERSE (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkeys[round]); \
round--; \
}
/* Convert the user provided key KEY of KEY_LENGTH bytes into the
internally used format. */
static void
serpent_key_prepare (const byte *key, unsigned int key_length,
serpent_key_t key_prepared)
{
int i;
/* Copy key. */
for (i = 0; i < key_length / 4; i++)
{
#ifdef WORDS_BIGENDIAN
key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
#else
key_prepared[i] = ((u32 *) key)[i];
#endif
}
if (i < 8)
{
/* Key must be padded according to the Serpent
specification. */
key_prepared[i] = 0x00000001;
for (i++; i < 8; i++)
key_prepared[i] = 0;
}
}
/* Derive the 33 subkeys from KEY and store them in SUBKEYS. */
static void
serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
{
u32 w_real[140]; /* The `prekey'. */
u32 k[132];
u32 *w = &w_real[8];
int i, j;
/* Initialize with key values. */
for (i = 0; i < 8; i++)
w[i - 8] = key[i];
/* Expand to intermediate key using the affine recurrence. */
for (i = 0; i < 132; i++)
w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
/* Calculate subkeys via S-Boxes, in bitslice mode. */
SBOX (3, w, k, 0);
SBOX (2, w, k, 4);
SBOX (1, w, k, 8);
SBOX (0, w, k, 12);
SBOX (7, w, k, 16);
SBOX (6, w, k, 20);
SBOX (5, w, k, 24);
SBOX (4, w, k, 28);
SBOX (3, w, k, 32);
SBOX (2, w, k, 36);
SBOX (1, w, k, 40);
SBOX (0, w, k, 44);
SBOX (7, w, k, 48);
SBOX (6, w, k, 52);
SBOX (5, w, k, 56);
SBOX (4, w, k, 60);
SBOX (3, w, k, 64);
SBOX (2, w, k, 68);
SBOX (1, w, k, 72);
SBOX (0, w, k, 76);
SBOX (7, w, k, 80);
SBOX (6, w, k, 84);
SBOX (5, w, k, 88);
SBOX (4, w, k, 92);
SBOX (3, w, k, 96);
SBOX (2, w, k, 100);
SBOX (1, w, k, 104);
SBOX (0, w, k, 108);
SBOX (7, w, k, 112);
SBOX (6, w, k, 116);
SBOX (5, w, k, 120);
SBOX (4, w, k, 124);
SBOX (3, w, k, 128);
/* Renumber subkeys. */
for (i = 0; i < ROUNDS + 1; i++)
for (j = 0; j < 4; j++)
subkeys[i][j] = k[4 * i + j];
}
/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */
static void
serpent_setkey_internal (serpent_context_t *context,
const byte *key, unsigned int key_length)
{
serpent_key_t key_prepared;
serpent_key_prepare (key, key_length, key_prepared);
serpent_subkeys_generate (key_prepared, context->keys);
_gcry_burn_stack (272 * sizeof (u32));
}
/* Initialize CTX with the key KEY of KEY_LENGTH bytes. */
static gcry_err_code_t
serpent_setkey (void *ctx,
const byte *key, unsigned int key_length)
{
serpent_context_t *context = ctx;
static const char *serpent_test_ret;
static int serpent_init_done;
gcry_err_code_t ret = GPG_ERR_NO_ERROR;
if (! serpent_init_done)
{
/* Execute a self-test the first time, Serpent is used. */
serpent_test_ret = serpent_test ();
if (serpent_test_ret)
log_error ("Serpent test failure: %s\n", serpent_test_ret);
serpent_init_done = 1;
}
if (serpent_test_ret)
ret = GPG_ERR_SELFTEST_FAILED;
else
{
serpent_setkey_internal (context, key, key_length);
_gcry_burn_stack (sizeof (serpent_key_t));
}
return ret;
}
static void
serpent_encrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
{
serpent_block_t b, b_next;
int round = 0;
#ifdef WORDS_BIGENDIAN
b[0] = byte_swap_32 (input[0]);
b[1] = byte_swap_32 (input[1]);
b[2] = byte_swap_32 (input[2]);
b[3] = byte_swap_32 (input[3]);
#else
b[0] = input[0];
b[1] = input[1];
b[2] = input[2];
b[3] = input[3];
#endif
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND_LAST (7, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
#endif
}
static void
serpent_decrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
{
serpent_block_t b, b_next;
int round = ROUNDS;
#ifdef WORDS_BIGENDIAN
b_next[0] = byte_swap_32 (input[0]);
b_next[1] = byte_swap_32 (input[1]);
b_next[2] = byte_swap_32 (input[2]);
b_next[3] = byte_swap_32 (input[3]);
#else
b_next[0] = input[0];
b_next[1] = input[1];
b_next[2] = input[2];
b_next[3] = input[3];
#endif
ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
#endif
}
static void
serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
{
serpent_context_t *context = ctx;
serpent_encrypt_internal (context,
(const u32 *) buffer_in, (u32 *) buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
static void
serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
{
serpent_context_t *context = ctx;
serpent_decrypt_internal (context,
(const u32 *) buffer_in,
(u32 *) buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
/* Serpent test. */
static const char *
serpent_test (void)
{
serpent_context_t context;
unsigned char scratch[16];
unsigned int i;
static struct test
{
int key_length;
unsigned char key[32];
unsigned char text_plain[16];
unsigned char text_cipher[16];
} test_data[] =
{
{
16,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
"\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
},
{
24,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
"\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
},
{
32,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
"\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
},
{
32,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
"\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
},
{
0
},
};
for (i = 0; test_data[i].key_length; i++)
{
serpent_setkey_internal (&context, test_data[i].key,
test_data[i].key_length);
serpent_encrypt_internal (&context,
(const u32 *) test_data[i].text_plain,
(u32 *) scratch);
if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{
case 16:
return "Serpent-128 test encryption failed.";
case 24:
return "Serpent-192 test encryption failed.";
case 32:
return "Serpent-256 test encryption failed.";
}
serpent_decrypt_internal (&context,
(const u32 *) test_data[i].text_cipher,
(u32 *) scratch);
if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{
case 16:
return "Serpent-128 test decryption failed.";
case 24:
return "Serpent-192 test decryption failed.";
case 32:
return "Serpent-256 test decryption failed.";
}
}
return NULL;
}
/* "SERPENT" is an alias for "SERPENT128". */
static const char *cipher_spec_serpent128_aliases[] =
{
"SERPENT",
NULL
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
{
"SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
{
"SERPENT192", NULL, NULL, 16, 192,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
{
"SERPENT256", NULL, NULL, 16, 256,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt
};

Some files were not shown because too many files have changed in this diff Show more