diff options
author | Romain Francoise <rfrancoise@debian.org> | 2014-04-15 19:34:32 +0200 |
---|---|---|
committer | Romain Francoise <rfrancoise@debian.org> | 2014-04-15 19:34:32 +0200 |
commit | c5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9 (patch) | |
tree | d4e2118cbd411caa1a0528eac831030109bc6e65 /src/libstrongswan/plugins | |
parent | 15fb7904f4431a6e7c305fd08732458f7f885e7e (diff) | |
download | vyos-strongswan-c5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9.tar.gz vyos-strongswan-c5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9.zip |
Import upstream version 5.1.3
Diffstat (limited to 'src/libstrongswan/plugins')
94 files changed, 4107 insertions, 3519 deletions
diff --git a/src/libstrongswan/plugins/acert/Makefile.am b/src/libstrongswan/plugins/acert/Makefile.am new file mode 100644 index 000000000..ba16f413a --- /dev/null +++ b/src/libstrongswan/plugins/acert/Makefile.am @@ -0,0 +1,17 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = \ + -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-acert.la +else +plugin_LTLIBRARIES = libstrongswan-acert.la +endif + +libstrongswan_acert_la_SOURCES = \ + acert_validator.h acert_validator.c \ + acert_plugin.h acert_plugin.c + +libstrongswan_acert_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/acert/Makefile.in b/src/libstrongswan/plugins/acert/Makefile.in new file mode 100644 index 000000000..3dd650d4b --- /dev/null +++ b/src/libstrongswan/plugins/acert/Makefile.in @@ -0,0 +1,759 @@ +# Makefile.in generated by automake 1.13.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libstrongswan/plugins/acert +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libstrongswan_acert_la_LIBADD = +am_libstrongswan_acert_la_OBJECTS = acert_validator.lo acert_plugin.lo +libstrongswan_acert_la_OBJECTS = $(am_libstrongswan_acert_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libstrongswan_acert_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_acert_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_acert_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_acert_la_rpath = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libstrongswan_acert_la_SOURCES) +DIST_SOURCES = $(libstrongswan_acert_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = \ + -rdynamic + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-acert.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-acert.la +libstrongswan_acert_la_SOURCES = \ + acert_validator.h acert_validator.c \ + acert_plugin.h acert_plugin.c + +libstrongswan_acert_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/acert/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/acert/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libstrongswan-acert.la: $(libstrongswan_acert_la_OBJECTS) $(libstrongswan_acert_la_DEPENDENCIES) $(EXTRA_libstrongswan_acert_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_acert_la_LINK) $(am_libstrongswan_acert_la_rpath) $(libstrongswan_acert_la_OBJECTS) $(libstrongswan_acert_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acert_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acert_validator.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pluginLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libstrongswan/plugins/acert/acert_plugin.c b/src/libstrongswan/plugins/acert/acert_plugin.c new file mode 100644 index 000000000..01d9ae3b8 --- /dev/null +++ b/src/libstrongswan/plugins/acert/acert_plugin.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include "acert_plugin.h" +#include "acert_validator.h" + +#include <library.h> + +typedef struct private_acert_plugin_t private_acert_plugin_t; + +/** + * private data of acert_plugin + */ +struct private_acert_plugin_t { + + /** + * public functions + */ + acert_plugin_t public; + + /** + * Validator implementation instance. + */ + acert_validator_t *validator; +}; + +METHOD(plugin_t, get_name, char*, + private_acert_plugin_t *this) +{ + return "acert"; +} + +/** + * Register validator + */ +static bool plugin_cb(private_acert_plugin_t *this, + plugin_feature_t *feature, bool reg, void *cb_data) +{ + if (reg) + { + lib->credmgr->add_validator(lib->credmgr, &this->validator->validator); + } + else + { + lib->credmgr->remove_validator(lib->credmgr, &this->validator->validator); + } + return TRUE; +} + +METHOD(plugin_t, get_features, int, + private_acert_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), + PLUGIN_PROVIDE(CUSTOM, "acert"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_acert_plugin_t *this) +{ + this->validator->destroy(this->validator); + free(this); +} + +/* + * see header file + */ +plugin_t *acert_plugin_create() +{ + private_acert_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + .validator = acert_validator_create(), + ); + + return &this->public.plugin; +} diff --git a/src/libstrongswan/plugins/acert/acert_plugin.h b/src/libstrongswan/plugins/acert/acert_plugin.h new file mode 100644 index 000000000..97d12936d --- /dev/null +++ b/src/libstrongswan/plugins/acert/acert_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup acert acert + * @ingroup plugins + * + * @defgroup acert_plugin acert_plugin + * @{ @ingroup acert + */ + +#ifndef ACERT_PLUGIN_H_ +#define ACERT_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct acert_plugin_t acert_plugin_t; + +/** + * X.509 attribute certificate group membership checking. + */ +struct acert_plugin_t { + + /** + * Implements plugin_t. interface. + */ + plugin_t plugin; +}; + +#endif /** ACERT_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/acert/acert_validator.c b/src/libstrongswan/plugins/acert/acert_validator.c new file mode 100644 index 000000000..ab15dba98 --- /dev/null +++ b/src/libstrongswan/plugins/acert/acert_validator.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#define _GNU_SOURCE +#include <library.h> + +#include "acert_validator.h" + +#include <credentials/certificates/x509.h> +#include <credentials/certificates/ac.h> + +typedef struct private_acert_validator_t private_acert_validator_t; + +/** + * Private data of an acert_validator_t object. + */ +struct private_acert_validator_t { + + /** + * Public acert_validator_t interface. + */ + acert_validator_t public; +}; + +/** + * Check if an AC can be trusted + */ +static bool verify(private_acert_validator_t *this, certificate_t *ac) +{ + certificate_t *issuer; + enumerator_t *enumerator; + bool verified = FALSE; + + if (!ac->get_validity(ac, NULL, NULL, NULL)) + { + return FALSE; + } + DBG1(DBG_CFG, "verifying attribute certificate issued by \"%Y\"", + ac->get_issuer(ac)); + enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, + ac->get_issuer(ac), TRUE); + while (enumerator->enumerate(enumerator, &issuer, NULL)) + { + if (issuer->get_validity(issuer, NULL, NULL, NULL)) + { + if (lib->credmgr->issued_by(lib->credmgr, ac, issuer, NULL)) + { + verified = TRUE; + break; + } + } + } + enumerator->destroy(enumerator); + + return verified; +} + +/** + * Apply AC group membership to auth config + */ +static void apply(private_acert_validator_t *this, ac_t *ac, auth_cfg_t *auth) +{ + enumerator_t *enumerator; + ac_group_type_t type; + chunk_t chunk; + + enumerator = ac->create_group_enumerator(ac); + while (enumerator->enumerate(enumerator, &type, &chunk)) + { + if (type == AC_GROUP_TYPE_STRING) + { + auth->add(auth, AUTH_RULE_GROUP, + identification_create_from_data(chunk)); + } + } + enumerator->destroy(enumerator); +} + +METHOD(cert_validator_t, validate, bool, + private_acert_validator_t *this, certificate_t *subject, + certificate_t *issuer, bool online, u_int pathlen, bool anchor, + auth_cfg_t *auth) +{ + /* for X.509 end entity certs only */ + if (pathlen == 0 && subject->get_type(subject) == CERT_X509) + { + x509_t *x509 = (x509_t*)subject; + enumerator_t *enumerator; + identification_t *id, *serial; + ac_t *ac; + + /* find attribute certificates by serial and issuer. A lookup by + * the holder DN would work as well, but RFC 5755 recommends the use + * of baseCertificateID. */ + serial = identification_create_from_encoding(ID_KEY_ID, + x509->get_serial(x509)); + enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, + CERT_X509_AC, KEY_ANY, serial, FALSE); + while (enumerator->enumerate(enumerator, &ac)) + { + id = ac->get_holderIssuer(ac); + if (id && id->equals(id, subject->get_issuer(subject))) + { + if (verify(this, &ac->certificate)) + { + apply(this, ac, auth); + } + } + } + enumerator->destroy(enumerator); + serial->destroy(serial); + } + return TRUE; +} + +METHOD(acert_validator_t, destroy, void, + private_acert_validator_t *this) +{ + free(this); +} + +/** + * See header + */ +acert_validator_t *acert_validator_create() +{ + private_acert_validator_t *this; + + INIT(this, + .public = { + .validator.validate = _validate, + .destroy = _destroy, + }, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/acert/acert_validator.h b/src/libstrongswan/plugins/acert/acert_validator.h new file mode 100644 index 000000000..507776f18 --- /dev/null +++ b/src/libstrongswan/plugins/acert/acert_validator.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup acert_validator acert_validator + * @{ @ingroup acert + */ + +#ifndef ACERT_VALIDATOR_H_ +#define ACERT_VALIDATOR_H_ + +#include <credentials/cert_validator.h> + +typedef struct acert_validator_t acert_validator_t; + +/** + * Attribute certificate group membership checking + */ +struct acert_validator_t { + + /** + * Implements cert_validator_t interface. + */ + cert_validator_t validator; + + /** + * Destroy a acert_validator_t. + */ + void (*destroy)(acert_validator_t *this); +}; + +/** + * Create a acert_validator instance. + */ +acert_validator_t *acert_validator_create(); + +#endif /** ACERT_VALIDATOR_H_ @}*/ diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in index 9e91e8671..f9c0750ed 100644 --- a/src/libstrongswan/plugins/aes/Makefile.in +++ b/src/libstrongswan/plugins/aes/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in index 4ea1e8f36..08f5e9453 100644 --- a/src/libstrongswan/plugins/af_alg/Makefile.in +++ b/src/libstrongswan/plugins/af_alg/Makefile.in @@ -374,7 +374,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in index 150e8d4d4..bfd9f2b6c 100644 --- a/src/libstrongswan/plugins/agent/Makefile.in +++ b/src/libstrongswan/plugins/agent/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in index f13a96421..1e3f69f96 100644 --- a/src/libstrongswan/plugins/blowfish/Makefile.in +++ b/src/libstrongswan/plugins/blowfish/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in index ed3f05681..b1e0f160b 100644 --- a/src/libstrongswan/plugins/ccm/Makefile.in +++ b/src/libstrongswan/plugins/ccm/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/ccm/ccm_aead.c b/src/libstrongswan/plugins/ccm/ccm_aead.c index 65eccb2db..6d4b2e13c 100644 --- a/src/libstrongswan/plugins/ccm/ccm_aead.c +++ b/src/libstrongswan/plugins/ccm/ccm_aead.c @@ -343,7 +343,8 @@ METHOD(aead_t, destroy, void, /** * See header */ -ccm_aead_t *ccm_aead_create(encryption_algorithm_t algo, size_t key_size) +ccm_aead_t *ccm_aead_create(encryption_algorithm_t algo, + size_t key_size, size_t salt_size) { private_ccm_aead_t *this; size_t icv_size; @@ -360,6 +361,11 @@ ccm_aead_t *ccm_aead_create(encryption_algorithm_t algo, size_t key_size) default: return NULL; } + if (salt_size && salt_size != SALT_SIZE) + { + /* currently not supported */ + return NULL; + } switch (algo) { case ENCR_AES_CCM_ICV8: diff --git a/src/libstrongswan/plugins/ccm/ccm_aead.h b/src/libstrongswan/plugins/ccm/ccm_aead.h index 79ab31804..0f1ec09a7 100644 --- a/src/libstrongswan/plugins/ccm/ccm_aead.h +++ b/src/libstrongswan/plugins/ccm/ccm_aead.h @@ -44,8 +44,10 @@ struct ccm_aead_t { * * @param algo algorithm to implement, a CCM mode * @param key_size key size in bytes + * @param salt_size size of implicit salt length * @return aead, NULL if not supported */ -ccm_aead_t *ccm_aead_create(encryption_algorithm_t algo, size_t key_size); +ccm_aead_t *ccm_aead_create(encryption_algorithm_t algo, size_t key_size, + size_t salt_size); #endif /** CCM_AEAD_H_ @}*/ diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in index 620d8359f..a609e7177 100644 --- a/src/libstrongswan/plugins/cmac/Makefile.in +++ b/src/libstrongswan/plugins/cmac/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in index 060287d1c..654800b65 100644 --- a/src/libstrongswan/plugins/constraints/Makefile.in +++ b/src/libstrongswan/plugins/constraints/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in index ff34435a2..b6789e76d 100644 --- a/src/libstrongswan/plugins/ctr/Makefile.in +++ b/src/libstrongswan/plugins/ctr/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in index a756a0a7e..67a92b3c2 100644 --- a/src/libstrongswan/plugins/curl/Makefile.in +++ b/src/libstrongswan/plugins/curl/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in index ca79430c9..fb38b0738 100644 --- a/src/libstrongswan/plugins/des/Makefile.in +++ b/src/libstrongswan/plugins/des/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in index b94b644c0..6986a8156 100644 --- a/src/libstrongswan/plugins/dnskey/Makefile.in +++ b/src/libstrongswan/plugins/dnskey/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in index 3bb540d90..71a61f617 100644 --- a/src/libstrongswan/plugins/fips_prf/Makefile.in +++ b/src/libstrongswan/plugins/fips_prf/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in index 7bce3c983..dbf9d1169 100644 --- a/src/libstrongswan/plugins/gcm/Makefile.in +++ b/src/libstrongswan/plugins/gcm/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/gcm/gcm_aead.c b/src/libstrongswan/plugins/gcm/gcm_aead.c index ba5f2e4b3..4ab17017f 100644 --- a/src/libstrongswan/plugins/gcm/gcm_aead.c +++ b/src/libstrongswan/plugins/gcm/gcm_aead.c @@ -375,7 +375,8 @@ METHOD(aead_t, destroy, void, /** * See header */ -gcm_aead_t *gcm_aead_create(encryption_algorithm_t algo, size_t key_size) +gcm_aead_t *gcm_aead_create(encryption_algorithm_t algo, + size_t key_size, size_t salt_size) { private_gcm_aead_t *this; size_t icv_size; @@ -392,6 +393,11 @@ gcm_aead_t *gcm_aead_create(encryption_algorithm_t algo, size_t key_size) default: return NULL; } + if (salt_size && salt_size != SALT_SIZE) + { + /* currently not supported */ + return NULL; + } switch (algo) { case ENCR_AES_GCM_ICV8: diff --git a/src/libstrongswan/plugins/gcm/gcm_aead.h b/src/libstrongswan/plugins/gcm/gcm_aead.h index 846c3c76c..5c09477c3 100644 --- a/src/libstrongswan/plugins/gcm/gcm_aead.h +++ b/src/libstrongswan/plugins/gcm/gcm_aead.h @@ -44,8 +44,10 @@ struct gcm_aead_t { * * @param algo algorithm to implement, a gcm mode * @param key_size key size in bytes + * @param salt_size size of implicit salt length * @return aead, NULL if not supported */ -gcm_aead_t *gcm_aead_create(encryption_algorithm_t algo, size_t key_size); +gcm_aead_t *gcm_aead_create(encryption_algorithm_t algo, size_t key_size, + size_t salt_size); #endif /** GCM_AEAD_H_ @}*/ diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in index 4ce3cf919..731375dcd 100644 --- a/src/libstrongswan/plugins/gcrypt/Makefile.in +++ b/src/libstrongswan/plugins/gcrypt/Makefile.in @@ -374,7 +374,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in index 73e0645b0..6b63e192d 100644 --- a/src/libstrongswan/plugins/gmp/Makefile.in +++ b/src/libstrongswan/plugins/gmp/Makefile.in @@ -371,7 +371,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in index f5e38fa90..d255cc95d 100644 --- a/src/libstrongswan/plugins/hmac/Makefile.in +++ b/src/libstrongswan/plugins/hmac/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/keychain/Makefile.in b/src/libstrongswan/plugins/keychain/Makefile.in index 42093e413..38a478b77 100644 --- a/src/libstrongswan/plugins/keychain/Makefile.in +++ b/src/libstrongswan/plugins/keychain/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in index 7f14fbf8e..bd5bd43f2 100644 --- a/src/libstrongswan/plugins/ldap/Makefile.in +++ b/src/libstrongswan/plugins/ldap/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in index bdd446cd3..a5caf8df5 100644 --- a/src/libstrongswan/plugins/md4/Makefile.in +++ b/src/libstrongswan/plugins/md4/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in index 32aac7bfa..c44893149 100644 --- a/src/libstrongswan/plugins/md5/Makefile.in +++ b/src/libstrongswan/plugins/md5/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in index a35f8051b..fb36d16a2 100644 --- a/src/libstrongswan/plugins/mysql/Makefile.in +++ b/src/libstrongswan/plugins/mysql/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in index 25437bdb8..60e45db7c 100644 --- a/src/libstrongswan/plugins/nonce/Makefile.in +++ b/src/libstrongswan/plugins/nonce/Makefile.in @@ -371,7 +371,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/ntru/Makefile.am b/src/libstrongswan/plugins/ntru/Makefile.am index b33cbc8c9..e241554b5 100644 --- a/src/libstrongswan/plugins/ntru/Makefile.am +++ b/src/libstrongswan/plugins/ntru/Makefile.am @@ -12,21 +12,15 @@ endif libstrongswan_ntru_la_SOURCES = \ ntru_plugin.h ntru_plugin.c \ + ntru_convert.h ntru_convert.c \ ntru_drbg.h ntru_drbg.c \ ntru_ke.h ntru_ke.c \ ntru_mgf1.h ntru_mgf1.c \ + ntru_param_set.h ntru_param_set.c \ ntru_poly.h ntru_poly.c \ - ntru_trits.h ntru_trits.c \ - ntru_crypto/ntru_crypto.h \ - ntru_crypto/ntru_crypto_ntru_convert.h \ - ntru_crypto/ntru_crypto_ntru_convert.c \ - ntru_crypto/ntru_crypto_ntru_encrypt.c \ - ntru_crypto/ntru_crypto_ntru_encrypt_key.h \ - ntru_crypto/ntru_crypto_ntru_encrypt_key.c \ - ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h \ - ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c \ - ntru_crypto/ntru_crypto_ntru_poly.h \ - ntru_crypto/ntru_crypto_ntru_poly.c + ntru_public_key.h ntru_public_key.c \ + ntru_private_key.h ntru_private_key.c \ + ntru_trits.h ntru_trits.c libstrongswan_ntru_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in index af192d203..38258048f 100644 --- a/src/libstrongswan/plugins/ntru/Makefile.in +++ b/src/libstrongswan/plugins/ntru/Makefile.in @@ -128,14 +128,10 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_ntru_la_LIBADD = -am__dirstamp = $(am__leading_dot)dirstamp -am_libstrongswan_ntru_la_OBJECTS = ntru_plugin.lo ntru_drbg.lo \ - ntru_ke.lo ntru_mgf1.lo ntru_poly.lo ntru_trits.lo \ - ntru_crypto/ntru_crypto_ntru_convert.lo \ - ntru_crypto/ntru_crypto_ntru_encrypt.lo \ - ntru_crypto/ntru_crypto_ntru_encrypt_key.lo \ - ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.lo \ - ntru_crypto/ntru_crypto_ntru_poly.lo +am_libstrongswan_ntru_la_OBJECTS = ntru_plugin.lo ntru_convert.lo \ + ntru_drbg.lo ntru_ke.lo ntru_mgf1.lo ntru_param_set.lo \ + ntru_poly.lo ntru_public_key.lo ntru_private_key.lo \ + ntru_trits.lo libstrongswan_ntru_la_OBJECTS = $(am_libstrongswan_ntru_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -377,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ @@ -427,21 +422,15 @@ AM_CFLAGS = \ @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-ntru.la libstrongswan_ntru_la_SOURCES = \ ntru_plugin.h ntru_plugin.c \ + ntru_convert.h ntru_convert.c \ ntru_drbg.h ntru_drbg.c \ ntru_ke.h ntru_ke.c \ ntru_mgf1.h ntru_mgf1.c \ + ntru_param_set.h ntru_param_set.c \ ntru_poly.h ntru_poly.c \ - ntru_trits.h ntru_trits.c \ - ntru_crypto/ntru_crypto.h \ - ntru_crypto/ntru_crypto_ntru_convert.h \ - ntru_crypto/ntru_crypto_ntru_convert.c \ - ntru_crypto/ntru_crypto_ntru_encrypt.c \ - ntru_crypto/ntru_crypto_ntru_encrypt_key.h \ - ntru_crypto/ntru_crypto_ntru_encrypt_key.c \ - ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h \ - ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c \ - ntru_crypto/ntru_crypto_ntru_poly.h \ - ntru_crypto/ntru_crypto_ntru_poly.c + ntru_public_key.h ntru_public_key.c \ + ntru_private_key.h ntru_private_key.c \ + ntru_trits.h ntru_trits.c libstrongswan_ntru_la_LDFLAGS = -module -avoid-version all: all-am @@ -524,47 +513,26 @@ clean-pluginLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } -ntru_crypto/$(am__dirstamp): - @$(MKDIR_P) ntru_crypto - @: > ntru_crypto/$(am__dirstamp) -ntru_crypto/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) ntru_crypto/$(DEPDIR) - @: > ntru_crypto/$(DEPDIR)/$(am__dirstamp) -ntru_crypto/ntru_crypto_ntru_convert.lo: ntru_crypto/$(am__dirstamp) \ - ntru_crypto/$(DEPDIR)/$(am__dirstamp) -ntru_crypto/ntru_crypto_ntru_encrypt.lo: ntru_crypto/$(am__dirstamp) \ - ntru_crypto/$(DEPDIR)/$(am__dirstamp) -ntru_crypto/ntru_crypto_ntru_encrypt_key.lo: \ - ntru_crypto/$(am__dirstamp) \ - ntru_crypto/$(DEPDIR)/$(am__dirstamp) -ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.lo: \ - ntru_crypto/$(am__dirstamp) \ - ntru_crypto/$(DEPDIR)/$(am__dirstamp) -ntru_crypto/ntru_crypto_ntru_poly.lo: ntru_crypto/$(am__dirstamp) \ - ntru_crypto/$(DEPDIR)/$(am__dirstamp) libstrongswan-ntru.la: $(libstrongswan_ntru_la_OBJECTS) $(libstrongswan_ntru_la_DEPENDENCIES) $(EXTRA_libstrongswan_ntru_la_DEPENDENCIES) $(AM_V_CCLD)$(libstrongswan_ntru_la_LINK) $(am_libstrongswan_ntru_la_rpath) $(libstrongswan_ntru_la_OBJECTS) $(libstrongswan_ntru_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f ntru_crypto/*.$(OBJEXT) - -rm -f ntru_crypto/*.lo distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_convert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_drbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_ke.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_mgf1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_param_set.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_poly.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_private_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_public_key.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_trits.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_convert.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_encrypt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_encrypt_key.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_encrypt_param_sets.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_poly.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -595,7 +563,6 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs - -rm -rf ntru_crypto/.libs ntru_crypto/_libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique @@ -712,8 +679,6 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ntru_crypto/$(DEPDIR)/$(am__dirstamp) - -rm -f ntru_crypto/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -724,7 +689,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) ntru_crypto/$(DEPDIR) + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -770,7 +735,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) ntru_crypto/$(DEPDIR) + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/src/libstrongswan/plugins/ntru/ntru_convert.c b/src/libstrongswan/plugins/ntru/ntru_convert.c new file mode 100644 index 000000000..6330b2e39 --- /dev/null +++ b/src/libstrongswan/plugins/ntru/ntru_convert.c @@ -0,0 +1,452 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Copyright (C) 2009-2013 Security Innovation + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include <stdlib.h> +#include <string.h> + +#include "ntru_convert.h" + +/** + * 3-bit to 2-trit conversion tables: 2 represents -1 + */ +static uint8_t const bits_2_trit1[] = {0, 0, 0, 1, 1, 1, 2, 2}; +static uint8_t const bits_2_trit2[] = {0, 1, 2, 0, 1, 2, 0, 1}; + +/** + * See header. + */ +void ntru_bits_2_trits(uint8_t const *octets, uint16_t num_trits, uint8_t *trits) +{ + uint32_t bits24, bits3, shift; + + while (num_trits >= 16) + { + /* get next three octets */ + bits24 = ((uint32_t)(*octets++)) << 16; + bits24 |= ((uint32_t)(*octets++)) << 8; + bits24 |= (uint32_t)(*octets++); + + /* for each 3 bits in the three octets, output 2 trits */ + bits3 = (bits24 >> 21) & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + bits3 = (bits24 >> 18) & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + bits3 = (bits24 >> 15) & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + bits3 = (bits24 >> 12) & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + bits3 = (bits24 >> 9) & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + bits3 = (bits24 >> 6) & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + bits3 = (bits24 >> 3) & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + bits3 = bits24 & 0x7; + *trits++ = bits_2_trit1[bits3]; + *trits++ = bits_2_trit2[bits3]; + + num_trits -= 16; + } + if (num_trits == 0) + { + return; + } + + /* get three octets */ + bits24 = ((uint32_t)(*octets++)) << 16; + bits24 |= ((uint32_t)(*octets++)) << 8; + bits24 |= (uint32_t)(*octets++); + + shift = 21; + while (num_trits) + { + /** + * for each 3 bits in the three octets, output up to 2 trits + * until all trits needed are produced + */ + bits3 = (bits24 >> shift) & 0x7; + shift -= 3; + *trits++ = bits_2_trit1[bits3]; + if (--num_trits) + { + *trits++ = bits_2_trit2[bits3]; + --num_trits; + } + } +} + +/** + * See header. + */ +bool ntru_trits_2_bits(uint8_t const *trits, uint32_t num_trits, uint8_t *octets) +{ + bool all_trits_valid = TRUE; + uint32_t bits24, bits3, shift; + + while (num_trits >= 16) + { + /* convert each 2 trits to 3 bits and pack */ + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 = (bits3 << 21); + + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= (bits3 << 18); + + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= (bits3 << 15); + + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= (bits3 << 12); + + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= (bits3 << 9); + + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= (bits3 << 6); + + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= (bits3 << 3); + + bits3 = *trits++ * 3; + bits3 += *trits++; + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= bits3; + + num_trits -= 16; + + /* output three octets */ + *octets++ = (uint8_t)((bits24 >> 16) & 0xff); + *octets++ = (uint8_t)((bits24 >> 8) & 0xff); + *octets++ = (uint8_t)(bits24 & 0xff); + } + + bits24 = 0; + shift = 21; + while (num_trits) + { + /* convert each 2 trits to 3 bits and pack */ + bits3 = *trits++ * 3; + if (--num_trits) + { + bits3 += *trits++; + --num_trits; + } + if (bits3 > 7) + { + bits3 = 7; + all_trits_valid = FALSE; + } + bits24 |= (bits3 << shift); + shift -= 3; + } + + /* output three octets */ + *octets++ = (uint8_t)((bits24 >> 16) & 0xff); + *octets++ = (uint8_t)((bits24 >> 8) & 0xff); + *octets++ = (uint8_t)(bits24 & 0xff); + + return all_trits_valid; +} + +/** + * See header + */ +void ntru_coeffs_mod4_2_octets(uint16_t num_coeffs, uint16_t const *coeffs, uint8_t *octets) +{ + uint8_t bits2; + int shift, i; + + *octets = 0; + shift = 6; + for (i = 0; i < num_coeffs; i++) + { + bits2 = (uint8_t)(coeffs[i] & 0x3); + *octets |= bits2 << shift; + shift -= 2; + if (shift < 0) + { + ++octets; + *octets = 0; + shift = 6; + } + } +} + +/** + * See header. + */ +void ntru_trits_2_octet(uint8_t const *trits, uint8_t *octet) +{ + int i; + + *octet = 0; + for (i = 4; i >= 0; i--) + { + *octet = (*octet * 3) + trits[i]; + } +} + +/** + * See header. + */ +void ntru_octet_2_trits(uint8_t octet, uint8_t *trits) +{ + int i; + + for (i = 0; i < 5; i++) + { + trits[i] = octet % 3; + octet = (octet - trits[i]) / 3; + } +} + +/** + * See header. + */ +void ntru_indices_2_trits(uint16_t in_len, uint16_t const *in, bool plus1, + uint8_t *out) +{ + uint8_t trit = plus1 ? 1 : 2; + int i; + + for (i = 0; i < in_len; i++) + { + out[in[i]] = trit; + } +} + +/** + * See header. + */ +void ntru_packed_trits_2_indices(uint8_t const *in, uint16_t num_trits, + uint16_t *indices_plus1, + uint16_t *indices_minus1) +{ + uint8_t trits[5]; + uint16_t i = 0; + int j; + + while (num_trits >= 5) + { + ntru_octet_2_trits(*in++, trits); + num_trits -= 5; + for (j = 0; j < 5; j++, i++) + { + if (trits[j] == 1) + { + *indices_plus1 = i; + ++indices_plus1; + } + else if (trits[j] == 2) + { + *indices_minus1 = i; + ++indices_minus1; + } + } + } + if (num_trits) + { + ntru_octet_2_trits(*in, trits); + for (j = 0; num_trits && (j < 5); j++, i++) + { + if (trits[j] == 1) + { + *indices_plus1 = i; + ++indices_plus1; + } + else if (trits[j] == 2) + { + *indices_minus1 = i; + ++indices_minus1; + } + --num_trits; + } + } +} + +/** + * See header. + */ +void ntru_indices_2_packed_trits(uint16_t const *indices, uint16_t num_plus1, + uint16_t num_minus1, uint16_t num_trits, + uint8_t *buf, uint8_t *out) +{ + /* convert indices to an array of trits */ + memset(buf, 0, num_trits); + ntru_indices_2_trits(num_plus1, indices, TRUE, buf); + ntru_indices_2_trits(num_minus1, indices + num_plus1, FALSE, buf); + + /* pack the array of trits */ + while (num_trits >= 5) + { + ntru_trits_2_octet(buf, out); + num_trits -= 5; + buf += 5; + ++out; + } + if (num_trits) + { + uint8_t trits[5]; + + memcpy(trits, buf, num_trits); + memset(trits + num_trits, 0, sizeof(trits) - num_trits); + ntru_trits_2_octet(trits, out); + } +} + +/** + * See header + */ +void ntru_elements_2_octets(uint16_t in_len, uint16_t const *in, uint8_t n_bits, + uint8_t *out) +{ + uint16_t temp; + int shift, i; + + /* pack */ + temp = 0; + shift = n_bits - 8; + i = 0; + while (i < in_len) + { + /* add bits to temp to fill an octet and output the octet */ + temp |= in[i] >> shift; + *out++ = (uint8_t)(temp & 0xff); + shift = 8 - shift; + if (shift < 1) + { + /* next full octet is in current input word */ + shift += n_bits; + temp = 0; + } + else + { + /* put remaining bits of input word in temp as partial octet, + * and increment index to next input word + */ + temp = in[i] << (uint16_t)shift; + ++i; + } + shift = n_bits - shift; + } + + /* output any bits remaining in last input word */ + if (shift != n_bits - 8) + { + *out++ = (uint8_t)(temp & 0xff); + } +} + + +/** + * See header. + */ +void ntru_octets_2_elements(uint16_t in_len, uint8_t const *in, uint8_t n_bits, + uint16_t *out) +{ + uint16_t temp; + uint16_t mask = (1 << n_bits) - 1; + int shift, i; + + /* unpack */ + temp = 0; + shift = n_bits; + i = 0; + while (i < in_len) + { + shift = 8 - shift; + if (shift < 0) + { + /* the current octet will not fill the current element */ + shift += n_bits; + } + else + { + /* add bits from the current octet to fill the current element and + * output the element + */ + temp |= ((uint16_t)in[i]) >> shift; + *out++ = temp & mask; + temp = 0; + } + + /* add the remaining bits of the current octet to start an element */ + shift = n_bits - shift; + temp |= ((uint16_t)in[i]) << shift; + ++i; + } +} diff --git a/src/libstrongswan/plugins/ntru/ntru_convert.h b/src/libstrongswan/plugins/ntru/ntru_convert.h new file mode 100644 index 000000000..31594b1f6 --- /dev/null +++ b/src/libstrongswan/plugins/ntru/ntru_convert.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Copyright (C) 2009-2013 Security Innovation + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup ntru_convert ntru_convert + * @{ @ingroup ntru_p + */ + +#ifndef NTRU_CONVERT_H_ +#define NTRU_CONVERT_H_ + +#include <library.h> + +/** + * Each 3 bits in an array of octets is converted to 2 trits in an array + * of trits. + * + * @param octets pointer to array of octets + * @param num_trits number of trits to produce + * @param trits address for array of trits + */ +void ntru_bits_2_trits(uint8_t const *octets, uint16_t num_trits, + uint8_t *trits); + +/** + * Each 2 trits in an array of trits is converted to 3 bits, and the bits + * are packed in an array of octets. A multiple of 3 octets is output. + * Any bits in the final octets not derived from trits are zero. + * + * @param trits pointer to array of trits + * @param num_trits number of trits to convert + * @param octets address for array of octets + * @return TRUE if all trits were valid + * FALSE if invalid trits were found + */ +bool ntru_trits_2_bits(uint8_t const *trits, uint32_t num_trits, + uint8_t *octets); + +/** + * Takes an array of coefficients mod 4 and packs the results into an + * octet string. + * + * @param num_coeffs number of coefficients + * @param coeffs pointer to coefficients + * @param octets address for octets + */ +void ntru_coeffs_mod4_2_octets(uint16_t num_coeffs, uint16_t const *coeffs, + uint8_t *octets); + +/** + * Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1). + * + * @param trits pointer to trits + * @param octet address for octet + */ +void ntru_trits_2_octet(uint8_t const *trits, uint8_t *octet); + +/** + * Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1). + * + * @param octet octet to be unpacked + * @param trits address for trits + */ +void ntru_octet_2_trits(uint8_t octet, uint8_t *trits); + +/** + * + * Converts a list of the nonzero indices of a polynomial into an array of + * trits. + * + * @param in_len no. of indices + * @param in pointer to list of indices + * @param plus1 if list is +1 coefficients + * @param out address of output polynomial + */ +void ntru_indices_2_trits(uint16_t in_len, uint16_t const *in, bool plus1, + uint8_t *out); + +/** + * Unpacks an array of N trits and creates a list of array indices + * corresponding to trits = +1, and list of array indices corresponding to + * trits = -1. + * + * @param in pointer to packed-trit octets + * @param num_trits no. of packed trits + * @param indices_plus1 address for indices of +1 trits + * @param indices_minus1 address for indices of -1 trits + */ +void ntru_packed_trits_2_indices(uint8_t const *in, uint16_t num_trits, + uint16_t *indices_plus1, + uint16_t *indices_minus1); + +/** + * Takes a list of array indices corresponding to elements whose values + * are +1 or -1, and packs the N-element array of trits described by these + * lists into octets, 5 trits per octet. + * + * @param indices pointer to indices + * @param num_plus1 no. of indices for +1 trits + * @param num_minus1 no. of indices for -1 trits + * @param num_trits N, no. of trits in array + * @param buf temp buf, N octets + * @param out address for packed octet + */ +void ntru_indices_2_packed_trits(uint16_t const *indices, uint16_t num_plus1, + uint16_t num_minus1, uint16_t num_trits, + uint8_t *buf, uint8_t *out); + +/** + * Packs an array of n-bit elements into an array of + * ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16. + * + * @param in_len no. of elements to be packed + * @param in ptr to elements to be packed + * @param n_bits no. of bits in input element + * @param out addr for output octets + */ +void ntru_elements_2_octets(uint16_t in_len, uint16_t const *in, uint8_t n_bits, + uint8_t *out); + +/** + * Unpacks an octet string into an array of ((in_len * 8) / n_bits) + * n-bit elements, 8 < n < 16. Any extra bits are discarded. + * + * @param in_len no. of octets to be unpacked + * @param in ptr to octets to be unpacked + * @param n_bits no. of bits in output element + * @param out addr for output elements + */ +void ntru_octets_2_elements(uint16_t in_len, uint8_t const *in, uint8_t n_bits, + uint16_t *out); + +#endif /** NTRU_CONVERT_H_ @}*/ diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto.h deleted file mode 100644 index 72f47035e..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto.h +++ /dev/null @@ -1,235 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto.h is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - - -/****************************************************************************** - * - * File: ntru_crypto.h - * - * Contents: Public header file for NTRUEncrypt. - * - *****************************************************************************/ - -#ifndef NTRU_CRYPTO_H -#define NTRU_CRYPTO_H - -#include <library.h> - -#include "ntru_drbg.h" - -#if !defined( NTRUCALL ) - #if !defined(WIN32) || defined (NTRUCRYPTO_STATIC) - // Linux, or a Win32 static library - #define NTRUCALL extern uint32_t - #elif defined (NTRUCRYPTO_EXPORTS) - // Win32 DLL build - #define NTRUCALL extern __declspec(dllexport) uint32_t - #else - // Win32 DLL import - #define NTRUCALL extern __declspec(dllimport) uint32_t - #endif -#endif /* NTRUCALL */ - -/* parameter set ID list */ - -typedef enum _NTRU_ENCRYPT_PARAM_SET_ID { - NTRU_EES401EP1, - NTRU_EES449EP1, - NTRU_EES677EP1, - NTRU_EES1087EP2, - NTRU_EES541EP1, - NTRU_EES613EP1, - NTRU_EES887EP1, - NTRU_EES1171EP1, - NTRU_EES659EP1, - NTRU_EES761EP1, - NTRU_EES1087EP1, - NTRU_EES1499EP1, - NTRU_EES401EP2, - NTRU_EES439EP1, - NTRU_EES593EP1, - NTRU_EES743EP1, -} NTRU_ENCRYPT_PARAM_SET_ID; - - -/* error codes */ - -#define NTRU_OK 0 -#define NTRU_FAIL 1 -#define NTRU_BAD_PARAMETER 2 -#define NTRU_BAD_LENGTH 3 -#define NTRU_BUFFER_TOO_SMALL 4 -#define NTRU_INVALID_PARAMETER_SET 5 -#define NTRU_BAD_PUBLIC_KEY 6 -#define NTRU_BAD_PRIVATE_KEY 7 -#define NTRU_OUT_OF_MEMORY 8 -#define NTRU_BAD_ENCODING 9 -#define NTRU_OID_NOT_RECOGNIZED 10 -#define NTRU_DRBG_FAIL 11 -#define NTRU_MGF1_FAIL 12 - -/* function declarations */ - -/* ntru_crypto_ntru_encrypt - * - * Implements NTRU encryption (SVES) for the parameter set specified in - * the public key blob. - * - * Before invoking this function, a DRBG must be instantiated using - * ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that - * instantiation the requested security strength must be at least as large - * as the security strength of the NTRU parameter set being used. - * Failure to instantiate the DRBG with the proper security strength will - * result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH. - * - * The required minimum size of the output ciphertext buffer (ct) may be - * queried by invoking this function with ct = NULL. In this case, no - * encryption is performed, NTRU_OK is returned, and the required minimum - * size for ct is returned in ct_len. - * - * When ct != NULL, at invocation *ct_len must be the size of the ct buffer. - * Upon return it is the actual size of the ciphertext. - * - * Returns NTRU_OK if successful. - * Returns NTRU_DRBG_FAIL if the DRBG handle is invalid. - * Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL. - * Returns NTRU_BAD_LENGTH if a length argument (pubkey_blob_len or pt_len) is - * zero, or if pt_len exceeds the maximum plaintext length for the parameter set. - * Returns NTRU_BAD_PUBLIC_KEY if the public-key blob is invalid - * (unknown format, corrupt, bad length). - * Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small. - * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap. - */ - -NTRUCALL -ntru_crypto_ntru_encrypt( - ntru_drbg_t *drbg , /* in - handle for DRBG */ - uint16_t pubkey_blob_len, /* in - no. of octets in public key - blob */ - uint8_t const *pubkey_blob, /* in - pointer to public key */ - uint16_t pt_len, /* in - no. of octets in plaintext */ - uint8_t const *pt, /* in - pointer to plaintext */ - uint16_t *ct_len, /* in/out - no. of octets in ct, addr for - no. of octets in ciphertext */ - uint8_t *ct); /* out - address for ciphertext */ - - -/* ntru_crypto_ntru_decrypt - * - * Implements NTRU decryption (SVES) for the parameter set specified in - * the private key blob. - * - * The maximum size of the output plaintext may be queried by invoking - * this function with pt = NULL. In this case, no decryption is performed, - * NTRU_OK is returned, and the maximum size the plaintext could be is - * returned in pt_len. - * Note that until the decryption is performed successfully, the actual size - * of the resulting plaintext cannot be known. - * - * When pt != NULL, at invocation *pt_len must be the size of the pt buffer. - * Upon return it is the actual size of the plaintext. - * - * Returns NTRU_OK if successful. - * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pt) is NULL. - * Returns NTRU_BAD_LENGTH if a length argument (privkey_blob) is zero, or if - * ct_len is invalid for the parameter set. - * Returns NTRU_BAD_PRIVATE_KEY if the private-key blob is invalid - * (unknown format, corrupt, bad length). - * Returns NTRU_BUFFER_TOO_SMALL if the plaintext buffer is too small. - * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap. - * Returns NTRU_FAIL if a decryption error occurs. - */ - -NTRUCALL -ntru_crypto_ntru_decrypt( - uint16_t privkey_blob_len, /* in - no. of octets in private key - blob */ - uint8_t const *privkey_blob, /* in - pointer to private key */ - uint16_t ct_len, /* in - no. of octets in ciphertext */ - uint8_t const *ct, /* in - pointer to ciphertext */ - uint16_t *pt_len, /* in/out - no. of octets in pt, addr for - no. of octets in plaintext */ - uint8_t *pt); /* out - address for plaintext */ - - -/* ntru_crypto_ntru_encrypt_keygen - * - * Implements key generation for NTRUEncrypt for the parameter set specified. - * - * Before invoking this function, a DRBG must be instantiated using - * ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that - * instantiation the requested security strength must be at least as large - * as the security strength of the NTRU parameter set being used. - * Failure to instantiate the DRBG with the proper security strength will - * result in this function returning NTRU_DRBG_FAIL. - * - * The required minimum size of the output public-key buffer (pubkey_blob) - * may be queried by invoking this function with pubkey_blob = NULL. - * In this case, no key generation is performed, NTRU_OK is returned, and - * the required minimum size for pubkey_blob is returned in pubkey_blob_len. - * - * The required minimum size of the output private-key buffer (privkey_blob) - * may be queried by invoking this function with privkey_blob = NULL. - * In this case, no key generation is performed, NTRU_OK is returned, and - * the required minimum size for privkey_blob is returned in privkey_blob_len. - * - * The required minimum sizes of both pubkey_blob and privkey_blob may be - * queried as described above, in a single invocation of this function. - * - * When pubkey_blob != NULL and privkey_blob != NULL, at invocation - * *pubkey_blob_len must be the size of the pubkey_blob buffer and - * *privkey_blob_len must be the size of the privkey_blob buffer. - * Upon return, *pubkey_blob_len is the actual size of the public-key blob - * and *privkey_blob_len is the actual size of the private-key blob. - * - * Returns NTRU_OK if successful. - * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pubkey_blob - * or privkey_blob) is NULL. - * Returns NTRU_INVALID_PARAMETER_SET if the parameter-set ID is invalid. - * Returns NTRU_BAD_LENGTH if a length argument is invalid. - * Returns NTRU_BUFFER_TOO_SMALL if either the pubkey_blob buffer or the - * privkey_blob buffer is too small. - * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap. - * Returns NTRU_FAIL if the polynomial generated for f is not invertible in - * (Z/qZ)[X]/(X^N - 1), which is extremely unlikely. - * Should this occur, this function should simply be invoked again. - */ - -NTRUCALL -ntru_crypto_ntru_encrypt_keygen( - ntru_drbg_t *drbg, /* in - handle of DRBG */ - NTRU_ENCRYPT_PARAM_SET_ID param_set_id, /* in - parameter set ID */ - uint16_t *pubkey_blob_len, /* in/out - no. of octets in - pubkey_blob, addr - for no. of octets - in pubkey_blob */ - uint8_t *pubkey_blob, /* out - address for - public key blob */ - uint16_t *privkey_blob_len, /* in/out - no. of octets in - privkey_blob, addr - for no. of octets - in privkey_blob */ - uint8_t *privkey_blob); /* out - address for - private key blob */ -#endif /* NTRU_CRYPTO_H */ diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.c deleted file mode 100644 index 3d6dfde41..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.c +++ /dev/null @@ -1,581 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_convert.c is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -/****************************************************************************** - * - * File: ntru_crypto_ntru_convert.c - * - * Contents: Conversion routines for NTRUEncrypt, including packing, unpacking, - * and others. - * - *****************************************************************************/ - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include "ntru_crypto_ntru_convert.h" - - -/* 3-bit to 2-trit conversion tables: 2 represents -1 */ - -static uint8_t const bits_2_trit1[] = {0, 0, 0, 1, 1, 1, 2, 2}; -static uint8_t const bits_2_trit2[] = {0, 1, 2, 0, 1, 2, 0, 1}; - - -/* ntru_bits_2_trits - * - * Each 3 bits in an array of octets is converted to 2 trits in an array - * of trits. - * - * The octet array may overlap the end of the trit array. - */ - -void -ntru_bits_2_trits( - uint8_t const *octets, /* in - pointer to array of octets */ - uint16_t num_trits, /* in - number of trits to produce */ - uint8_t *trits) /* out - address for array of trits */ -{ - uint32_t bits24; - uint32_t bits3; - uint32_t shift; - - assert(octets); - assert(trits); - - while (num_trits >= 16) { - - /* get next three octets */ - - bits24 = ((uint32_t)(*octets++)) << 16; - bits24 |= ((uint32_t)(*octets++)) << 8; - bits24 |= (uint32_t)(*octets++); - - /* for each 3 bits in the three octets, output 2 trits */ - - bits3 = (bits24 >> 21) & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - bits3 = (bits24 >> 18) & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - bits3 = (bits24 >> 15) & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - bits3 = (bits24 >> 12) & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - bits3 = (bits24 >> 9) & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - bits3 = (bits24 >> 6) & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - bits3 = (bits24 >> 3) & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - bits3 = bits24 & 0x7; - *trits++ = bits_2_trit1[bits3]; - *trits++ = bits_2_trit2[bits3]; - - num_trits -= 16; - } - if (num_trits == 0) - return; - - /* get three octets */ - - bits24 = ((uint32_t)(*octets++)) << 16; - bits24 |= ((uint32_t)(*octets++)) << 8; - bits24 |= (uint32_t)(*octets++); - - shift = 21; - while (num_trits) { - - /* for each 3 bits in the three octets, output up to 2 trits - * until all trits needed are produced - */ - - bits3 = (bits24 >> shift) & 0x7; - shift -= 3; - *trits++ = bits_2_trit1[bits3]; - if (--num_trits) { - *trits++ = bits_2_trit2[bits3]; - --num_trits; - } - } -} - - -/* ntru_trits_2_bits - * - * Each 2 trits in an array of trits is converted to 3 bits, and the bits - * are packed in an array of octets. A multiple of 3 octets is output. - * Any bits in the final octets not derived from trits are zero. - * - * Returns TRUE if all trits were valid. - * Returns FALSE if invalid trits were found. - */ - -bool -ntru_trits_2_bits( - uint8_t const *trits, /* in - pointer to array of trits */ - uint32_t num_trits, /* in - number of trits to convert */ - uint8_t *octets) /* out - address for array of octets */ -{ - bool all_trits_valid = TRUE; - uint32_t bits24; - uint32_t bits3; - uint32_t shift; - - assert(octets); - assert(trits); - - while (num_trits >= 16) { - - /* convert each 2 trits to 3 bits and pack */ - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 = (bits3 << 21); - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= (bits3 << 18); - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= (bits3 << 15); - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= (bits3 << 12); - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= (bits3 << 9); - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= (bits3 << 6); - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= (bits3 << 3); - - bits3 = *trits++ * 3; - bits3 += *trits++; - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= bits3; - - num_trits -= 16; - - /* output three octets */ - - *octets++ = (uint8_t)((bits24 >> 16) & 0xff); - *octets++ = (uint8_t)((bits24 >> 8) & 0xff); - *octets++ = (uint8_t)(bits24 & 0xff); - } - - bits24 = 0; - shift = 21; - while (num_trits) { - - /* convert each 2 trits to 3 bits and pack */ - - bits3 = *trits++ * 3; - if (--num_trits) { - bits3 += *trits++; - --num_trits; - } - if (bits3 > 7) { - bits3 = 7; - all_trits_valid = FALSE; - } - bits24 |= (bits3 << shift); - shift -= 3; - } - - /* output three octets */ - - *octets++ = (uint8_t)((bits24 >> 16) & 0xff); - *octets++ = (uint8_t)((bits24 >> 8) & 0xff); - *octets++ = (uint8_t)(bits24 & 0xff); - - return all_trits_valid; -} - - -/* ntru_coeffs_mod4_2_octets - * - * Takes an array of ring element coefficients mod 4 and packs the - * results into an octet string. - */ - -void -ntru_coeffs_mod4_2_octets( - uint16_t num_coeffs, /* in - number of coefficients */ - uint16_t const *coeffs, /* in - pointer to coefficients */ - uint8_t *octets) /* out - address for octets */ -{ - uint8_t bits2; - int shift; - uint16_t i; - - assert(coeffs); - assert(octets); - - *octets = 0; - shift = 6; - for (i = 0; i < num_coeffs; i++) { - bits2 = (uint8_t)(coeffs[i] & 0x3); - *octets |= bits2 << shift; - shift -= 2; - if (shift < 0) { - ++octets; - *octets = 0; - shift = 6; - } - } -} - - -/* ntru_trits_2_octet - * - * Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1). - */ - -void -ntru_trits_2_octet( - uint8_t const *trits, /* in - pointer to trits */ - uint8_t *octet) /* out - address for octet */ -{ - int i; - - assert(trits); - assert(octet); - - *octet = 0; - for (i = 4; i >= 0; i--) { - *octet = (*octet * 3) + trits[i]; - } -} - - -/* ntru_octet_2_trits - * - * Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1). - */ - -void -ntru_octet_2_trits( - uint8_t octet, /* in - octet to be unpacked */ - uint8_t *trits) /* out - address for trits */ -{ - int i; - - assert(trits); - - for (i = 0; i < 5; i++) { - trits[i] = octet % 3; - octet = (octet - trits[i]) / 3; - } -} - - -/* ntru_indices_2_trits - * - * Converts a list of the nonzero indices of a polynomial into an array of - * trits. - */ - -void -ntru_indices_2_trits( - uint16_t in_len, /* in - no. of indices */ - uint16_t const *in, /* in - pointer to list of indices */ - bool plus1, /* in - if list is +1 cofficients */ - uint8_t *out) /* out - address of output polynomial */ -{ - uint8_t trit = plus1 ? 1 : 2; - uint16_t i; - - assert(in); - assert(out); - - for (i = 0; i < in_len; i++) { - out[in[i]] = trit; - } -} - - -/* ntru_packed_trits_2_indices - * - * Unpacks an array of N trits and creates a list of array indices - * corresponding to trits = +1, and list of array indices corresponding to - * trits = -1. - */ - -void -ntru_packed_trits_2_indices( - uint8_t const *in, /* in - pointer to packed-trit octets */ - uint16_t num_trits, /* in - no. of packed trits */ - uint16_t *indices_plus1, /* out - address for indices of +1 trits */ - uint16_t *indices_minus1) /* out - address for indices of -1 trits */ -{ - uint8_t trits[5]; - uint16_t i = 0; - int j; - - assert(in); - assert(indices_plus1); - assert(indices_minus1); - - while (num_trits >= 5) { - ntru_octet_2_trits(*in++, trits); - num_trits -= 5; - for (j = 0; j < 5; j++, i++) { - if (trits[j] == 1) { - *indices_plus1 = i; - ++indices_plus1; - } else if (trits[j] == 2) { - *indices_minus1 = i; - ++indices_minus1; - } - } - } - if (num_trits) { - ntru_octet_2_trits(*in, trits); - for (j = 0; num_trits && (j < 5); j++, i++) { - if (trits[j] == 1) { - *indices_plus1 = i; - ++indices_plus1; - } else if (trits[j] == 2) { - *indices_minus1 = i; - ++indices_minus1; - } - --num_trits; - } - } -} - - -/* ntru_indices_2_packed_trits - * - * Takes a list of array indices corresponding to elements whose values - * are +1 or -1, and packs the N-element array of trits described by these - * lists into octets, 5 trits per octet. - */ - -void -ntru_indices_2_packed_trits( - uint16_t const *indices, /* in - pointer to indices */ - uint16_t num_plus1, /* in - no. of indices for +1 trits */ - uint16_t num_minus1, /* in - no. of indices for -1 trits */ - uint16_t num_trits, /* in - N, no. of trits in array */ - uint8_t *buf, /* in - temp buf, N octets */ - uint8_t *out) /* out - address for packed octets */ -{ - assert(indices); - assert(buf); - assert(out); - - /* convert indices to an array of trits */ - - memset(buf, 0, num_trits); - ntru_indices_2_trits(num_plus1, indices, TRUE, buf); - ntru_indices_2_trits(num_minus1, indices + num_plus1, FALSE, buf); - - /* pack the array of trits */ - - while (num_trits >= 5) { - ntru_trits_2_octet(buf, out); - num_trits -= 5; - buf += 5; - ++out; - } - if (num_trits) { - uint8_t trits[5]; - - memcpy(trits, buf, num_trits); - memset(trits + num_trits, 0, sizeof(trits) - num_trits); - ntru_trits_2_octet(trits, out); - } -} - - -/* ntru_elements_2_octets - * - * Packs an array of n-bit elements into an array of - * ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16. - */ - -void -ntru_elements_2_octets( - uint16_t in_len, /* in - no. of elements to be packed */ - uint16_t const *in, /* in - ptr to elements to be packed */ - uint8_t n_bits, /* in - no. of bits in input element */ - uint8_t *out) /* out - addr for output octets */ -{ - uint16_t temp; - int shift; - uint16_t i; - - assert(in_len); - assert(in); - assert((n_bits > 8) && (n_bits < 16)); - assert(out); - - /* pack */ - - temp = 0; - shift = n_bits - 8; - i = 0; - while (i < in_len) { - - /* add bits to temp to fill an octet and output the octet */ - - temp |= in[i] >> shift; - *out++ = (uint8_t)(temp & 0xff); - shift = 8 - shift; - if (shift < 1) { - - /* next full octet is in current input word */ - - shift += n_bits; - temp = 0; - - } else { - - /* put remaining bits of input word in temp as partial octet, - * and increment index to next input word - */ - temp = in[i] << (uint16_t)shift; - - ++i; - } - shift = n_bits - shift; - } - - /* output any bits remaining in last input word */ - - if (shift != n_bits - 8) { - *out++ = (uint8_t)(temp & 0xff); - } -} - - -/* ntru_octets_2_elements - * - * Unpacks an octet string into an array of ((in_len * 8) / n_bits) - * n-bit elements, 8 < n_bits < 16. Any extra bits are discarded. - */ - -void -ntru_octets_2_elements( - uint16_t in_len, /* in - no. of octets to be unpacked */ - uint8_t const *in, /* in - ptr to octets to be unpacked */ - uint8_t n_bits, /* in - no. of bits in output element */ - uint16_t *out) /* out - addr for output elements */ -{ - uint16_t temp; - uint16_t mask = (1 << n_bits) - 1; - int shift; - uint16_t i; - - assert(in_len > 1); - assert(in); - assert((n_bits > 8) && (n_bits < 16)); - assert(out); - - /* unpack */ - - temp = 0; - shift = n_bits; - i = 0; - while (i < in_len) { - shift = 8 - shift; - if (shift < 0) { - - /* the current octet will not fill the current element */ - - shift += n_bits; - - } else { - - /* add bits from the current octet to fill the current element and - * output the element - */ - - temp |= ((uint16_t)in[i]) >> shift; - *out++ = temp & mask; - temp = 0; - } - - /* add the remaining bits of the current octet to start an element */ - - shift = n_bits - shift; - temp |= ((uint16_t)in[i]) << shift; - ++i; - } -} - - diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.h deleted file mode 100644 index 1c4b35b24..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.h +++ /dev/null @@ -1,183 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_convert.h is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -/****************************************************************************** - * - * File: ntru_crypto_ntru_convert.h - * - * Contents: Definitions and declarations for conversion routines - * for NTRUEncrypt, including packing, unpacking and others. - * - *****************************************************************************/ - -#ifndef NTRU_CRYPTO_NTRU_CONVERT_H -#define NTRU_CRYPTO_NTRU_CONVERT_H - -#include "ntru_crypto.h" - - -/* function declarations */ - -/* ntru_bits_2_trits - * - * Each 3 bits in an array of octets is converted to 2 trits in an array - * of trits. - */ - -extern void -ntru_bits_2_trits( - uint8_t const *octets, /* in - pointer to array of octets */ - uint16_t num_trits, /* in - number of trits to produce */ - uint8_t *trits); /* out - address for array of trits */ - - -/* ntru_trits_2_bits - * - * Each 2 trits in an array of trits is converted to 3 bits, and the bits - * are packed in an array of octets. A multiple of 3 octets is output. - * Any bits in the final octets not derived from trits are zero. - * - * Returns TRUE if all trits were valid. - * Returns FALSE if invalid trits were found. - */ - -extern bool -ntru_trits_2_bits( - uint8_t const *trits, /* in - pointer to array of trits */ - uint32_t num_trits, /* in - number of trits to convert */ - uint8_t *octets); /* out - address for array of octets */ - - -/* ntru_coeffs_mod4_2_octets - * - * Takes an array of coefficients mod 4 and packs the results into an - * octet string. - */ - -extern void -ntru_coeffs_mod4_2_octets( - uint16_t num_coeffs, /* in - number of coefficients */ - uint16_t const *coeffs, /* in - pointer to coefficients */ - uint8_t *octets); /* out - address for octets */ - - -/* ntru_trits_2_octet - * - * Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1). - */ - -extern void -ntru_trits_2_octet( - uint8_t const *trits, /* in - pointer to trits */ - uint8_t *octet); /* out - address for octet */ - - -/* ntru_octet_2_trits - * - * Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1). - */ - -extern void -ntru_octet_2_trits( - uint8_t octet, /* in - octet to be unpacked */ - uint8_t *trits); /* out - address for trits */ - - -/* ntru_indices_2_trits - * - * Converts a list of the nonzero indices of a polynomial into an array of - * trits. - */ - -extern void -ntru_indices_2_trits( - uint16_t in_len, /* in - no. of indices */ - uint16_t const *in, /* in - pointer to list of indices */ - bool plus1, /* in - if list is +1 coefficients */ - uint8_t *out); /* out - address of output polynomial */ - - -/* ntru_packed_trits_2_indices - * - * Unpacks an array of N trits and creates a list of array indices - * corresponding to trits = +1, and list of array indices corresponding to - * trits = -1. - */ - -extern void -ntru_packed_trits_2_indices( - uint8_t const *in, /* in - pointer to packed-trit octets */ - uint16_t num_trits, /* in - no. of packed trits */ - uint16_t *indices_plus1, /* out - address for indices of +1 trits */ - uint16_t *indices_minus1); /* out - address for indices of -1 trits */ - - -/* ntru_indices_2_packed_trits - * - * Takes a list of array indices corresponding to elements whose values - * are +1 or -1, and packs the N-element array of trits described by these - * lists into octets, 5 trits per octet. - */ - -extern void -ntru_indices_2_packed_trits( - uint16_t const *indices, /* in - pointer to indices */ - uint16_t num_plus1, /* in - no. of indices for +1 trits */ - uint16_t num_minus1, /* in - no. of indices for -1 trits */ - uint16_t num_trits, /* in - N, no. of trits in array */ - uint8_t *buf, /* in - temp buf, N octets */ - uint8_t *out); /* out - address for packed octets */ - - -/* ntru_elements_2_octets - * - * Packs an array of n-bit elements into an array of - * ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16. - */ - -extern void -ntru_elements_2_octets( - uint16_t in_len, /* in - no. of elements to be packed */ - uint16_t const *in, /* in - ptr to elements to be packed */ - uint8_t n_bits, /* in - no. of bits in input element */ - uint8_t *out); /* out - addr for output octets */ - - -/* ntru_octets_2_elements - * - * Unpacks an octet string into an array of ((in_len * 8) / n_bits) - * n-bit elements, 8 < n < 16. Any extra bits are discarded. - */ - -extern void -ntru_octets_2_elements( - uint16_t in_len, /* in - no. of octets to be unpacked */ - uint8_t const *in, /* in - ptr to octets to be unpacked */ - uint8_t n_bits, /* in - no. of bits in output element */ - uint16_t *out); /* out - addr for output elements */ - - -#endif /* NTRU_CRYPTO_NTRU_CONVERT_H */ - - diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt.c deleted file mode 100644 index dba81915a..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt.c +++ /dev/null @@ -1,1034 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_encrypt.c is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -/****************************************************************************** - * - * File: ntru_crypto_ntru_encrypt.c - * - * Contents: Routines implementing NTRUEncrypt encryption and decryption and - * key generation. - * - *****************************************************************************/ - - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include "ntru_crypto.h" -#include "ntru_crypto_ntru_encrypt_param_sets.h" -#include "ntru_crypto_ntru_encrypt_key.h" -#include "ntru_crypto_ntru_convert.h" -#include "ntru_crypto_ntru_poly.h" -# -#include "ntru_trits.h" -#include "ntru_poly.h" - -/* ntru_crypto_ntru_encrypt - * - * Implements NTRU encryption (SVES) for the parameter set specified in - * the public key blob. - * - * Before invoking this function, a DRBG must be instantiated using - * ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that - * instantiation the requested security strength must be at least as large - * as the security strength of the NTRU parameter set being used. - * Failure to instantiate the DRBG with the proper security strength will - * result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH. - * - * The required minimum size of the output ciphertext buffer (ct) may be - * queried by invoking this function with ct = NULL. In this case, no - * encryption is performed, NTRU_OK is returned, and the required minimum - * size for ct is returned in ct_len. - * - * When ct != NULL, at invocation *ct_len must be the size of the ct buffer. - * Upon return it is the actual size of the ciphertext. - * - * Returns NTRU_OK if successful. - * Returns NTRU_DRBG_FAIL if the DRBG handle is invalid. - * Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL. - * Returns NTRU_BAD_LENGTH if a length argument (pubkey_blob_len or pt_len) is - * zero, or if pt_len exceeds the maximum plaintext length for the parameter set. - * Returns NTRU_BAD_PUBLIC_KEY if the public-key blob is invalid - * (unknown format, corrupt, bad length). - * Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small. - * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap. - */ - -uint32_t -ntru_crypto_ntru_encrypt( - ntru_drbg_t *drbg, /* in - handle of DRBG */ - uint16_t pubkey_blob_len, /* in - no. of octets in public key - blob */ - uint8_t const *pubkey_blob, /* in - pointer to public key */ - uint16_t pt_len, /* in - no. of octets in plaintext */ - uint8_t const *pt, /* in - pointer to plaintext */ - uint16_t *ct_len, /* in/out - no. of octets in ct, addr for - no. of octets in ciphertext */ - uint8_t *ct) /* out - address for ciphertext */ -{ - NTRU_ENCRYPT_PARAM_SET *params = NULL; - uint8_t const *pubkey_packed = NULL; - uint8_t pubkey_pack_type = 0x00; - uint16_t packed_ct_len; - size_t scratch_buf_len; - uint32_t dr; - uint32_t dr1 = 0; - uint32_t dr2 = 0; - uint32_t dr3 = 0; - uint16_t ring_mult_tmp_len; - int16_t m1 = 0; - uint16_t *scratch_buf = NULL; - uint16_t *ringel_buf = NULL; - uint8_t *b_buf = NULL; - uint8_t *tmp_buf = NULL; - bool msg_rep_good = FALSE; - hash_algorithm_t hash_algid; - uint16_t mprime_len = 0; - uint16_t mod_q_mask; - uint32_t result = NTRU_OK; - ntru_trits_t *mask; - uint8_t *mask_trits; - chunk_t seed; - ntru_poly_t *r_poly; - - /* check for bad parameters */ - - if (!pubkey_blob || !pt || !ct_len) - { - return NTRU_BAD_PARAMETER; - } - if ((pubkey_blob_len == 0) || (pt_len == 0)) - { - return NTRU_BAD_LENGTH; - } - - /* get a pointer to the parameter-set parameters, the packing type for - * the public key, and a pointer to the packed public key - */ - - if (!ntru_crypto_ntru_encrypt_key_parse(TRUE /* pubkey */, pubkey_blob_len, - pubkey_blob, &pubkey_pack_type, - NULL, ¶ms, &pubkey_packed, - NULL)) - { - return NTRU_BAD_PUBLIC_KEY; - } - - /* return the ciphertext size if requested */ - - packed_ct_len = (params->N * params->q_bits + 7) >> 3; - if (!ct) - { - *ct_len = packed_ct_len; - return NTRU_OK; - } - - /* check the ciphertext buffer size */ - - if (*ct_len < packed_ct_len) - { - return NTRU_BUFFER_TOO_SMALL; - } - - /* check the plaintext length */ - - if (pt_len > params->m_len_max) - { - return NTRU_BAD_LENGTH; - } - - /* allocate memory for all operations */ - - if (params->is_product_form) - { - ring_mult_tmp_len = params->N << 1; /* 2N 16-bit word buffer */ - dr1 = params->dF_r & 0xff; - dr2 = (params->dF_r >> 8) & 0xff; - dr3 = (params->dF_r >> 16) & 0xff; - dr = dr1 + dr2 + dr3; - } - else - { - ring_mult_tmp_len = params->N; /* N 16-bit word buffer */ - dr = params->dF_r; - } - scratch_buf_len = (ring_mult_tmp_len << 1) + - /* X-byte temp buf for ring mult and - other intermediate results */ - (params->N << 1) + /* 2N-byte buffer for ring elements - and overflow from temp buffer */ - (dr << 2) + /* buffer for r indices */ - params->sec_strength_len; - /* buffer for b */ - scratch_buf = malloc(scratch_buf_len); - if (!scratch_buf) - { - return NTRU_OUT_OF_MEMORY; - } - ringel_buf = scratch_buf + ring_mult_tmp_len; - b_buf = (uint8_t *)(ringel_buf + params->N); - tmp_buf = (uint8_t *)scratch_buf; - - /* set hash algorithm based on security strength */ - hash_algid = (params->sec_strength_len <= 20) ? HASH_SHA1 : HASH_SHA256; - - /* set constants */ - mod_q_mask = params->q - 1; - - /* loop until a message representative with proper weight is achieved */ - - do { - uint8_t *ptr = tmp_buf; - - /* get b */ - if (drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE, - params->sec_strength_len, b_buf)) - { - result = NTRU_OK; - } - else - { - result = NTRU_FAIL; - } - - if (result == NTRU_OK) - { - - /* form sData (OID || m || b || hTrunc) */ - memcpy(ptr, params->OID, 3); - ptr += 3; - memcpy(ptr, pt, pt_len); - ptr += pt_len; - memcpy(ptr, b_buf, params->sec_strength_len); - ptr += params->sec_strength_len; - memcpy(ptr, pubkey_packed, params->sec_strength_len); - ptr += params->sec_strength_len; - - DBG2(DBG_LIB, "generate polynomial r"); - - seed = chunk_create(tmp_buf, ptr - tmp_buf); - r_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, - params->N, params->q, - params->dF_r, params->dF_r, - params->is_product_form); - if (!r_poly) - { - result = NTRU_MGF1_FAIL; - } - } - - if (result == NTRU_OK) - { - uint16_t pubkey_packed_len; - - /* unpack the public key */ - assert(pubkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS); - pubkey_packed_len = (params->N * params->q_bits + 7) >> 3; - ntru_octets_2_elements(pubkey_packed_len, pubkey_packed, - params->q_bits, ringel_buf); - - /* form R = h * r */ - r_poly->ring_mult(r_poly, ringel_buf, ringel_buf); - r_poly->destroy(r_poly); - - /* form R mod 4 */ - ntru_coeffs_mod4_2_octets(params->N, ringel_buf, tmp_buf); - - /* form mask */ - seed = chunk_create(tmp_buf, (params->N + 3)/4); - mask = ntru_trits_create(params->N, hash_algid, seed); - if (!mask) - { - result = NTRU_MGF1_FAIL; - } - } - - if (result == NTRU_OK) - { - uint8_t *Mtrin_buf = tmp_buf + params->N; - uint8_t *M_buf = Mtrin_buf + params->N - - (params->sec_strength_len + params->m_len_len + - params->m_len_max + 2); - uint16_t i; - - /* form the padded message M */ - ptr = M_buf; - memcpy(ptr, b_buf, params->sec_strength_len); - ptr += params->sec_strength_len; - if (params->m_len_len == 2) - *ptr++ = (uint8_t)((pt_len >> 8) & 0xff); - *ptr++ = (uint8_t)(pt_len & 0xff); - memcpy(ptr, pt, pt_len); - ptr += pt_len; - - /* add an extra zero byte in case without it the bit string - * is not a multiple of 3 bits and therefore might not be - * able to produce enough trits - */ - - memset(ptr, 0, params->m_len_max - pt_len + 2); - - /* convert M to trits (Mbin to Mtrin) */ - mprime_len = params->N; - if (params->is_product_form) - { - --mprime_len; - } - - ntru_bits_2_trits(M_buf, mprime_len, Mtrin_buf); - mask_trits = mask->get_trits(mask); - - /* form the msg representative m' by adding Mtrin to mask, mod p */ - if (params->is_product_form) - { - for (i = 0; i < mprime_len; i++) - { - tmp_buf[i] = mask_trits[i] + Mtrin_buf[i]; - if (tmp_buf[i] >= 3) - { - tmp_buf[i] -= 3; - } - if (tmp_buf[i] == 1) - { - ++m1; - } - else if (tmp_buf[i] == 2) - { - --m1; - } - } - } - else - { - for (i = 0; i < mprime_len; i++) - { - tmp_buf[i] = mask_trits[i] + Mtrin_buf[i]; - if (tmp_buf[i] >= 3) - { - tmp_buf[i] -= 3; - } - } - } - mask->destroy(mask); - - /* check that message representative meets minimum weight - * requirements - */ - - if (params->is_product_form) - msg_rep_good = m1 < 0 ? (bool)(-m1 <= params->min_msg_rep_wt) : - (bool)( m1 <= params->min_msg_rep_wt); - else - msg_rep_good = ntru_poly_check_min_weight(mprime_len, tmp_buf, - params->min_msg_rep_wt); - msg_rep_good = TRUE; - } - } while ((result == NTRU_OK) && !msg_rep_good); - - if (result == NTRU_OK) - { - uint16_t i; - - /* form ciphertext e by adding m' to R mod q */ - - for (i = 0; i < mprime_len; i++) { - if (tmp_buf[i] == 1) - ringel_buf[i] = (ringel_buf[i] + 1) & mod_q_mask; - else if (tmp_buf[i] == 2) - ringel_buf[i] = (ringel_buf[i] - 1) & mod_q_mask; - } - if (params->is_product_form) - ringel_buf[i] = (ringel_buf[i] - m1) & mod_q_mask; - - /* pack ciphertext */ - ntru_elements_2_octets(params->N, ringel_buf, params->q_bits, ct); - *ct_len = packed_ct_len; - } - - /* cleanup */ - memset(scratch_buf, 0, scratch_buf_len); - free(scratch_buf); - - return result; -} - - -/* ntru_crypto_ntru_decrypt - * - * Implements NTRU decryption (SVES) for the parameter set specified in - * the private key blob. - * - * The maximum size of the output plaintext may be queried by invoking - * this function with pt = NULL. In this case, no decryption is performed, - * NTRU_OK is returned, and the maximum size the plaintext could be is - * returned in pt_len. - * Note that until the decryption is performed successfully, the actual size - * of the resulting plaintext cannot be known. - * - * When pt != NULL, at invocation *pt_len must be the size of the pt buffer. - * Upon return it is the actual size of the plaintext. - * - * Returns NTRU_OK if successful. - * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pt) is NULL. - * Returns NTRU_BAD_LENGTH if a length argument (privkey_blob) is zero, or if - * ct_len is invalid for the parameter set. - * Returns NTRU_BAD_PRIVATE_KEY if the private-key blob is invalid - * (unknown format, corrupt, bad length). - * Returns NTRU_BUFFER_TOO_SMALL if the plaintext buffer is too small. - * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap. - * Returns NTRU_FAIL if a decryption error occurs. - */ - -uint32_t -ntru_crypto_ntru_decrypt( - uint16_t privkey_blob_len, /* in - no. of octets in private key - blob */ - uint8_t const *privkey_blob, /* in - pointer to private key */ - uint16_t ct_len, /* in - no. of octets in ciphertext */ - uint8_t const *ct, /* in - pointer to ciphertext */ - uint16_t *pt_len, /* in/out - no. of octets in pt, addr for - no. of octets in plaintext */ - uint8_t *pt) /* out - address for plaintext */ -{ - NTRU_ENCRYPT_PARAM_SET *params = NULL; - uint8_t const *privkey_packed = NULL; - uint8_t const *pubkey_packed = NULL; - uint8_t privkey_pack_type = 0x00; - uint8_t pubkey_pack_type = 0x00; - size_t scratch_buf_len; - uint32_t dF_r; - uint32_t dF_r1 = 0; - uint32_t dF_r2 = 0; - uint32_t dF_r3 = 0; - uint16_t ring_mult_tmp_len; - int16_t m1 = 0; - uint16_t *scratch_buf = NULL; - uint16_t *ringel_buf1 = NULL; - uint16_t *ringel_buf2 = NULL; - uint16_t *i_buf = NULL; - uint8_t *m_buf = NULL; - uint8_t *tmp_buf = NULL; - uint8_t *Mtrin_buf = NULL; - uint8_t *M_buf = NULL; - uint8_t *ptr = NULL; - hash_algorithm_t hash_algid; - uint16_t cmprime_len; - uint16_t mod_q_mask; - uint16_t q_mod_p; - uint16_t cm_len = 0; - uint16_t num_zeros; - uint16_t i; - bool decryption_ok = TRUE; - uint32_t result = NTRU_OK; - ntru_trits_t *mask; - uint8_t *mask_trits; - chunk_t seed; - ntru_poly_t *F_poly, *r_poly; - - /* check for bad parameters */ - if (!privkey_blob || !ct || !pt_len) - { - return NTRU_BAD_PARAMETER; - } - if ((privkey_blob_len == 0) || (ct_len == 0)) - { - return NTRU_BAD_LENGTH; - } - - /* get a pointer to the parameter-set parameters, the packing types for - * the public and private keys, and pointers to the packed public and - * private keys - */ - - if (!ntru_crypto_ntru_encrypt_key_parse(FALSE /* privkey */, - privkey_blob_len, - privkey_blob, &pubkey_pack_type, - &privkey_pack_type, ¶ms, - &pubkey_packed, &privkey_packed)) - { - return NTRU_BAD_PRIVATE_KEY; - } - - /* return the max plaintext size if requested */ - - if (!pt) - { - *pt_len = params->m_len_max; - return NTRU_OK; - } - - /* cannot check the plaintext buffer size until after the plaintext - * is derived, if we allow plaintext buffers only as large as the - * actual plaintext - */ - - /* check the ciphertext length */ - - if (ct_len != (params->N * params->q_bits + 7) >> 3) - { - return NTRU_BAD_LENGTH; - } - - /* allocate memory for all operations */ - - if (params->is_product_form) - { - ring_mult_tmp_len = params->N << 1; /* 2N 16-bit word buffer */ - dF_r1 = params->dF_r & 0xff; - dF_r2 = (params->dF_r >> 8) & 0xff; - dF_r3 = (params->dF_r >> 16) & 0xff; - dF_r = dF_r1 + dF_r2 + dF_r3; - } else { - ring_mult_tmp_len = params->N; /* N 16-bit word buffer */ - dF_r = params->dF_r; - } - scratch_buf_len = (ring_mult_tmp_len << 1) + - /* X-byte temp buf for ring mult and - other intermediate results */ - (params->N << 2) + /* 2 2N-byte bufs for ring elements - and overflow from temp buffer */ - (dF_r << 2) + /* buffer for F, r indices */ - params->m_len_max; /* buffer for plaintext */ - scratch_buf = malloc(scratch_buf_len); - if (!scratch_buf) - { - return NTRU_OUT_OF_MEMORY; - } - ringel_buf1 = scratch_buf + ring_mult_tmp_len; - ringel_buf2 = ringel_buf1 + params->N; - i_buf = ringel_buf2 + params->N; - m_buf = (uint8_t *)(i_buf + (dF_r << 1)); - tmp_buf = (uint8_t *)scratch_buf; - Mtrin_buf = (uint8_t *)ringel_buf1; - M_buf = Mtrin_buf + params->N; - - /* set hash algorithm based on security strength */ - hash_algid = (params->sec_strength_len <= 20) ? HASH_SHA1 : HASH_SHA256; - - /* set constants */ - mod_q_mask = params->q - 1; - q_mod_p = params->q % 3; - - /* unpack the ciphertext */ - ntru_octets_2_elements(ct_len, ct, params->q_bits, ringel_buf2); - - /* unpack the private key */ - if (privkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_TRITS) - { - ntru_packed_trits_2_indices(privkey_packed, params->N, i_buf, - i_buf + dF_r); - - } - else if (privkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_INDICES) - { - ntru_octets_2_elements( - (((uint16_t)dF_r << 1) * params->N_bits + 7) >> 3, - privkey_packed, params->N_bits, i_buf); - - } - else - { - assert(FALSE); - } - - /* form cm': - * F * e - * A = e * (1 + pF) mod q = e + pFe mod q - * a = A in the range [-q/2, q/2) - * cm' = a mod p - */ - F_poly = ntru_poly_create_from_data(i_buf, params->N, params->q, - params->dF_r, params->dF_r, - params->is_product_form); - F_poly->ring_mult(F_poly, ringel_buf2, ringel_buf1); - F_poly->destroy(F_poly); - - cmprime_len = params->N; - if (params->is_product_form) - { - --cmprime_len; - for (i = 0; i < cmprime_len; i++) - { - ringel_buf1[i] = (ringel_buf2[i] + 3 * ringel_buf1[i]) & mod_q_mask; - if (ringel_buf1[i] >= (params->q >> 1)) - { - ringel_buf1[i] = ringel_buf1[i] - q_mod_p; - } - Mtrin_buf[i] = (uint8_t)(ringel_buf1[i] % 3); - if (Mtrin_buf[i] == 1) - { - ++m1; - } - else if (Mtrin_buf[i] == 2) - { - --m1; - } - } - } - else - { - for (i = 0; i < cmprime_len; i++) - { - ringel_buf1[i] = (ringel_buf2[i] + 3 * ringel_buf1[i]) & mod_q_mask; - if (ringel_buf1[i] >= (params->q >> 1)) - { - ringel_buf1[i] = ringel_buf1[i] - q_mod_p; - } - Mtrin_buf[i] = (uint8_t)(ringel_buf1[i] % 3); - } - } - - /* check that the candidate message representative meets minimum weight - * requirements - */ - - if (params->is_product_form) - { - decryption_ok = m1 < 0 ? (bool)(-m1 <= params->min_msg_rep_wt) : - (bool)( m1 <= params->min_msg_rep_wt); - } - else - { - decryption_ok = ntru_poly_check_min_weight(cmprime_len, Mtrin_buf, - params->min_msg_rep_wt); - } - - /* form cR = e - cm' mod q */ - for (i = 0; i < cmprime_len; i++) - { - if (Mtrin_buf[i] == 1) - { - ringel_buf2[i] = (ringel_buf2[i] - 1) & mod_q_mask; - } - else if (Mtrin_buf[i] == 2) - { - ringel_buf2[i] = (ringel_buf2[i] + 1) & mod_q_mask; - } - } - if (params->is_product_form) - { - ringel_buf2[i] = (ringel_buf2[i] + m1) & mod_q_mask; - } - - /* form cR mod 4 */ - ntru_coeffs_mod4_2_octets(params->N, ringel_buf2, tmp_buf); - - /* form mask */ - seed = chunk_create(tmp_buf, (params->N + 3)/4); - mask = ntru_trits_create(params->N, hash_algid, seed); - if (!mask) - { - result = NTRU_MGF1_FAIL; - } - else - { - mask_trits = mask->get_trits(mask); - - /* form cMtrin by subtracting mask from cm', mod p */ - for (i = 0; i < cmprime_len; i++) - { - Mtrin_buf[i] = Mtrin_buf[i] - mask_trits[i]; - if (Mtrin_buf[i] >= 3) - { - Mtrin_buf[i] += 3; - } - } - mask->destroy(mask); - - if (params->is_product_form) - - /* set the last trit to zero since that's what it was, and - * because it can't be calculated from (cm' - mask) since - * we don't have the correct value for the last cm' trit - */ - - Mtrin_buf[i] = 0; - - /* convert cMtrin to cM (Mtrin to Mbin) */ - - if (!ntru_trits_2_bits(Mtrin_buf, params->N, M_buf)) - decryption_ok = FALSE; - - /* validate the padded message cM and copy cm to m_buf */ - - ptr = M_buf + params->sec_strength_len; - if (params->m_len_len == 2) - cm_len = (uint16_t)(*ptr++) << 16; - cm_len |= (uint16_t)(*ptr++); - if (cm_len > params->m_len_max) { - cm_len = params->m_len_max; - decryption_ok = FALSE; - } - memcpy(m_buf, ptr, cm_len); - ptr += cm_len; - num_zeros = params->m_len_max - cm_len + 1; - for (i = 0; i < num_zeros; i++) { - if (ptr[i] != 0) - decryption_ok = FALSE; - } - - /* form sData (OID || m || b || hTrunc) */ - - ptr = tmp_buf; - memcpy(ptr, params->OID, 3); - ptr += 3; - memcpy(ptr, m_buf, cm_len); - ptr += cm_len; - memcpy(ptr, M_buf, params->sec_strength_len); - ptr += params->sec_strength_len; - memcpy(ptr, pubkey_packed, params->sec_strength_len); - ptr += params->sec_strength_len; - - /* generate cr */ - DBG2(DBG_LIB, "generate polynomial r"); - - seed = chunk_create(tmp_buf, ptr - tmp_buf); - r_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, - params->N, params->q, - params->dF_r, params->dF_r, - params->is_product_form); - if (!r_poly) - { - result = NTRU_MGF1_FAIL; - } - } - - if (result == NTRU_OK) - { - /* unpack the public key */ - { - uint16_t pubkey_packed_len; - - assert(pubkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS); - pubkey_packed_len = (params->N * params->q_bits + 7) >> 3; - ntru_octets_2_elements(pubkey_packed_len, pubkey_packed, - params->q_bits, ringel_buf1); - } - - /* form cR' = h * cr */ - r_poly->ring_mult(r_poly, ringel_buf1, ringel_buf1); - r_poly->destroy(r_poly); - - /* compare cR' to cR */ - for (i = 0; i < params->N; i++) - { - if (ringel_buf1[i] != ringel_buf2[i]) - { - decryption_ok = FALSE; - } - } - - /* output plaintext and plaintext length */ - if (decryption_ok) - { - if (*pt_len < cm_len) - { - return NTRU_BUFFER_TOO_SMALL; - } - memcpy(pt, m_buf, cm_len); - *pt_len = cm_len; - } - } - - /* cleanup */ - memset(scratch_buf, 0, scratch_buf_len); - free(scratch_buf); - - if (!decryption_ok) - { - return NTRU_FAIL; - } - - return result; -} - - -/* ntru_crypto_ntru_encrypt_keygen - * - * Implements key generation for NTRUEncrypt for the parameter set specified. - * - * The required minimum size of the output public-key buffer (pubkey_blob) - * may be queried by invoking this function with pubkey_blob = NULL. - * In this case, no key generation is performed, NTRU_OK is returned, and - * the required minimum size for pubkey_blob is returned in pubkey_blob_len. - * - * The required minimum size of the output private-key buffer (privkey_blob) - * may be queried by invoking this function with privkey_blob = NULL. - * In this case, no key generation is performed, NTRU_OK is returned, and - * the required minimum size for privkey_blob is returned in privkey_blob_len. - * - * The required minimum sizes of both pubkey_blob and privkey_blob may be - * queried as described above, in a single invocation of this function. - * - * When pubkey_blob != NULL and privkey_blob != NULL, at invocation - * *pubkey_blob_len must be the size of the pubkey_blob buffer and - * *privkey_blob_len must be the size of the privkey_blob buffer. - * Upon return, *pubkey_blob_len is the actual size of the public-key blob - * and *privkey_blob_len is the actual size of the private-key blob. - * - * Returns NTRU_OK if successful. - * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pubkey_blob or - * privkey_blob) is NULL. - * Returns NTRU_INVALID_PARAMETER_SET if the parameter-set ID is invalid. - * Returns NTRU_BAD_LENGTH if a length argument is invalid. - * Returns NTRU_BUFFER_TOO_SMALL if either the pubkey_blob buffer or the - * privkey_blob buffer is too small. - * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap. - * Returns NTRU_FAIL if the polynomial generated for f is not invertible in - * (Z/qZ)[X]/(X^N - 1), which is extremely unlikely. - * Should this occur, this function should simply be invoked again. - */ - -uint32_t -ntru_crypto_ntru_encrypt_keygen( - ntru_drbg_t *drbg, /* in - handle of DRBG */ - NTRU_ENCRYPT_PARAM_SET_ID param_set_id, /* in - parameter set ID */ - uint16_t *pubkey_blob_len, /* in/out - no. of octets in - pubkey_blob, addr - for no. of octets - in pubkey_blob */ - uint8_t *pubkey_blob, /* out - address for - public key blob */ - uint16_t *privkey_blob_len, /* in/out - no. of octets in - privkey_blob, addr - for no. of octets - in privkey_blob */ - uint8_t *privkey_blob) /* out - address for - private key blob */ -{ - NTRU_ENCRYPT_PARAM_SET *params = NULL; - uint16_t public_key_blob_len; - uint16_t private_key_blob_len; - uint8_t pubkey_pack_type; - uint8_t privkey_pack_type; - size_t scratch_buf_len; - uint32_t dF; - uint32_t dF1 = 0; - uint32_t dF2 = 0; - uint32_t dF3 = 0; - uint16_t *scratch_buf = NULL; - uint16_t *ringel_buf1 = NULL; - uint16_t *ringel_buf2 = NULL; - uint8_t *tmp_buf = NULL; - uint16_t mod_q_mask; - hash_algorithm_t hash_algid; - uint16_t seed_len; - chunk_t seed; - uint32_t result = NTRU_OK; - ntru_poly_t *F_poly = NULL; - ntru_poly_t *g_poly = NULL; - uint16_t *F_indices; - - /* get a pointer to the parameter-set parameters */ - - if ((params = ntru_encrypt_get_params_with_id(param_set_id)) == NULL) - { - return NTRU_INVALID_PARAMETER_SET; - } - - /* check for bad parameters */ - - if (!pubkey_blob_len || !privkey_blob_len) - { - return NTRU_BAD_PARAMETER; - } - - /* get public and private key packing types and blob lengths */ - - ntru_crypto_ntru_encrypt_key_get_blob_params(params, &pubkey_pack_type, - &public_key_blob_len, - &privkey_pack_type, - &private_key_blob_len); - - /* return the pubkey_blob size and/or privkey_blob size if requested */ - - if (!pubkey_blob || !privkey_blob) - { - if (!pubkey_blob) - *pubkey_blob_len = public_key_blob_len; - if (!privkey_blob) - *privkey_blob_len = private_key_blob_len; - return NTRU_OK; - } - - /* check size of output buffers */ - - if ((*pubkey_blob_len < public_key_blob_len) || - (*privkey_blob_len < private_key_blob_len)) - { - return NTRU_BUFFER_TOO_SMALL; - } - - /* allocate memory for all operations */ - if (params->is_product_form) { - dF1 = params->dF_r & 0xff; - dF2 = (params->dF_r >> 8) & 0xff; - dF3 = (params->dF_r >> 16) & 0xff; - dF = dF1 + dF2 + dF3; - } else { - dF = params->dF_r; - } - - scratch_buf_len = (params->N * 8) + /* 4N-byte temp buffer for ring inv - and other intermediate results, - 2N-byte buffer for f, g indices - and overflow from temp buffer, - 2N-byte buffer for f^-1 */ - (dF << 2); /* buffer for F indices */ - scratch_buf = malloc(scratch_buf_len); - if (!scratch_buf) - { - return NTRU_OUT_OF_MEMORY; - } - ringel_buf1 = scratch_buf + (params->N << 1); - ringel_buf2 = ringel_buf1 + params->N; - tmp_buf = (uint8_t *)scratch_buf; - - /* set hash algorithm and seed length based on security strength */ - if (params->sec_strength_len <= 20) - { - hash_algid = HASH_SHA1; - } - else - { - hash_algid = HASH_SHA256; - } - seed_len = params->sec_strength_len + 8; - - /* set constants */ - - mod_q_mask = params->q - 1; - - /* get random bytes for seed for generating trinary F - * as a list of indices - */ - - if (drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE, - seed_len, tmp_buf)) - { - result = NTRU_OK; - } - else - { - result = NTRU_DRBG_FAIL; - } - - if (result == NTRU_OK) - { - DBG2(DBG_LIB, "generate polynomial F"); - - seed = chunk_create(tmp_buf, seed_len); - F_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, - params->N, params->q, - params->dF_r, params->dF_r, - params->is_product_form); - if (!F_poly) - { - result = NTRU_MGF1_FAIL; - } - } - - if (result == NTRU_OK) - { - int i; - - F_poly->get_array(F_poly, ringel_buf1); - - /* form f = 1 + pF */ - for (i = 0; i < params->N; i++) - { - ringel_buf1[i] = (ringel_buf1[i] * 3) & mod_q_mask; - } - ringel_buf1[0] = (ringel_buf1[0] + 1) & mod_q_mask; - - /* find f^-1 in (Z/qZ)[X]/(X^N - 1) */ - if (!ntru_ring_inv(ringel_buf1, params->N, params->q, - scratch_buf, ringel_buf2)) - { - result = NTRU_FAIL; - } - } - - if (result == NTRU_OK) - { - - /* get random bytes for seed for generating trinary polynomial g - * as a list of indices - */ - if (!drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE, - seed_len, tmp_buf)) - { - result = NTRU_DRBG_FAIL; - } - } - - if (result == NTRU_OK) - { - DBG2(DBG_LIB, "generate polynomial g"); - - seed = chunk_create(tmp_buf, seed_len); - g_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, - params->N, params->q, - params->dg + 1, params->dg, FALSE); - if (!g_poly) - { - result = NTRU_MGF1_FAIL; - } - } - - if (result == NTRU_OK) - { - uint16_t i; - - /* compute h = p * (f^-1 * g) mod q */ - g_poly->ring_mult(g_poly, ringel_buf2, ringel_buf2); - g_poly->destroy(g_poly); - - for (i = 0; i < params->N; i++) - { - ringel_buf2[i] = (ringel_buf2[i] * 3) & mod_q_mask; - } - - /* create public key blob */ - ntru_crypto_ntru_encrypt_key_create_pubkey_blob(params, ringel_buf2, - pubkey_pack_type, - pubkey_blob); - *pubkey_blob_len = public_key_blob_len; - - /* create private key blob */ - F_indices = F_poly->get_indices(F_poly); - ntru_crypto_ntru_encrypt_key_create_privkey_blob(params, ringel_buf2, - F_indices, - privkey_pack_type, - tmp_buf, privkey_blob); - *privkey_blob_len = private_key_blob_len; - } - - /* cleanup */ - DESTROY_IF(F_poly); - memset(scratch_buf, 0, scratch_buf_len); - free(scratch_buf); - - return result; -} diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.c deleted file mode 100644 index 90baaadf3..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.c +++ /dev/null @@ -1,360 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_encrypt_key.c is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -/****************************************************************************** - * - * File: ntru_crypto_ntru_encrypt_key.c - * - * Contents: Routines for exporting and importing public and private keys - * for NTRUEncrypt. - * - *****************************************************************************/ - - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include "ntru_crypto_ntru_encrypt_key.h" - - -/* ntru_crypto_ntru_encrypt_key_parse - * - * Parses an NTRUEncrypt key blob. - * If the blob is not corrupt, returns packing types for public and private - * keys, a pointer to the parameter set, a pointer to the public key, and - * a pointer to the private key if it exists. - * - * Returns TRUE if successful. - * Returns FALSE if the blob is invalid. - */ - -bool -ntru_crypto_ntru_encrypt_key_parse( - bool pubkey_parse, /* in - if parsing pubkey - blob */ - uint16_t key_blob_len, /* in - no. octets in key - blob */ - uint8_t const *key_blob, /* in - pointer to key blob */ - uint8_t *pubkey_pack_type, /* out - addr for pubkey - packing type */ - uint8_t *privkey_pack_type, /* out - addr for privkey - packing type */ - NTRU_ENCRYPT_PARAM_SET **params, /* out - addr for ptr to - parameter set */ - uint8_t const **pubkey, /* out - addr for ptr to - packed pubkey */ - uint8_t const **privkey) /* out - addr for ptr to - packed privkey */ -{ - uint8_t tag; - - assert(key_blob_len); - assert(key_blob); - assert(pubkey_pack_type); - assert(params); - assert(pubkey); - - /* parse key blob based on tag */ - - tag = key_blob[0]; - switch (tag) { - case NTRU_ENCRYPT_PUBKEY_TAG: - if (!pubkey_parse) - return FALSE; - break; - case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG: - case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG: - case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG: - assert(privkey_pack_type); - assert(privkey); - if (pubkey_parse) - return FALSE; - break; - default: - return FALSE; - } - - switch (tag) { - case NTRU_ENCRYPT_PUBKEY_TAG: - case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG: - case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG: - case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG: - - /* Version 0: - * byte 0: tag - * byte 1: no. of octets in OID - * bytes 2-4: OID - * bytes 5- : packed pubkey - * [packed privkey] - */ - - { - NTRU_ENCRYPT_PARAM_SET *p = NULL; - uint16_t pubkey_packed_len; - - /* check OID length and minimum blob length for tag and OID */ - - if ((key_blob_len < 5) || (key_blob[1] != 3)) - return FALSE; - - /* get a pointer to the parameter set corresponding to the OID */ - - if ((p = ntru_encrypt_get_params_with_OID(key_blob + 2)) == NULL) - return FALSE; - - /* check blob length and assign pointers to blob fields */ - - pubkey_packed_len = (p->N * p->q_bits + 7) / 8; - if (pubkey_parse) { /* public-key parsing */ - if (key_blob_len != 5 + pubkey_packed_len) - return FALSE; - - *pubkey = key_blob + 5; - - } else { /* private-key parsing */ - uint16_t privkey_packed_len; - uint16_t privkey_packed_trits_len = (p->N + 4) / 5; - uint16_t privkey_packed_indices_len; - uint16_t dF; - - /* check packing type for product-form private keys */ - - if (p->is_product_form && - (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG)) - return FALSE; - - /* set packed-key length for packed indices */ - - if (p->is_product_form) - dF = (uint16_t)( (p->dF_r & 0xff) + /* df1 */ - ((p->dF_r >> 8) & 0xff) + /* df2 */ - ((p->dF_r >> 16) & 0xff)); /* df3 */ - else - dF = (uint16_t)p->dF_r; - privkey_packed_indices_len = ((dF << 1) * p->N_bits + 7) >> 3; - - /* set private-key packing type if defaulted */ - - if (tag == NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG) { - if (p->is_product_form || - (privkey_packed_indices_len <= - privkey_packed_trits_len)) - tag = NTRU_ENCRYPT_PRIVKEY_INDICES_TAG; - else - tag = NTRU_ENCRYPT_PRIVKEY_TRITS_TAG; - } - - if (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG) - privkey_packed_len = privkey_packed_trits_len; - else - privkey_packed_len = privkey_packed_indices_len; - - if (key_blob_len != 5 + pubkey_packed_len + privkey_packed_len) - return FALSE; - - *pubkey = key_blob + 5; - *privkey = *pubkey + pubkey_packed_len; - *privkey_pack_type = (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG) ? - NTRU_ENCRYPT_KEY_PACKED_TRITS : - NTRU_ENCRYPT_KEY_PACKED_INDICES; - } - - /* return parameter set pointer */ - - *pubkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS; - *params = p; - } - default: - break; /* can't get here */ - } - return TRUE; -} - - -/* ntru_crypto_ntru_encrypt_key_get_blob_params - * - * Returns public and private key packing types and blob lengths given - * a packing format. For now, only a default packing format exists. - * - * Only public-key params may be returned by setting privkey_pack_type - * and privkey_blob_len to NULL. - */ - -void -ntru_crypto_ntru_encrypt_key_get_blob_params( - NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to - param set - parameters */ - uint8_t *pubkey_pack_type, /* out - addr for pubkey - packing type */ - uint16_t *pubkey_blob_len, /* out - addr for no. of - bytes in - pubkey blob */ - uint8_t *privkey_pack_type, /* out - addr for privkey - packing type */ - uint16_t *privkey_blob_len) /* out - addr for no. of - bytes in - privkey blob */ -{ - uint16_t pubkey_packed_len = (params->N * params->q_bits + 7) >> 3; - - assert(params); - assert(pubkey_pack_type); - assert(pubkey_blob_len); - - *pubkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS; - *pubkey_blob_len = 5 + pubkey_packed_len; - - if (privkey_pack_type && privkey_blob_len) { - uint16_t privkey_packed_trits_len = (params->N + 4) / 5; - uint16_t privkey_packed_indices_len; - uint16_t dF; - - if (params->is_product_form) - dF = (uint16_t)( (params->dF_r & 0xff) + /* df1 */ - ((params->dF_r >> 8) & 0xff) + /* df2 */ - ((params->dF_r >> 16) & 0xff)); /* df3 */ - else - dF = (uint16_t)params->dF_r; - privkey_packed_indices_len = ((dF << 1) * params->N_bits + 7) >> 3; - - if (params->is_product_form || - (privkey_packed_indices_len <= privkey_packed_trits_len)) { - *privkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_INDICES; - *privkey_blob_len = - 5 + pubkey_packed_len + privkey_packed_indices_len; - } else { - *privkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_TRITS; - *privkey_blob_len = - 5 + pubkey_packed_len + privkey_packed_trits_len; - } - } -} - - -/* ntru_crypto_ntru_encrypt_key_create_pubkey_blob - * - * Returns a public key blob, packed according to the packing type provided. - */ - -void -ntru_crypto_ntru_encrypt_key_create_pubkey_blob( - NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to - param set - parameters */ - uint16_t const *pubkey, /* in - pointer to the - coefficients - of the pubkey */ - uint8_t pubkey_pack_type, /* out - pubkey packing - type */ - uint8_t *pubkey_blob) /* out - addr for the - pubkey blob */ -{ - assert(params); - assert(pubkey); - assert(pubkey_blob); - - switch (pubkey_pack_type) { - case NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS: - *pubkey_blob++ = NTRU_ENCRYPT_PUBKEY_TAG; - *pubkey_blob++ = (uint8_t)sizeof(params->OID); - memcpy(pubkey_blob, params->OID, sizeof(params->OID)); - pubkey_blob += sizeof(params->OID); - ntru_elements_2_octets(params->N, pubkey, params->q_bits, - pubkey_blob); - break; - default: - assert(FALSE); - } -} - - -/* ntru_crypto_ntru_encrypt_key_create_privkey_blob - * - * Returns a private key blob, packed according to the packing type provided. - */ - -void -ntru_crypto_ntru_encrypt_key_create_privkey_blob( - NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to - param set - parameters */ - uint16_t const *pubkey, /* in - pointer to the - coefficients - of the pubkey */ - uint16_t const *privkey, /* in - pointer to the - indices of the - privkey */ - uint8_t privkey_pack_type, /* in - privkey packing - type */ - uint8_t *buf, /* in - temp, N bytes */ - uint8_t *privkey_blob) /* out - addr for the - privkey blob */ -{ - assert(params); - assert(pubkey); - assert(privkey); - assert(privkey_blob); - - switch (privkey_pack_type) { - case NTRU_ENCRYPT_KEY_PACKED_TRITS: - case NTRU_ENCRYPT_KEY_PACKED_INDICES: - - /* format header and packed public key */ - - *privkey_blob++ = NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG; - *privkey_blob++ = (uint8_t)sizeof(params->OID); - memcpy(privkey_blob, params->OID, sizeof(params->OID)); - privkey_blob += sizeof(params->OID); - ntru_elements_2_octets(params->N, pubkey, params->q_bits, - privkey_blob); - privkey_blob += (params->N * params->q_bits + 7) >> 3; - - /* add packed private key */ - - if (privkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_TRITS) { - ntru_indices_2_packed_trits(privkey, (uint16_t)params->dF_r, - (uint16_t)params->dF_r, - params->N, buf, privkey_blob); - } else { - uint32_t dF; - - if (params->is_product_form) { - dF = (params->dF_r & 0xff) + - ((params->dF_r >> 8) & 0xff) + - ((params->dF_r >> 16) & 0xff); - } else { - dF = params->dF_r; - } - ntru_elements_2_octets((uint16_t)dF << 1, privkey, - params->N_bits, privkey_blob); - } - break; - default: - assert(FALSE); - break; - } -} - - diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.h deleted file mode 100644 index 6734f2a4c..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.h +++ /dev/null @@ -1,167 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_cencrypt_key.h is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - - -#ifndef NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H -#define NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H - -#include "ntru_crypto_ntru_convert.h" -#include "ntru_crypto_ntru_encrypt_param_sets.h" - - -/* key-blob definitions */ - -#define NTRU_ENCRYPT_PUBKEY_TAG 0x01 -#define NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG 0x02 -#define NTRU_ENCRYPT_PRIVKEY_TRITS_TAG 0xfe -#define NTRU_ENCRYPT_PRIVKEY_INDICES_TAG 0xff - -/* packing types */ - -#define NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS 0x01 -#define NTRU_ENCRYPT_KEY_PACKED_INDICES 0x02 -#define NTRU_ENCRYPT_KEY_PACKED_TRITS 0x03 - -/* function declarations */ - - -/* ntru_crypto_ntru_encrypt_key_parse - * - * Parses an NTRUEncrypt key blob. - * If the blob is not corrupt, returns packing types for public and private - * keys, a pointer to the parameter set, a pointer to the public key, and - * a pointer to the private key if it exists. - * - * Returns TRUE if successful. - * Returns FALSE if the blob is invalid. - */ - -extern bool -ntru_crypto_ntru_encrypt_key_parse( - bool pubkey_parse, /* in - if parsing pubkey - blob */ - uint16_t key_blob_len, /* in - no. octets in key - blob */ - uint8_t const *key_blob, /* in - pointer to key blob */ - uint8_t *pubkey_pack_type, /* out - addr for pubkey - packing type */ - uint8_t *privkey_pack_type, /* out - addr for privkey - packing type */ - NTRU_ENCRYPT_PARAM_SET **params, /* out - addr for ptr to - parameter set */ - uint8_t const **pubkey, /* out - addr for ptr to - packed pubkey */ - uint8_t const **privkey); /* out - addr for ptr to - packed privkey */ - - -/* ntru_crypto_ntru_encrypt_key_get_blob_params - * - * Returns public and private key packing types and blob lengths given - * a packing format. For now, only a default packing format exists. - * - * Only public-key params may be returned by setting privkey_pack_type - * and privkey_blob_len to NULL. - */ - -extern void -ntru_crypto_ntru_encrypt_key_get_blob_params( - NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to - param set - parameters */ - uint8_t *pubkey_pack_type, /* out - addr for pubkey - packing type */ - uint16_t *pubkey_blob_len, /* out - addr for no. of - bytes in - pubkey blob */ - uint8_t *privkey_pack_type, /* out - addr for privkey - packing type */ - uint16_t *privkey_blob_len); /* out - addr for no. of - bytes in - privkey blob */ - - -/* ntru_crypto_ntru_encrypt_key_create_pubkey_blob - * - * Returns a public key blob, packed according to the packing type provided. - */ - -extern void -ntru_crypto_ntru_encrypt_key_create_pubkey_blob( - NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to - param set - parameters */ - uint16_t const *pubkey, /* in - pointer to the - coefficients - of the pubkey */ - uint8_t pubkey_pack_type, /* out - addr for pubkey - packing type */ - uint8_t *pubkey_blob); /* out - addr for the - pubkey blob */ - - -/* ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob - * - * Returns a public key blob, recreated from an already-packed public key. - */ - -extern void -ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob( - NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to - param set - parameters */ - uint16_t packed_pubkey_len, /* in - no. octets in - packed pubkey */ - uint8_t const *packed_pubkey, /* in - pointer to the - packed pubkey */ - uint8_t pubkey_pack_type, /* out - pubkey packing - type */ - uint8_t *pubkey_blob); /* out - addr for the - pubkey blob */ - - -/* ntru_crypto_ntru_encrypt_key_create_privkey_blob - * - * Returns a privlic key blob, packed according to the packing type provided. - */ - -extern void -ntru_crypto_ntru_encrypt_key_create_privkey_blob( - NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to - param set - parameters */ - uint16_t const *pubkey, /* in - pointer to the - coefficients - of the pubkey */ - uint16_t const *privkey, /* in - pointer to the - indices of the - privkey */ - uint8_t privkey_pack_type, /* in - privkey packing - type */ - uint8_t *buf, /* in - temp, N bytes */ - uint8_t *privkey_blob); /* out - addr for the - privkey blob */ - - -#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H */ diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h deleted file mode 100644 index e5e977a0e..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_encrypt_param_sets.h is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -/****************************************************************************** - * - * File: ntru_crypto_ntru_encrypt_param_sets.h - * - * Contents: Definitions and declarations for the NTRUEncrypt parameter sets. - * - *****************************************************************************/ - -#ifndef NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H -#define NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H - -#include "ntru_crypto.h" - -/* structures */ - -typedef struct _NTRU_ENCRYPT_PARAM_SET { - NTRU_ENCRYPT_PARAM_SET_ID id; /* parameter-set ID */ - uint8_t const OID[3]; /* pointer to OID */ - uint8_t der_id; /* parameter-set DER id */ - uint8_t N_bits; /* no. of bits in N (i.e. in - an index */ - uint16_t N; /* ring dimension */ - uint16_t sec_strength_len; /* no. of octets of - security strength */ - uint16_t q; /* big modulus */ - uint8_t q_bits; /* no. of bits in q (i.e. in - a coefficient */ - bool is_product_form; /* if product form used */ - uint32_t dF_r; /* no. of 1 or -1 coefficients - in ring elements F, r */ - uint16_t dg; /* no. - 1 of 1 coefficients - or no. of -1 coefficients - in ring element g */ - uint16_t m_len_max; /* max no. of plaintext - octets */ - uint16_t min_msg_rep_wt; /* min. message - representative weight */ - uint8_t c_bits; /* no. bits in candidate for - deriving an index in - IGF-2 */ - uint8_t m_len_len; /* no. of octets to hold - mLenOctets */ -} NTRU_ENCRYPT_PARAM_SET; - - - -/* function declarations */ - -/* ntru_encrypt_get_params_with_id - * - * Looks up a set of NTRU Encrypt parameters based on the id of the - * parameter set. - * - * Returns a pointer to the parameter set parameters if successful. - * Returns NULL if the parameter set cannot be found. - */ - -extern NTRU_ENCRYPT_PARAM_SET * -ntru_encrypt_get_params_with_id( - NTRU_ENCRYPT_PARAM_SET_ID id); /* in - parameter-set id */ - - -/* ntru_encrypt_get_params_with_OID - * - * Looks up a set of NTRU Encrypt parameters based on the OID of the - * parameter set. - * - * Returns a pointer to the parameter set parameters if successful. - * Returns NULL if the parameter set cannot be found. - */ - -extern NTRU_ENCRYPT_PARAM_SET * -ntru_encrypt_get_params_with_OID( - uint8_t const *oid); /* in - pointer to parameter-set OID */ - -#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H */ - diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.c deleted file mode 100644 index 8e4eede87..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.c +++ /dev/null @@ -1,242 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_poly.c is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -#include <stdlib.h> -#include <string.h> -#include "ntru_crypto_ntru_poly.h" - -/* ntru_poly_check_min_weight - * - * Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed - * a minimum weight. - */ - -bool -ntru_poly_check_min_weight( - uint16_t num_els, /* in - degree of polynomial */ - uint8_t *ringels, /* in - pointer to trinary ring elements */ - uint16_t min_wt) /* in - minimum weight */ -{ - uint16_t wt[3]; - uint16_t i; - - wt[0] = wt[1] = wt[2] = 0; - for (i = 0; i < num_els; i++) { - ++wt[ringels[i]]; - } - if ((wt[0] < min_wt) || (wt[1] < min_wt) || (wt[2] < min_wt)) { - return FALSE; - } - return TRUE; -} - -/* ntru_ring_mult_coefficients - * - * Multiplies ring element (polynomial) "a" by ring element (polynomial) "b" - * to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1). - * This is a convolution operation. - * - * Ring element "b" has coefficients in the range [0,N). - * - * This assumes q is 2^r where 8 < r < 16, so that overflow of the sum - * beyond 16 bits does not matter. - */ - -void -ntru_ring_mult_coefficients( - uint16_t const *a, /* in - pointer to polynomial a */ - uint16_t const *b, /* in - pointer to polynomial b */ - uint16_t N, /* in - no. of coefficients in a, b, c */ - uint16_t q, /* in - large modulus */ - uint16_t *c) /* out - address for polynomial c */ -{ - uint16_t const *bptr = b; - uint16_t mod_q_mask = q - 1; - uint16_t i, k; - - /* c[k] = sum(a[i] * b[k-i]) mod q */ - memset(c, 0, N * sizeof(uint16_t)); - for (k = 0; k < N; k++) { - i = 0; - while (i <= k) - c[k] += a[i++] * *bptr--; - bptr += N; - while (i < N) - c[k] += a[i++] * *bptr--; - c[k] &= mod_q_mask; - ++bptr; - } -} - - -/* ntru_ring_inv - * - * Finds the inverse of a polynomial, a, in (Z/2^rZ)[X]/(X^N - 1). - * - * This assumes q is 2^r where 8 < r < 16, so that operations mod q can - * wait until the end, and only 16-bit arrays need to be used. - */ - -bool -ntru_ring_inv( - uint16_t *a, /* in - pointer to polynomial a */ - uint16_t N, /* in - no. of coefficients in a */ - uint16_t q, /* in - large modulus */ - uint16_t *t, /* in - temp buffer of 2N elements */ - uint16_t *a_inv) /* out - address for polynomial a^-1 */ -{ - uint8_t *b = (uint8_t *)t; /* b cannot be in a_inv since it must be - rotated and copied there as a^-1 mod 2 */ - uint8_t *c = b + N; /* c cannot be in a_inv since it exchanges - with b, and b cannot be in a_inv */ - uint8_t *f = c + N; - uint8_t *g = (uint8_t *)a_inv; /* g needs N + 1 bytes */ - uint16_t *t2 = t + N; - uint16_t deg_b; - uint16_t deg_c; - uint16_t deg_f; - uint16_t deg_g; - uint16_t k = 0; - bool done = FALSE; - uint16_t i, j; - - /* form a^-1 in (Z/2Z)[X]/X^N - 1) */ - memset(b, 0, (N << 1)); /* clear to init b, c */ - - /* b(X) = 1 */ - b[0] = 1; - deg_b = 0; - - /* c(X) = 0 (cleared above) */ - deg_c = 0; - - /* f(X) = a(X) mod 2 */ - for (i = 0; i < N; i++) - f[i] = (uint8_t)(a[i] & 1); - deg_f = N - 1; - - /* g(X) = X^N - 1 */ - g[0] = 1; - memset(g + 1, 0, N - 1); - g[N] = 1; - deg_g = N; - - /* until f(X) = 1 */ - - while (!done) - { - - /* while f[0] = 0, f(X) /= X, c(X) *= X, k++ */ - - for (i = 0; (i <= deg_f) && (f[i] == 0); ++i); - if (i > deg_f) - return FALSE; - if (i) { - f = f + i; - deg_f = deg_f - i; - deg_c = deg_c + i; - for (j = deg_c; j >= i; j--) - c[j] = c[j-i]; - for (j = 0; j < i; j++) - c[j] = 0; - k = k + i; - } - - /* adjust degree of f(X) if the highest coefficients are zero - * Note: f[0] = 1 from above so the loop will terminate. - */ - - while (f[deg_f] == 0) - --deg_f; - - /* if f(X) = 1, done - * Note: f[0] = 1 from above, so only check the x term and up - */ - - for (i = 1; (i <= deg_f) && (f[i] == 0); ++i); - if (i > deg_f) { - done = TRUE; - break; - } - - /* if deg_f < deg_g, f <-> g, b <-> c */ - - if (deg_f < deg_g) { - uint8_t *x; - - x = f; - f = g; - g = x; - deg_f ^= deg_g; - deg_g ^= deg_f; - deg_f ^= deg_g; - x = b; - b = c; - c = x; - deg_b ^= deg_c; - deg_c ^= deg_b; - deg_b ^= deg_c; - } - - /* f(X) += g(X), b(X) += c(X) */ - - for (i = 0; i <= deg_g; i++) - f[i] ^= g[i]; - - if (deg_c > deg_b) - deg_b = deg_c; - for (i = 0; i <= deg_c; i++) - b[i] ^= c[i]; - } - - /* a^-1 in (Z/2Z)[X]/(X^N - 1) = b(X) shifted left k coefficients */ - - j = 0; - if (k >= N) - k = k - N; - for (i = k; i < N; i++) - a_inv[j++] = (uint16_t)(b[i]); - for (i = 0; i < k; i++) - a_inv[j++] = (uint16_t)(b[i]); - - /* lift a^-1 in (Z/2Z)[X]/(X^N - 1) to a^-1 in (Z/qZ)[X]/(X^N -1) */ - - for (j = 0; j < 4; ++j) { /* assumes 256 < q <= 65536 */ - - /* a^-1 = a^-1 * (2 - a * a^-1) mod q */ - - memcpy(t2, a_inv, N * sizeof(uint16_t)); - ntru_ring_mult_coefficients(a, t2, N, q, t); - for (i = 0; i < N; ++i) - t[i] = q - t[i]; - t[0] = t[0] + 2; - ntru_ring_mult_coefficients(t2, t, N, q, a_inv); - } - - return TRUE; - - -} - - diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.h deleted file mode 100644 index 1e9d467ed..000000000 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.h +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_poly.h is a component of ntru-crypto. - * - * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -/****************************************************************************** - * - * File: ntru_crypto_ntru_poly.h - * - * Contents: Public header file for generating and operating on polynomials - * in the NTRU algorithm. - * - *****************************************************************************/ - - -#ifndef NTRU_CRYPTO_NTRU_POLY_H -#define NTRU_CRYPTO_NTRU_POLY_H - - -#include "ntru_crypto.h" - -#include <crypto/hashers/hasher.h> - - -/* function declarations */ - -/* ntru_poly_check_min_weight - * - * Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed - * a minimum weight. - */ - -extern bool -ntru_poly_check_min_weight( - uint16_t num_els, /* in - degree of polynomial */ - uint8_t *ringels, /* in - pointer to trinary ring elements */ - uint16_t min_wt); /* in - minimum weight */ - -/* ntru_ring_mult_coefficients - * - * Multiplies ring element (polynomial) "a" by ring element (polynomial) "b" - * to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1). - * This is a convolution operation. - * - * Ring element "b" has coefficients in the range [0,N). - * - * This assumes q is 2^r where 8 < r < 16, so that overflow of the sum - * beyond 16 bits does not matter. - */ - -extern void -ntru_ring_mult_coefficients( - uint16_t const *a, /* in - pointer to polynomial a */ - uint16_t const *b, /* in - pointer to polynomial b */ - uint16_t N, /* in - no. of coefficients in a, b, c */ - uint16_t q, /* in - large modulus */ - uint16_t *c); /* out - address for polynomial c */ - - -/* ntru_ring_inv - * - * Finds the inverse of a polynomial, a, in (Z/2^rZ)[X]/(X^N - 1). - * - * This assumes q is 2^r where 8 < r < 16, so that operations mod q can - * wait until the end, and only 16-bit arrays need to be used. - */ - -extern bool -ntru_ring_inv( - uint16_t *a, /* in - pointer to polynomial a */ - uint16_t N, /* in - no. of coefficients in a */ - uint16_t q, /* in - large modulus */ - uint16_t *t, /* in - temp buffer of 2N elements */ - uint16_t *a_inv); /* out - address for polynomial a^-1 */ - - -#endif /* NTRU_CRYPTO_NTRU_POLY_H */ diff --git a/src/libstrongswan/plugins/ntru/ntru_drbg.c b/src/libstrongswan/plugins/ntru/ntru_drbg.c index 181a58939..ef0d3d9c8 100644 --- a/src/libstrongswan/plugins/ntru/ntru_drbg.c +++ b/src/libstrongswan/plugins/ntru/ntru_drbg.c @@ -67,6 +67,10 @@ struct private_ntru_drbg_t { */ chunk_t value; + /** + * reference count + */ + refcount_t ref; }; /** @@ -180,13 +184,23 @@ METHOD(ntru_drbg_t, generate, bool, return TRUE; } +METHOD(ntru_drbg_t, get_ref, ntru_drbg_t*, + private_ntru_drbg_t *this) +{ + ref_get(&this->ref); + return &this->public; +} + METHOD(ntru_drbg_t, destroy, void, private_ntru_drbg_t *this) { - this->hmac->destroy(this->hmac); - chunk_clear(&this->key); - chunk_clear(&this->value); - free(this); + if (ref_put(&this->ref)) + { + this->hmac->destroy(this->hmac); + chunk_clear(&this->key); + chunk_clear(&this->value); + free(this); + } } /* @@ -238,6 +252,7 @@ ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str, .get_strength = _get_strength, .reseed = _reseed, .generate = _generate, + .get_ref = _get_ref, .destroy = _destroy, }, .strength = strength, @@ -247,6 +262,7 @@ ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str, .value = chunk_alloc(hmac->get_block_size(hmac)), .max_requests = max_requests, .reseed_counter = 1, + .ref = 1, ); memset(this->key.ptr, 0x00, this->key.len); diff --git a/src/libstrongswan/plugins/ntru/ntru_drbg.h b/src/libstrongswan/plugins/ntru/ntru_drbg.h index 38ac718ae..83cef11be 100644 --- a/src/libstrongswan/plugins/ntru/ntru_drbg.h +++ b/src/libstrongswan/plugins/ntru/ntru_drbg.h @@ -58,6 +58,13 @@ struct ntru_drbg_t { u_int8_t *out); /** + * Get a reference on an ntru_drbg_t object increasing the count by one + * + * @return reference to the ntru_drbg_t object + */ + ntru_drbg_t* (*get_ref)(ntru_drbg_t *this); + + /** * Uninstantiate and destroy the DRBG object */ void (*destroy)(ntru_drbg_t *this); diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.c b/src/libstrongswan/plugins/ntru/ntru_ke.c index 39fb261cd..abaa22336 100644 --- a/src/libstrongswan/plugins/ntru/ntru_ke.c +++ b/src/libstrongswan/plugins/ntru/ntru_ke.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andreas Steffen + * Copyright (C) 2013-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,54 +15,33 @@ #include "ntru_ke.h" #include "ntru_drbg.h" - -#include "ntru_crypto/ntru_crypto.h" +#include "ntru_param_set.h" +#include "ntru_private_key.h" +#include "ntru_public_key.h" #include <crypto/diffie_hellman.h> #include <utils/debug.h> typedef struct private_ntru_ke_t private_ntru_ke_t; -typedef struct param_set_t param_set_t; - -/** - * Defines an NTRU parameter set by ID or OID - */ -struct param_set_t { - NTRU_ENCRYPT_PARAM_SET_ID id; - char oid[3]; - char *name; -}; /* Best bandwidth and speed, no X9.98 compatibility */ -static param_set_t param_sets_optimum[] = { - { NTRU_EES401EP2, {0x00, 0x02, 0x10}, "ees401ep2" }, - { NTRU_EES439EP1, {0x00, 0x03, 0x10}, "ees439ep1" }, - { NTRU_EES593EP1, {0x00, 0x05, 0x10}, "ees593ep1" }, - { NTRU_EES743EP1, {0x00, 0x06, 0x10}, "ees743ep1" } +static ntru_param_set_id_t param_sets_optimum[] = { + NTRU_EES401EP2, NTRU_EES439EP1, NTRU_EES593EP1, NTRU_EES743EP1 }; /* X9.98/IEEE 1363.1 parameter sets for best speed */ -static param_set_t param_sets_x9_98_speed[] = { - { NTRU_EES659EP1, {0x00, 0x02, 0x06}, "ees659ep1" }, - { NTRU_EES761EP1, {0x00, 0x03, 0x05}, "ees761ep1" }, - { NTRU_EES1087EP1, {0x00, 0x05, 0x05}, "ees1087ep1" }, - { NTRU_EES1499EP1, {0x00, 0x06, 0x05}, "ees1499ep1" } +static ntru_param_set_id_t param_sets_x9_98_speed[] = { + NTRU_EES659EP1, NTRU_EES761EP1, NTRU_EES1087EP1, NTRU_EES1499EP1 }; /* X9.98/IEEE 1363.1 parameter sets for best bandwidth (smallest size) */ -static param_set_t param_sets_x9_98_bandwidth[] = { - { NTRU_EES401EP1, {0x00, 0x02, 0x04}, "ees401ep1" }, - { NTRU_EES449EP1, {0x00, 0x03, 0x03}, "ees449ep1" }, - { NTRU_EES677EP1, {0x00, 0x05, 0x03}, "ees677ep1" }, - { NTRU_EES1087EP2, {0x00, 0x06, 0x03}, "ees1087ep2" } +static ntru_param_set_id_t param_sets_x9_98_bandwidth[] = { + NTRU_EES401EP1, NTRU_EES449EP1, NTRU_EES677EP1, NTRU_EES1087EP2 }; /* X9.98/IEEE 1363.1 parameter sets balancing speed and bandwidth */ -static param_set_t param_sets_x9_98_balance[] = { - { NTRU_EES541EP1, {0x00, 0x02, 0x05}, "ees541ep1" }, - { NTRU_EES613EP1, {0x00, 0x03, 0x04}, "ees613ep1" }, - { NTRU_EES887EP1, {0x00, 0x05, 0x04}, "ees887ep1" }, - { NTRU_EES1171EP1, {0x00, 0x06, 0x04}, "ees1171ep1" } +static ntru_param_set_id_t param_sets_x9_98_balance[] = { + NTRU_EES541EP1, NTRU_EES613EP1, NTRU_EES887EP1, NTRU_EES1171EP1 }; /** @@ -82,7 +61,7 @@ struct private_ntru_ke_t { /** * NTRU Parameter Set */ - param_set_t *param_set; + ntru_param_set_t *param_set; /** * Cryptographical strength in bits of the NTRU Parameter Set @@ -92,12 +71,12 @@ struct private_ntru_ke_t { /** * NTRU Public Key */ - chunk_t pub_key; + ntru_public_key_t *pubkey; /** * NTRU Private Key */ - chunk_t priv_key; + ntru_private_key_t *privkey; /** * NTRU encrypted shared secret @@ -133,8 +112,6 @@ struct private_ntru_ke_t { METHOD(diffie_hellman_t, get_my_public_value, void, private_ntru_ke_t *this, chunk_t *value) { - uint16_t pub_key_len, priv_key_len; - *value = chunk_empty; if (this->responder) @@ -146,34 +123,19 @@ METHOD(diffie_hellman_t, get_my_public_value, void, } else { - if (this->pub_key.len == 0) + if (!this->pubkey) { - /* determine the NTRU public and private key sizes */ - if (ntru_crypto_ntru_encrypt_keygen(this->drbg, this->param_set->id, - &pub_key_len, NULL, - &priv_key_len, NULL) != NTRU_OK) - { - DBG1(DBG_LIB, "error determining NTRU public and private key " - "sizes"); - return; - } - this->pub_key = chunk_alloc(pub_key_len); - this->priv_key = chunk_alloc(priv_key_len); - /* generate a random NTRU public/private key pair */ - if (ntru_crypto_ntru_encrypt_keygen(this->drbg, this->param_set->id, - &pub_key_len, this->pub_key.ptr, - &priv_key_len, this->priv_key.ptr) != NTRU_OK) + this->privkey = ntru_private_key_create(this->drbg, this->param_set); + if (!this->privkey) { DBG1(DBG_LIB, "NTRU keypair generation failed"); - chunk_free(&this->priv_key); - chunk_free(&this->pub_key); return; } - DBG3(DBG_LIB, "NTRU public key: %B", &this->pub_key); - DBG4(DBG_LIB, "NTRU private key: %B", &this->priv_key); + this->pubkey = this->privkey->get_public_key(this->privkey); } - *value = chunk_clone(this->pub_key); + *value = chunk_clone(this->pubkey->get_encoding(this->pubkey)); + DBG3(DBG_LIB, "NTRU public key: %B", value); } } @@ -194,9 +156,7 @@ METHOD(diffie_hellman_t, get_shared_secret, status_t, METHOD(diffie_hellman_t, set_other_public_value, void, private_ntru_ke_t *this, chunk_t value) { - u_int16_t plaintext_len, ciphertext_len; - - if (this->priv_key.len) + if (this->privkey) { /* initiator decrypting shared secret */ if (value.len == 0) @@ -204,48 +164,36 @@ METHOD(diffie_hellman_t, set_other_public_value, void, DBG1(DBG_LIB, "empty NTRU ciphertext"); return; } - this->ciphertext = chunk_clone(value); - DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext); - - /* determine the size of the maximum plaintext */ - if (ntru_crypto_ntru_decrypt(this->priv_key.len, this->priv_key.ptr, - this->ciphertext.len, this->ciphertext.ptr, - &plaintext_len, NULL) != NTRU_OK) - { - DBG1(DBG_LIB, "error determining maximum plaintext size"); - return; - } - this->shared_secret = chunk_alloc(plaintext_len); + DBG3(DBG_LIB, "NTRU ciphertext: %B", &value); /* decrypt the shared secret */ - if (ntru_crypto_ntru_decrypt(this->priv_key.len, this->priv_key.ptr, - this->ciphertext.len, this->ciphertext.ptr, - &plaintext_len, this->shared_secret.ptr) != NTRU_OK) + if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret)) { DBG1(DBG_LIB, "NTRU decryption of shared secret failed"); - chunk_free(&this->shared_secret); return; } - this->shared_secret.len = plaintext_len; this->computed = TRUE; } else { + ntru_public_key_t *pubkey; + /* responder generating and encrypting the shared secret */ this->responder = TRUE; - /* check the NTRU public key format */ - if (value.len < 5 || value.ptr[0] != 1 || value.ptr[1] != 3) + DBG3(DBG_LIB, "NTRU public key: %B", &value); + pubkey = ntru_public_key_create_from_data(this->drbg, value); + if (!pubkey) { - DBG1(DBG_LIB, "received NTRU public key with invalid header"); return; } - if (!memeq(value.ptr + 2, this->param_set->oid, 3)) + if (pubkey->get_id(pubkey) != this->param_set->id) { - DBG1(DBG_LIB, "received NTRU public key with wrong OID"); + DBG1(DBG_LIB, "received NTRU public key with wrong OUI"); + pubkey->destroy(pubkey); return; } - this->pub_key = chunk_clone(value); + this->pubkey = pubkey; /* shared secret size is chosen as twice the cryptographical strength */ this->shared_secret = chunk_alloc(2 * this->strength / BITS_PER_BYTE); @@ -260,25 +208,10 @@ METHOD(diffie_hellman_t, set_other_public_value, void, } this->computed = TRUE; - /* determine the size of the ciphertext */ - if (ntru_crypto_ntru_encrypt(this->drbg, - this->pub_key.len, this->pub_key.ptr, - this->shared_secret.len, this->shared_secret.ptr, - &ciphertext_len, NULL) != NTRU_OK) - { - DBG1(DBG_LIB, "error determining ciphertext size"); - return; - } - this->ciphertext = chunk_alloc(ciphertext_len); - /* encrypt the shared secret */ - if (ntru_crypto_ntru_encrypt(this->drbg, - this->pub_key.len, this->pub_key.ptr, - this->shared_secret.len, this->shared_secret.ptr, - &ciphertext_len, this->ciphertext.ptr) != NTRU_OK) + if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext)) { DBG1(DBG_LIB, "NTRU encryption of shared secret failed"); - chunk_free(&this->ciphertext); return; } DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext); @@ -294,11 +227,11 @@ METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, METHOD(diffie_hellman_t, destroy, void, private_ntru_ke_t *this) { + DESTROY_IF(this->privkey); + DESTROY_IF(this->pubkey); this->drbg->destroy(this->drbg); this->entropy->destroy(this->entropy); - chunk_free(&this->pub_key); chunk_free(&this->ciphertext); - chunk_clear(&this->priv_key); chunk_clear(&this->shared_secret); free(this); } @@ -309,7 +242,7 @@ METHOD(diffie_hellman_t, destroy, void, ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) { private_ntru_ke_t *this; - param_set_t *param_sets, *param_set; + ntru_param_set_id_t *param_sets, param_set_id; rng_t *entropy; ntru_drbg_t *drbg; char *parameter_set; @@ -339,25 +272,25 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) { case NTRU_112_BIT: strength = 112; - param_set = ¶m_sets[0]; + param_set_id = param_sets[0]; break; case NTRU_128_BIT: strength = 128; - param_set = ¶m_sets[1]; + param_set_id = param_sets[1]; break; case NTRU_192_BIT: strength = 192; - param_set = ¶m_sets[2]; + param_set_id = param_sets[2]; break; case NTRU_256_BIT: strength = 256; - param_set = ¶m_sets[3]; + param_set_id = param_sets[3]; break; default: return NULL; } - DBG1(DBG_LIB, "%u bit %s NTRU parameter set %s selected", strength, - parameter_set, param_set->name); + DBG1(DBG_LIB, "%u bit %s NTRU parameter set %N selected", strength, + parameter_set, ntru_param_set_id_names, param_set_id); entropy = lib->crypto->create_rng(lib->crypto, RNG_TRUE); if (!entropy) @@ -385,7 +318,7 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) }, }, .group = group, - .param_set = param_set, + .param_set = ntru_param_set_get_by_id(param_set_id), .strength = strength, .entropy = entropy, .drbg = drbg, diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c b/src/libstrongswan/plugins/ntru/ntru_param_set.c index 5ddf91d2a..4af1e3091 100644 --- a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c +++ b/src/libstrongswan/plugins/ntru/ntru_param_set.c @@ -1,44 +1,49 @@ -/****************************************************************************** - * NTRU Cryptography Reference Source Code - * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved. - * - * ntru_crypto_ntru_param_sets.c is a component of ntru-crypto. +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * Copyright (C) 2009-2013 Security Innovation - * - * 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 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - *****************************************************************************/ - -/****************************************************************************** - * - * File: ntru_crypto_ntru_encrypt_param_sets.c * - * Contents: Defines the NTRUEncrypt parameter sets. + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. * - *****************************************************************************/ - -#include <stdlib.h> -#include <string.h> -#include "ntru_crypto_ntru_encrypt_param_sets.h" - - -/* parameter sets */ + * 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. + */ -static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = { +#include "ntru_param_set.h" + +#include <utils/test.h> + +ENUM(ntru_param_set_id_names, NTRU_EES401EP1, NTRU_EES743EP1, + "ees401ep1", + "ees449ep1", + "ees677ep1", + "ees1087ep2", + "ees541ep1", + "ees613ep1", + "ees887ep1", + "ees1171ep1", + "ees659ep1", + "ees761ep1", + "ees1087ep1", + "ees1499ep1", + "ees401ep2", + "ees439ep1", + "ees593ep1", + "ees743ep1" +); + +/** + * NTRU encryption parameter set definitions + */ +static ntru_param_set_t ntru_param_sets[] = { + /* X9.98/IEEE 1363.1 parameter sets for best bandwidth (smallest size) */ { NTRU_EES401EP1, /* parameter-set id */ {0x00, 0x02, 0x04}, /* OID */ @@ -97,7 +102,7 @@ static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = { NTRU_EES1087EP2, /* parameter-set id */ {0x00, 0x06, 0x03}, /* OID */ 0x25, /* DER id */ - 10, /* no. of bits in N (i.e., in an index) */ + 11, /* no. of bits in N (i.e., in an index) */ 1087, /* N */ 32, /* security strength in octets */ 2048, /* q */ @@ -111,6 +116,7 @@ static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = { 1, /* lLen */ }, + /* X9.98/IEEE 1363.1 parameter sets balancing speed and bandwidth */ { NTRU_EES541EP1, /* parameter-set id */ {0x00, 0x02, 0x05}, /* OID */ @@ -183,6 +189,7 @@ static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = { 1, /* lLen */ }, + /* X9.98/IEEE 1363.1 parameter sets for best speed */ { NTRU_EES659EP1, /* parameter-set id */ {0x00, 0x02, 0x06}, /* OID */ @@ -255,6 +262,7 @@ static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = { 1, /* lLen */ }, + /* Best bandwidth and speed, no X9.98 compatibility */ { NTRU_EES401EP2, /* parameter-set id */ {0x00, 0x02, 0x10}, /* OID */ @@ -329,56 +337,39 @@ static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = { }; -static size_t numParamSets = - sizeof(ntruParamSets)/sizeof(NTRU_ENCRYPT_PARAM_SET); - - -/* functions */ - -/* ntru_encrypt_get_params_with_id - * - * Looks up a set of NTRUEncrypt parameters based on the id of the - * parameter set. - * - * Returns a pointer to the parameter set parameters if successful. - * Returns NULL if the parameter set cannot be found. +/** + * See header. */ - -NTRU_ENCRYPT_PARAM_SET * -ntru_encrypt_get_params_with_id( - NTRU_ENCRYPT_PARAM_SET_ID id) /* in - parameter-set id */ +ntru_param_set_t* ntru_param_set_get_by_id(ntru_param_set_id_t id) { - size_t i; - - for (i = 0; i < numParamSets; i++) { - if (ntruParamSets[i].id == id) { - return &(ntruParamSets[i]); - } - } - return NULL; + int i; + + for (i = 0; i < countof(ntru_param_sets); i++) + { + if (ntru_param_sets[i].id == id) + { + return &ntru_param_sets[i]; + } + } + return NULL; } -/* ntru_encrypt_get_params_with_OID - * - * Looks up a set of NTRUEncrypt parameters based on the OID of the - * parameter set. - * - * Returns a pointer to the parameter set parameters if successful. - * Returns NULL if the parameter set cannot be found. +/** + * See header. */ - -NTRU_ENCRYPT_PARAM_SET * -ntru_encrypt_get_params_with_OID( - uint8_t const *oid) /* in - pointer to parameter-set OID */ +ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid) { - size_t i; - - for (i = 0; i < numParamSets; i++) { - if (!memcmp(ntruParamSets[i].OID, oid, 3)) { - return &(ntruParamSets[i]); - } - } - return NULL; + int i; + + for (i = 0; i < countof(ntru_param_sets); i++) + { + if (memeq(ntru_param_sets[i].oid, oid, 3)) + { + return &ntru_param_sets[i]; + } + } + return NULL; } +EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_param_set_get_by_id); diff --git a/src/libstrongswan/plugins/ntru/ntru_param_set.h b/src/libstrongswan/plugins/ntru/ntru_param_set.h new file mode 100644 index 000000000..df4e55333 --- /dev/null +++ b/src/libstrongswan/plugins/ntru/ntru_param_set.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Copyright (C) 2009-2013 Security Innovation + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup ntru_param_set ntru_param_set + * @{ @ingroup ntru_p + */ + +#ifndef NTRU_PARAM_SET_H_ +#define NTRU_PARAM_SET_H_ + +typedef enum ntru_param_set_id_t ntru_param_set_id_t; +typedef struct ntru_param_set_t ntru_param_set_t; + +#include <library.h> + +/** + * Encoding types for NTRU encryption public/private key blobs + */ +#define NTRU_PUBKEY_TAG 0x01 +#define NTRU_PRIVKEY_DEFAULT_TAG 0x02 +#define NTRU_PRIVKEY_TRITS_TAG 0xfe +#define NTRU_PRIVKEY_INDICES_TAG 0xff + +/** + * Size in octets of the OID designating the NTRU encryption parameter set + */ +#define NTRU_OID_LEN 3 + +/** + * Packing types for NTRU encryption public/private keys + */ +#define NTRU_KEY_PACKED_COEFFICIENTS 0x01 +#define NTRU_KEY_PACKED_INDICES 0x02 +#define NTRU_KEY_PACKED_TRITS 0x03 + +/** + * NTRU encryption parameter set ID list + */ +enum ntru_param_set_id_t { + /* X9.98/IEEE 1363.1 parameter sets for best bandwidth (smallest size) */ + NTRU_EES401EP1, + NTRU_EES449EP1, + NTRU_EES677EP1, + NTRU_EES1087EP2, + /* X9.98/IEEE 1363.1 parameter sets balancing speed and bandwidth */ + NTRU_EES541EP1, + NTRU_EES613EP1, + NTRU_EES887EP1, + NTRU_EES1171EP1, + /* X9.98/IEEE 1363.1 parameter sets for best speed */ + NTRU_EES659EP1, + NTRU_EES761EP1, + NTRU_EES1087EP1, + NTRU_EES1499EP1, + /* Best bandwidth and speed, no X9.98 compatibility */ + NTRU_EES401EP2, + NTRU_EES439EP1, + NTRU_EES593EP1, + NTRU_EES743EP1, +}; + +extern enum_name_t *ntru_param_set_id_names; + +/** + * NTRU encryption parameter set definitions + */ +struct ntru_param_set_t { + ntru_param_set_id_t id; /* NTRU parameter set ID */ + uint8_t oid[NTRU_OID_LEN]; /* pointer to OID */ + uint8_t der_id; /* parameter-set DER id */ + uint8_t N_bits; /* no. of bits in N (i.e. in an index */ + uint16_t N; /* ring dimension */ + uint16_t sec_strength_len; /* no. of octets of security strength */ + uint16_t q; /* big modulus */ + uint8_t q_bits; /* no. of bits in q (i.e. in a coefficient */ + bool is_product_form; /* if product form used */ + uint32_t dF_r; /* no. of +1 or -1 coefficients in ring elements + F, r */ + uint16_t dg; /* no. - 1 of +1 coefficients or + no. of -1 coefficients in ring element g */ + uint16_t m_len_max; /* max no. of plaintext octets */ + uint16_t min_msg_rep_wt; /* min. message representative weight */ + uint8_t c_bits; /* no. bits in candidate for deriving an index */ + uint8_t m_len_len; /* no. of octets to hold mLenOctets */ +}; + +/** + * Get NTRU encryption parameter set by NTRU parameter set ID + * + * @param id NTRU parameter set ID + * @return NTRU parameter set +*/ +ntru_param_set_t* ntru_param_set_get_by_id(ntru_param_set_id_t id); + +/** + * Get NTRU encryption parameter set by NTRU parameter set OID + * + * @param oid NTRU parameter set OID + * @return NTRU parameter set +*/ +ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid); + +#endif /** NTRU_PARAM_SET_H_ @}*/ diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_poly.c index 3f754f2a0..77ab54a5c 100644 --- a/src/libstrongswan/plugins/ntru/ntru_poly.c +++ b/src/libstrongswan/plugins/ntru/ntru_poly.c @@ -239,11 +239,29 @@ METHOD(ntru_poly_t, destroy, void, free(this); } -static void init_indices(private_ntru_poly_t *this, bool is_product_form, - uint32_t indices_len_p, uint32_t indices_len_m) +/** + * Creates an empty ntru_poly_t object with space allocated for indices + */ +static private_ntru_poly_t* ntru_poly_create(uint16_t N, uint16_t q, + uint32_t indices_len_p, + uint32_t indices_len_m, + bool is_product_form) { + private_ntru_poly_t *this; int n; + INIT(this, + .public = { + .get_size = _get_size, + .get_indices = _get_indices, + .get_array = _get_array, + .ring_mult = _ring_mult, + .destroy = _destroy, + }, + .N = N, + .q = q, + ); + if (is_product_form) { this->num_polynomials = 3; @@ -265,6 +283,8 @@ static void init_indices(private_ntru_poly_t *this, bool is_product_form, this->num_indices = indices_len_p + indices_len_m; } this->indices = malloc(sizeof(uint16_t) * this->num_indices); + + return this; } /* @@ -291,19 +311,8 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, } i = hash_len = mgf1->get_hash_size(mgf1); - INIT(this, - .public = { - .get_size = _get_size, - .get_indices = _get_indices, - .get_array = _get_array, - .ring_mult = _ring_mult, - .destroy = _destroy, - }, - .N = N, - .q = q, - ); + this = ntru_poly_create(N, q, indices_len_p, indices_len_m, is_product_form); - init_indices(this, is_product_form, indices_len_p, indices_len_m); used = malloc(N); limit = N * ((1 << c_bits) / N); @@ -390,19 +399,8 @@ ntru_poly_t *ntru_poly_create_from_data(uint16_t *data, uint16_t N, uint16_t q, private_ntru_poly_t *this; int i; - INIT(this, - .public = { - .get_size = _get_size, - .get_indices = _get_indices, - .get_array = _get_array, - .ring_mult = _ring_mult, - .destroy = _destroy, - }, - .N = N, - .q = q, - ); + this = ntru_poly_create(N, q, indices_len_p, indices_len_m, is_product_form); - init_indices(this, is_product_form, indices_len_p, indices_len_m); for (i = 0; i < this->num_indices; i++) { this->indices[i] = data[i]; diff --git a/src/libstrongswan/plugins/ntru/ntru_private_key.c b/src/libstrongswan/plugins/ntru/ntru_private_key.c new file mode 100644 index 000000000..fa87fe9c3 --- /dev/null +++ b/src/libstrongswan/plugins/ntru/ntru_private_key.c @@ -0,0 +1,892 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Copyright (C) 2009-2013 Security Innovation + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include "ntru_private_key.h" +#include "ntru_trits.h" +#include "ntru_poly.h" +#include "ntru_convert.h" + +#include <utils/debug.h> +#include <utils/test.h> + +typedef struct private_ntru_private_key_t private_ntru_private_key_t; + +/** + * Private data of an ntru_private_key_t object. + */ +struct private_ntru_private_key_t { + + /** + * Public ntru_private_key_t interface. + */ + ntru_private_key_t public; + + /** + * NTRU Parameter Set + */ + ntru_param_set_t *params; + + /** + * Polynomial F which is the private key + */ + ntru_poly_t *privkey; + + /** + * Polynomial h which is the public key + */ + uint16_t *pubkey; + + /** + * Encoding of the private key + */ + chunk_t encoding; + + /** + * Deterministic Random Bit Generator + */ + ntru_drbg_t *drbg; + +}; + +METHOD(ntru_private_key_t, get_id, ntru_param_set_id_t, + private_ntru_private_key_t *this) +{ + return this->params->id; +} + +METHOD(ntru_private_key_t, get_public_key, ntru_public_key_t*, + private_ntru_private_key_t *this) +{ + return ntru_public_key_create(this->drbg, this->params, this->pubkey); +} + +/** + * Generate NTRU encryption private key encoding + */ +static void generate_encoding(private_ntru_private_key_t *this) +{ + size_t pubkey_len, privkey_len, privkey_trits_len, privkey_indices_len; + int privkey_pack_type; + uint16_t *indices; + uint8_t *trits; + u_char *enc; + + /* compute public key length encoded as packed coefficients */ + pubkey_len = (this->params->N * this->params->q_bits + 7) / 8; + + /* compute private key length encoded as packed trits coefficients */ + privkey_trits_len = (this->params->N + 4) / 5; + + /* compute private key length encoded as packed indices */ + privkey_indices_len = (this->privkey->get_size(this->privkey) * + this->params->N_bits + 7) / 8; + + if (this->params->is_product_form || + privkey_indices_len <= privkey_trits_len) + { + privkey_pack_type = NTRU_KEY_PACKED_INDICES; + privkey_len = privkey_indices_len; + } + else + { + privkey_pack_type = NTRU_KEY_PACKED_TRITS; + privkey_len = privkey_trits_len; + } + + /* allocate memory for private key encoding */ + this->encoding = chunk_alloc(2 + NTRU_OID_LEN + pubkey_len + privkey_len); + enc = this->encoding.ptr; + + /* format header and packed public key */ + *enc++ = NTRU_PRIVKEY_DEFAULT_TAG; + *enc++ = NTRU_OID_LEN; + memcpy(enc, this->params->oid, NTRU_OID_LEN); + enc += NTRU_OID_LEN; + ntru_elements_2_octets(this->params->N, this->pubkey, + this->params->q_bits, enc); + enc += pubkey_len; + + /* add packed private key */ + indices = this->privkey->get_indices(this->privkey); + + if (privkey_pack_type == NTRU_KEY_PACKED_TRITS) + { + /* encode private key as packed trits */ + trits = malloc(this->params->N); + ntru_indices_2_packed_trits(indices, this->params->dF_r, + this->params->dF_r, this->params->N, trits, enc); + memwipe(trits, this->params->N); + free(trits); + } + else + { + /* encode private key as packed indices */ + ntru_elements_2_octets(this->privkey->get_size(this->privkey), + indices, this->params->N_bits, enc); + } +} + +METHOD(ntru_private_key_t, get_encoding, chunk_t, + private_ntru_private_key_t *this) +{ + return this->encoding; +} + +/** + * Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed + * a minimum weight. + * + * @param N degree of polynomial + * @param t array of trinary ring elements + * @param min_wt minimum weight + * @return TRUE if minimum weight met or exceeded + */ +bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt) +{ + uint16_t wt[3]; + bool success; + int i; + + wt[0] = wt[1] = wt[2] = 0; + + for (i = 0; i < N; i++) + { + ++wt[t[i]]; + } + success = (wt[0] >= min_wt) && (wt[1] >= min_wt) && (wt[2] >= min_wt); + + DBG2(DBG_LIB, "minimum weight = %u, so -1: %u, 0: %u, +1: %u is %sok", + min_wt, wt[2], wt[0], wt[1], success ? "" : "not "); + + return success; +} + +METHOD(ntru_private_key_t, decrypt, bool, + private_ntru_private_key_t *this, chunk_t ciphertext, chunk_t *plaintext) +{ + hash_algorithm_t hash_algid; + size_t t_len, seed1_len, seed2_len; + uint16_t *t1, *t2, *t = NULL; + uint16_t mod_q_mask, q_mod_p, cmprime_len, cm_len = 0, num_zeros; + uint8_t *Mtrin, *M, *cm, *mask_trits, *ptr; + int16_t m1 = 0; + chunk_t seed = chunk_empty; + ntru_trits_t *mask; + ntru_poly_t *r_poly; + bool msg_rep_good, success = TRUE; + int i; + + *plaintext = chunk_empty; + + if (ciphertext.len != (this->params->N * this->params->q_bits + 7) / 8) + { + DBG1(DBG_LIB, "wrong NTRU ciphertext length"); + return FALSE; + } + + /* allocate temporary array t */ + t_len = 2 * this->params->N * sizeof(uint16_t); + t = malloc(t_len); + t1 = t; + t2 = t + this->params->N; + Mtrin = (uint8_t *)t1; + M = Mtrin + this->params->N; + + /* set hash algorithm based on security strength */ + hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 : + HASH_SHA256; + + /* set constants */ + mod_q_mask = this->params->q - 1; + q_mod_p = this->params->q % 3; + + /* unpack the ciphertext */ + ntru_octets_2_elements(ciphertext.len, ciphertext.ptr, + this->params->q_bits, t2); + + /* form cm': + * F * e + * A = e * (1 + pF) mod q = e + pFe mod q + * a = A in the range [-q/2, q/2) + * cm' = a mod p + */ + this->privkey->ring_mult(this->privkey, t2, t1); + + cmprime_len = this->params->N; + if (this->params->is_product_form) + { + --cmprime_len; + for (i = 0; i < cmprime_len; i++) + { + t1[i] = (t2[i] + 3 * t1[i]) & mod_q_mask; + if (t1[i] >= (this->params->q / 2)) + { + t1[i] -= q_mod_p; + } + Mtrin[i] = (uint8_t)(t1[i] % 3); + if (Mtrin[i] == 1) + { + ++m1; + } + else if (Mtrin[i] == 2) + { + --m1; + } + } + } + else + { + for (i = 0; i < cmprime_len; i++) + { + t1[i] = (t2[i] + 3 * t1[i]) & mod_q_mask; + if (t1[i] >= (this->params->q / 2)) + { + t1[i] -= q_mod_p; + } + Mtrin[i] = (uint8_t)(t1[i] % 3); + } + } + + /** + * check that the candidate message representative meets + * minimum weight requirements + */ + if (this->params->is_product_form) + { + msg_rep_good = (abs(m1) <= this->params->min_msg_rep_wt); + } + else + { + msg_rep_good = ntru_check_min_weight(cmprime_len, Mtrin, + this->params->min_msg_rep_wt); + } + if (!msg_rep_good) + { + DBG1(DBG_LIB, "decryption failed due to unsufficient minimum weight"); + success = FALSE; + } + + /* form cR = e - cm' mod q */ + for (i = 0; i < cmprime_len; i++) + { + if (Mtrin[i] == 1) + { + t2[i] = (t2[i] - 1) & mod_q_mask; + } + else if (Mtrin[i] == 2) + { + t2[i] = (t2[i] + 1) & mod_q_mask; + } + } + if (this->params->is_product_form) + { + t2[i] = (t2[i] + m1) & mod_q_mask; + } + + /* allocate memory for the larger of the two seeds */ + seed1_len = (this->params->N + 3)/4; + seed2_len = 3 + 2*this->params->sec_strength_len + this->params->m_len_max; + seed = chunk_alloc(max(seed1_len, seed2_len)); + seed.len = seed1_len; + + /* form cR mod 4 */ + ntru_coeffs_mod4_2_octets(this->params->N, t2, seed.ptr); + + /* form mask */ + mask = ntru_trits_create(this->params->N, hash_algid, seed); + if (!mask) + { + DBG1(DBG_LIB, "mask creation failed"); + success = FALSE; + goto err; + } + + mask_trits = mask->get_trits(mask); + + /* form cMtrin by subtracting mask from cm', mod p */ + for (i = 0; i < cmprime_len; i++) + { + Mtrin[i] -= mask_trits[i]; + if (Mtrin[i] >= 3) + { + Mtrin[i] += 3; + } + } + mask->destroy(mask); + + if (this->params->is_product_form) + { + /* set the last trit to zero since that's what it was, and + * because it can't be calculated from (cm' - mask) since + * we don't have the correct value for the last cm' trit + */ + Mtrin[i] = 0; + } + + /* convert cMtrin to cM (Mtrin to Mbin) */ + if (!ntru_trits_2_bits(Mtrin, this->params->N, M)) + { + success = FALSE; + goto err; + } + + /* skip the random padding */ + ptr = M + this->params->sec_strength_len; + + /* validate the padded message cM and copy cm to m_buf */ + if (this->params->m_len_len == 2) + { + cm_len = (uint16_t)(*ptr++) << 16; + } + cm_len |= (uint16_t)(*ptr++); + + if (cm_len > this->params->m_len_max) + { + cm_len = this->params->m_len_max; + DBG1(DBG_LIB, "NTRU message length is larger than maximum length"); + success = FALSE; + } + cm = ptr; + ptr += cm_len; + + /* check if the remaining padding consists of zeros */ + num_zeros = this->params->m_len_max - cm_len + 1; + for (i = 0; i < num_zeros; i++) + { + if (ptr[i] != 0) + { + DBG1(DBG_LIB, "non-zero trailing padding detected"); + success = FALSE; + break; + } + } + + /* form sData (OID || m || b || hTrunc) */ + ptr = seed.ptr; + memcpy(ptr, this->params->oid, 3); + ptr += 3; + memcpy(ptr, cm, cm_len); + ptr += cm_len; + memcpy(ptr, M, this->params->sec_strength_len); + ptr += this->params->sec_strength_len; + memcpy(ptr, this->encoding.ptr + 2 + NTRU_OID_LEN, + this->params->sec_strength_len); + ptr += this->params->sec_strength_len; + seed.len = ptr - seed.ptr; + + /* generate cr */ + DBG2(DBG_LIB, "generate polynomial r"); + r_poly = ntru_poly_create_from_seed(hash_algid, seed, + this->params->c_bits, this->params->N, + this->params->q, this->params->dF_r, + this->params->dF_r, this->params->is_product_form); + if (!r_poly) + { + success = FALSE; + goto err; + } + + /* output plaintext in allocated chunk */ + *plaintext = chunk_clone(chunk_create(cm, cm_len)); + + /* form cR' = h * cr */ + r_poly->ring_mult(r_poly, this->pubkey, t1); + r_poly->destroy(r_poly); + + /* compare cR' to cR */ + for (i = 0; i < this->params->N; i++) + { + if (t[i] != t2[i]) + { + DBG1(DBG_LIB, "cR' does not equal cR'"); + chunk_clear(plaintext); + success = FALSE; + break; + } + } + memwipe(t, t_len); + +err: + /* cleanup */ + chunk_clear(&seed); + free(t); + + return success; +} + +METHOD(ntru_private_key_t, destroy, void, + private_ntru_private_key_t *this) +{ + DESTROY_IF(this->privkey); + this->drbg->destroy(this->drbg); + chunk_clear(&this->encoding); + free(this->pubkey); + free(this); +} + +/** + * Multiplies ring element (polynomial) "a" by ring element (polynomial) "b" + * to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1). + * This is a convolution operation. + * + * Ring element "b" has coefficients in the range [0,N). + * + * This assumes q is 2^r where 8 < r < 16, so that overflow of the sum + * beyond 16 bits does not matter. + * + * @param a polynomial a + * @param b polynomial b + * @param N no. of coefficients in a, b, c + * @param q large modulus + * @param c polynomial c = a * b + */ +static void ring_mult_c(uint16_t *a, uint16_t *b, uint16_t N, uint16_t q, + uint16_t *c) +{ + uint16_t *bptr = b; + uint16_t mod_q_mask = q - 1; + int i, k; + + /* c[k] = sum(a[i] * b[k-i]) mod q */ + memset(c, 0, N * sizeof(uint16_t)); + for (k = 0; k < N; k++) + { + i = 0; + while (i <= k) + { + c[k] += a[i++] * *bptr--; + } + bptr += N; + while (i < N) + { + c[k] += a[i++] * *bptr--; + } + c[k] &= mod_q_mask; + ++bptr; + } +} + +/** + * Finds the inverse of a polynomial a in (Z/2^rZ)[X]/(X^N - 1). + * + * This assumes q is 2^r where 8 < r < 16, so that operations mod q can + * wait until the end, and only 16-bit arrays need to be used. + * + * @param a polynomial a + * @param N no. of coefficients in a + * @param q large modulus + * @param t temporary buffer of size 2N elements + * @param a_inv polynomial for inverse of a + */ +static bool ring_inv(uint16_t *a, uint16_t N, uint16_t q, uint16_t *t, + uint16_t *a_inv) +{ + uint8_t *b = (uint8_t *)t; + uint8_t *c = b + N; + uint8_t *f = c + N; + uint8_t *g = (uint8_t *)a_inv; + uint16_t *t2 = t + N; + uint16_t deg_b, deg_c, deg_f, deg_g; + bool done = FALSE; + int i, j, k = 0; + + /* form a^-1 in (Z/2Z)[X]/X^N - 1) */ + memset(b, 0, 2 * N); /* clear to init b, c */ + + /* b(X) = 1 */ + b[0] = 1; + deg_b = 0; + + /* c(X) = 0 (cleared above) */ + deg_c = 0; + + /* f(X) = a(X) mod 2 */ + for (i = 0; i < N; i++) + { + f[i] = (uint8_t)(a[i] & 1); + } + deg_f = N - 1; + + /* g(X) = X^N - 1 */ + g[0] = 1; + memset(g + 1, 0, N - 1); + g[N] = 1; + deg_g = N; + + /* until f(X) = 1 */ + while (!done) + { + /* while f[0] = 0, f(X) /= X, c(X) *= X, k++ */ + for (i = 0; (i <= deg_f) && (f[i] == 0); ++i); + + if (i > deg_f) + { + return FALSE; + } + if (i) + { + f = f + i; + deg_f = deg_f - i; + deg_c = deg_c + i; + for (j = deg_c; j >= i; j--) + { + c[j] = c[j-i]; + } + for (j = 0; j < i; j++) + { + c[j] = 0; + } + k = k + i; + } + + /* adjust degree of f(X) if the highest coefficients are zero + * Note: f[0] = 1 from above so the loop will terminate. + */ + while (f[deg_f] == 0) + { + --deg_f; + } + + /* if f(X) = 1, done + * Note: f[0] = 1 from above, so only check the x term and up + */ + for (i = 1; (i <= deg_f) && (f[i] == 0); ++i); + + if (i > deg_f) + { + done = TRUE; + break; + } + + /* if deg_f < deg_g, f <-> g, b <-> c */ + if (deg_f < deg_g) + { + uint8_t *x; + + x = f; + f = g; + g = x; + deg_f ^= deg_g; + deg_g ^= deg_f; + deg_f ^= deg_g; + x = b; + b = c; + c = x; + deg_b ^= deg_c; + deg_c ^= deg_b; + deg_b ^= deg_c; + } + + /* f(X) += g(X), b(X) += c(X) */ + for (i = 0; i <= deg_g; i++) + { + f[i] ^= g[i]; + } + if (deg_c > deg_b) + { + deg_b = deg_c; + } + for (i = 0; i <= deg_c; i++) + { + b[i] ^= c[i]; + } + } + + /* a^-1 in (Z/2Z)[X]/(X^N - 1) = b(X) shifted left k coefficients */ + j = 0; + if (k >= N) + { + k = k - N; + } + for (i = k; i < N; i++) + { + a_inv[j++] = (uint16_t)(b[i]); + } + for (i = 0; i < k; i++) + { + a_inv[j++] = (uint16_t)(b[i]); + } + + /* lift a^-1 in (Z/2Z)[X]/(X^N - 1) to a^-1 in (Z/qZ)[X]/(X^N -1) */ + for (j = 0; j < 4; ++j) /* assumes 256 < q <= 65536 */ + { + /* a^-1 = a^-1 * (2 - a * a^-1) mod q */ + memcpy(t2, a_inv, N * sizeof(uint16_t)); + ring_mult_c(a, t2, N, q, t); + for (i = 0; i < N; ++i) + { + t[i] = q - t[i]; + } + t[0] = t[0] + 2; + ring_mult_c(t2, t, N, q, a_inv); + } + + return TRUE; +} + +/* + * Described in header. + */ +ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, + ntru_param_set_t *params) +{ + private_ntru_private_key_t *this; + size_t t_len; + uint16_t *t1, *t2, *t = NULL; + uint16_t mod_q_mask; + hash_algorithm_t hash_algid; + ntru_poly_t *g_poly; + chunk_t seed; + int i; + + INIT(this, + .public = { + .get_id = _get_id, + .get_public_key = _get_public_key, + .get_encoding = _get_encoding, + .decrypt = _decrypt, + .destroy = _destroy, + }, + .params = params, + .pubkey = malloc(params->N * sizeof(uint16_t)), + .drbg = drbg->get_ref(drbg), + ); + + /* set hash algorithm and seed length based on security strength */ + if (params->sec_strength_len <= 20) + { + hash_algid = HASH_SHA1; + } + else + { + hash_algid = HASH_SHA256; + } + seed =chunk_alloc(params->sec_strength_len + 8); + + /* get random seed for generating trinary F as a list of indices */ + if (!drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE, + seed.len, seed.ptr)) + { + goto err; + } + + DBG2(DBG_LIB, "generate polynomial F"); + this->privkey = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, + params->N, params->q, + params->dF_r, params->dF_r, + params->is_product_form); + if (!this->privkey) + { + goto err; + } + + /* allocate temporary array t */ + t_len = 3 * params->N * sizeof(uint16_t); + t = malloc(t_len); + t1 = t + 2 * params->N; + + /* extend sparse private key polynomial f to N array elements */ + this->privkey->get_array(this->privkey, t1); + + /* set mask for large modulus */ + mod_q_mask = params->q - 1; + + /* form f = 1 + pF */ + for (i = 0; i < params->N; i++) + { + t1[i] = (t1[i] * 3) & mod_q_mask; + } + t1[0] = (t1[0] + 1) & mod_q_mask; + + /* use the public key array as a temporary buffer */ + t2 = this->pubkey; + + /* find f^-1 in (Z/qZ)[X]/(X^N - 1) */ + if (!ring_inv(t1, params->N, params->q, t, t2)) + { + goto err; + } + + /* get random seed for generating trinary g as a list of indices */ + if (!drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE, + seed.len, seed.ptr)) + { + goto err; + } + + DBG2(DBG_LIB, "generate polynomial g"); + g_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, + params->N, params->q, params->dg + 1, + params->dg, FALSE); + if (!g_poly) + { + goto err; + } + + /* compute public key polynomial h = p * (f^-1 * g) mod q */ + g_poly->ring_mult(g_poly, t2, t2); + g_poly->destroy(g_poly); + + for (i = 0; i < params->N; i++) + { + this->pubkey[i] = (t2[i] * 3) & mod_q_mask; + } + + /* cleanup temporary storage */ + chunk_clear(&seed); + memwipe(t, t_len); + free(t); + + /* generate private key encoding */ + generate_encoding(this); + + return &this->public; + +err: + chunk_free(&seed); + free(t); + destroy(this); + + return NULL; +} + +/* + * Described in header. + */ +ntru_private_key_t *ntru_private_key_create_from_data(ntru_drbg_t *drbg, + chunk_t data) +{ + private_ntru_private_key_t *this; + size_t header_len, pubkey_packed_len, privkey_packed_len; + size_t privkey_packed_trits_len, privkey_packed_indices_len; + uint8_t *privkey_packed, tag; + uint16_t *indices, dF; + ntru_param_set_t *params; + + header_len = 2 + NTRU_OID_LEN; + + /* check the NTRU public key header format */ + if (data.len < header_len || + !(data.ptr[0] == NTRU_PRIVKEY_DEFAULT_TAG || + data.ptr[0] == NTRU_PRIVKEY_TRITS_TAG || + data.ptr[0] == NTRU_PRIVKEY_INDICES_TAG) || + data.ptr[1] != NTRU_OID_LEN) + { + DBG1(DBG_LIB, "loaded NTRU private key with invalid header"); + return NULL; + } + tag = data.ptr[0]; + params = ntru_param_set_get_by_oid(data.ptr + 2); + + if (!params) + { + DBG1(DBG_LIB, "loaded NTRU private key with unknown OID"); + return NULL; + } + + pubkey_packed_len = (params->N * params->q_bits + 7) / 8; + privkey_packed_trits_len = (params->N + 4) / 5; + + /* check packing type for product-form private keys */ + if (params->is_product_form && tag == NTRU_PRIVKEY_TRITS_TAG) + { + DBG1(DBG_LIB, "a product-form NTRU private key cannot be trits-encoded"); + return NULL; + } + + /* set packed-key length for packed indices */ + if (params->is_product_form) + { + dF = (uint16_t)((params->dF_r & 0xff) + /* df1 */ + ((params->dF_r >> 8) & 0xff) + /* df2 */ + ((params->dF_r >> 16) & 0xff)); /* df3 */ + } + else + { + dF = (uint16_t)params->dF_r; + } + privkey_packed_indices_len = (2 * dF * params->N_bits + 7) / 8; + + /* set private-key packing type if defaulted */ + if (tag == NTRU_PRIVKEY_DEFAULT_TAG) + { + if (params->is_product_form || + privkey_packed_indices_len <= privkey_packed_trits_len) + { + tag = NTRU_PRIVKEY_INDICES_TAG; + } + else + { + tag = NTRU_PRIVKEY_TRITS_TAG; + } + } + privkey_packed_len = (tag == NTRU_PRIVKEY_TRITS_TAG) ? + privkey_packed_trits_len : privkey_packed_indices_len; + + if (data.len < header_len + pubkey_packed_len + privkey_packed_len) + { + DBG1(DBG_LIB, "loaded NTRU private key with wrong packed key size"); + return NULL; + } + + INIT(this, + .public = { + .get_id = _get_id, + .get_public_key = _get_public_key, + .get_encoding = _get_encoding, + .decrypt = _decrypt, + .destroy = _destroy, + }, + .params = params, + .pubkey = malloc(params->N * sizeof(uint16_t)), + .encoding = chunk_clone(data), + .drbg = drbg->get_ref(drbg), + ); + + /* unpack the encoded public key */ + ntru_octets_2_elements(pubkey_packed_len, data.ptr + header_len, + params->q_bits, this->pubkey); + + /* allocate temporary memory for indices */ + indices = malloc(2 * dF * sizeof(uint16_t)); + + /* unpack the private key */ + privkey_packed = data.ptr + header_len + pubkey_packed_len; + if (tag == NTRU_PRIVKEY_TRITS_TAG) + { + ntru_packed_trits_2_indices(privkey_packed, params->N, + indices, indices + dF); + } + else + { + ntru_octets_2_elements(privkey_packed_indices_len, privkey_packed, + params->N_bits, indices); + } + this->privkey = ntru_poly_create_from_data(indices, params->N, params->q, + params->dF_r, params->dF_r, + params->is_product_form); + + /* cleanup */ + memwipe(indices, 2 * dF * sizeof(uint16_t)); + free(indices); + + return &this->public; +} + +EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create); + +EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create_from_data); diff --git a/src/libstrongswan/plugins/ntru/ntru_private_key.h b/src/libstrongswan/plugins/ntru/ntru_private_key.h new file mode 100644 index 000000000..c6f08440f --- /dev/null +++ b/src/libstrongswan/plugins/ntru/ntru_private_key.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup ntru_private_key ntru_private_key + * @{ @ingroup ntru_p + */ + +#ifndef NTRU_PRIVATE_KEY_H_ +#define NTRU_PRIVATE_KEY_H_ + +typedef struct ntru_private_key_t ntru_private_key_t; + +#include "ntru_drbg.h" +#include "ntru_param_set.h" +#include "ntru_public_key.h" + +#include <library.h> + +/** + * Implements an NTRU encryption public/private key pair + */ +struct ntru_private_key_t { + + /** + * Returns NTRU parameter set ID of the private key + * + * @return NTRU parameter set ID + */ + ntru_param_set_id_t (*get_id)(ntru_private_key_t *this); + + /** + * Returns the NTRU encryption public key as an encoded binary blob + * + * @return NTRU encryption public key (must be freed after use) + */ + ntru_public_key_t* (*get_public_key)(ntru_private_key_t *this); + + /** + * Returns the packed encoding of the NTRU encryption private key + * + * @return Packed encoding of NTRU encryption private key + */ + chunk_t (*get_encoding)(ntru_private_key_t *this); + + /** + * Decrypts an NTRU ciphertext + * + * @param ciphertext NTRU Ciphertext + * @param plaintext Plaintext + * @return TRUE if decryption was successful + */ + bool (*decrypt)(ntru_private_key_t *this, chunk_t ciphertext, + chunk_t *plaintext); + + /** + * Destroy ntru_private_key_t object + */ + void (*destroy)(ntru_private_key_t *this); +}; + +/** + * Creates an NTRU encryption public/private key pair using a NIST DRBG + * + * @param drbg Digital Random Bit Generator used for key generation + * @param params NTRU encryption parameter set to be used + */ +ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t *params); + +/** + * Creates an NTRU encryption private key from encoding + * + * @param drbg Deterministic random bit generator + * @param data Encoded NTRU private key + */ +ntru_private_key_t *ntru_private_key_create_from_data(ntru_drbg_t *drbg, + chunk_t data); + +#endif /** NTRU_PRIVATE_KEY_H_ @}*/ + diff --git a/src/libstrongswan/plugins/ntru/ntru_public_key.c b/src/libstrongswan/plugins/ntru/ntru_public_key.c new file mode 100644 index 000000000..a2ff1b2b0 --- /dev/null +++ b/src/libstrongswan/plugins/ntru/ntru_public_key.c @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Copyright (C) 2009-2013 Security Innovation + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include "ntru_public_key.h" +#include "ntru_trits.h" +#include "ntru_poly.h" +#include "ntru_convert.h" + +#include <utils/debug.h> +#include <utils/test.h> + +typedef struct private_ntru_public_key_t private_ntru_public_key_t; + +/** + * Private data of an ntru_public_key_t object. + */ +struct private_ntru_public_key_t { + /** + * Public ntru_public_key_t interface. + */ + ntru_public_key_t public; + + /** + * NTRU Parameter Set + */ + ntru_param_set_t *params; + + /** + * Polynomial h which is the public key + */ + uint16_t *pubkey; + + /** + * Encoding of the public key + */ + chunk_t encoding; + + /** + * Deterministic Random Bit Generator + */ + ntru_drbg_t *drbg; + +}; + +METHOD(ntru_public_key_t, get_id, ntru_param_set_id_t, + private_ntru_public_key_t *this) +{ + return this->params->id; +} + +/** + * Generate NTRU encryption public key encoding + */ +static void generate_encoding(private_ntru_public_key_t *this) +{ + size_t pubkey_len; + u_char *enc; + + /* compute public key length encoded as packed coefficients */ + pubkey_len = (this->params->N * this->params->q_bits + 7) / 8; + + /* allocate memory for public key encoding */ + this->encoding = chunk_alloc(2 + NTRU_OID_LEN + pubkey_len); + enc = this->encoding.ptr; + + /* format header and packed public key */ + *enc++ = NTRU_PUBKEY_TAG; + *enc++ = NTRU_OID_LEN; + memcpy(enc, this->params->oid, NTRU_OID_LEN); + enc += NTRU_OID_LEN; + ntru_elements_2_octets(this->params->N, this->pubkey, + this->params->q_bits, enc); +} + +METHOD(ntru_public_key_t, get_encoding, chunk_t, + private_ntru_public_key_t *this) +{ + return this->encoding; +} + +#define MAX_SEC_STRENGTH_LEN 32 /* bytes */ + +/** + * Shared with ntru_private_key.c + */ +extern bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt); + +METHOD(ntru_public_key_t, encrypt, bool, + private_ntru_public_key_t *this, chunk_t plaintext, chunk_t *ciphertext) +{ + hash_algorithm_t hash_algid; + size_t t_len, seed1_len, seed2_len; + uint16_t *t1, *t = NULL; + uint8_t b[MAX_SEC_STRENGTH_LEN]; + uint8_t *t2, *Mtrin, *M, *mask_trits, *ptr; + uint16_t mod_q_mask, mprime_len = 0; + int16_t m1 = 0; + chunk_t seed = chunk_empty; + ntru_trits_t *mask; + ntru_poly_t *r_poly; + bool msg_rep_good, success = FALSE; + int i; + + *ciphertext = chunk_empty; + + if (plaintext.len > this->params->m_len_max) + { + DBG1(DBG_LIB, "plaintext exceeds maximum size"); + return FALSE; + } + + if (this->params->sec_strength_len > MAX_SEC_STRENGTH_LEN) + { + DBG1(DBG_LIB, "required security strength exceeds %d bits", + MAX_SEC_STRENGTH_LEN * BITS_PER_BYTE); + return FALSE; + } + + /* allocate temporary array t */ + t_len = (sizeof(uint16_t) + 3*sizeof(uint8_t)) * this->params->N; + t = malloc(t_len); + t1 = t; + t2 = (uint8_t *)(t1 + this->params->N); + Mtrin = t2 + this->params->N; + M = Mtrin + this->params->N; + + /* set hash algorithm based on security strength */ + hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 : + HASH_SHA256; + /* set constants */ + mod_q_mask = this->params->q - 1; + + /* allocate memory for the larger of the two seeds */ + seed1_len = (this->params->N + 3)/4; + seed2_len = 3 + 2*this->params->sec_strength_len + plaintext.len; + seed = chunk_alloc(max(seed1_len, seed2_len)); + + /* loop until a message representative with proper weight is achieved */ + do + { + if (!this->drbg->generate(this->drbg, + this->params->sec_strength_len * BITS_PER_BYTE, + this->params->sec_strength_len, b)) + { + goto err; + } + + /* form sData (OID || m || b || hTrunc) */ + ptr = seed.ptr; + memcpy(ptr, this->params->oid, NTRU_OID_LEN); + ptr += NTRU_OID_LEN; + memcpy(ptr, plaintext.ptr, plaintext.len); + ptr += plaintext.len; + memcpy(ptr, b, this->params->sec_strength_len); + ptr += this->params->sec_strength_len; + memcpy(ptr, this->encoding.ptr + 2 + NTRU_OID_LEN, + this->params->sec_strength_len); + ptr += this->params->sec_strength_len; + seed.len = seed2_len; + + DBG2(DBG_LIB, "generate polynomial r"); + r_poly = ntru_poly_create_from_seed(hash_algid, seed, this->params->c_bits, + this->params->N, this->params->q, + this->params->dF_r, this->params->dF_r, + this->params->is_product_form); + if (!r_poly) + { + goto err; + } + + /* form R = h * r */ + r_poly->ring_mult(r_poly, this->pubkey, t1); + r_poly->destroy(r_poly); + + /* form R mod 4 */ + ntru_coeffs_mod4_2_octets(this->params->N, t1, seed.ptr); + seed.len = seed1_len; + + /* form mask */ + mask = ntru_trits_create(this->params->N, hash_algid, seed); + if (!mask) + { + DBG1(DBG_LIB, "mask creation failed"); + goto err; + } + + /* form the padded message M */ + ptr = M; + memcpy(ptr, b, this->params->sec_strength_len); + ptr += this->params->sec_strength_len; + if (this->params->m_len_len == 2) + { + *ptr++ = (uint8_t)((plaintext.len >> 8) & 0xff); + } + *ptr++ = (uint8_t)(plaintext.len & 0xff); + memcpy(ptr, plaintext.ptr, plaintext.len); + ptr += plaintext.len; + + /* add an extra zero byte in case without it the bit string + * is not a multiple of 3 bits and therefore might not be + * able to produce enough trits + */ + memset(ptr, 0, this->params->m_len_max - plaintext.len + 2); + + /* convert M to trits (Mbin to Mtrin) */ + mprime_len = this->params->N; + if (this->params->is_product_form) + { + --mprime_len; + } + ntru_bits_2_trits(M, mprime_len, Mtrin); + mask_trits = mask->get_trits(mask); + + + /* form the msg representative m' by adding Mtrin to mask, mod p */ + if (this->params->is_product_form) + { + m1 = 0; + for (i = 0; i < mprime_len; i++) + { + t2[i] = mask_trits[i] + Mtrin[i]; + if (t2[i] >= 3) + { + t2[i] -= 3; + } + if (t2[i] == 1) + { + ++m1; + } + else if (t2[i] == 2) + { + --m1; + } + } + } + else + { + for (i = 0; i < mprime_len; i++) + { + t2[i] = mask_trits[i] + Mtrin[i]; + if (t2[i] >= 3) + { + t2[i] -= 3; + } + } + } + mask->destroy(mask); + + /* check that message representative meets minimum weight + * requirements + */ + if (this->params->is_product_form) + { + msg_rep_good = (abs(m1) <= this->params->min_msg_rep_wt); + } + else + { + msg_rep_good = ntru_check_min_weight(mprime_len, t2, + this->params->min_msg_rep_wt); + } + } + while (!msg_rep_good); + + /* form ciphertext e by adding m' to R mod q */ + for (i = 0; i < mprime_len; i++) + { + if (t2[i] == 1) + { + t1[i] = (t1[i] + 1) & mod_q_mask; + } + else if (t2[i] == 2) + { + t1[i] = (t1[i] - 1) & mod_q_mask; + } + } + if (this->params->is_product_form) + { + t1[i] = (t1[i] - m1) & mod_q_mask; + } + + /* pack ciphertext */ + *ciphertext = chunk_alloc((this->params->N * this->params->q_bits + 7) / 8); + ntru_elements_2_octets(this->params->N, t1, this->params->q_bits, + ciphertext->ptr); + + memwipe(t, t_len); + success = TRUE; + +err: + /* cleanup */ + chunk_clear(&seed); + free(t); + + return success; +} +METHOD(ntru_public_key_t, destroy, void, + private_ntru_public_key_t *this) +{ + this->drbg->destroy(this->drbg); + chunk_clear(&this->encoding); + free(this->pubkey); + free(this); +} + +/* + * Described in header. + */ +ntru_public_key_t *ntru_public_key_create(ntru_drbg_t *drbg, + ntru_param_set_t *params, + uint16_t *pubkey) +{ + private_ntru_public_key_t *this; + int i; + + INIT(this, + .public = { + .get_id = _get_id, + .get_encoding = _get_encoding, + .encrypt = _encrypt, + .destroy = _destroy, + }, + .params = params, + .pubkey = malloc(params->N * sizeof(uint16_t)), + .drbg = drbg->get_ref(drbg), + ); + + for (i = 0; i < params->N; i++) + { + this->pubkey[i] = pubkey[i]; + } + + /* generate public key encoding */ + generate_encoding(this); + + return &this->public; +} + +/* + * Described in header. + */ +ntru_public_key_t *ntru_public_key_create_from_data(ntru_drbg_t *drbg, + chunk_t data) +{ + private_ntru_public_key_t *this; + size_t header_len, pubkey_packed_len; + ntru_param_set_t *params; + + header_len = 2 + NTRU_OID_LEN; + + /* check the NTRU public key header format */ + if (data.len < header_len || + data.ptr[0] != NTRU_PUBKEY_TAG || + data.ptr[1] != NTRU_OID_LEN) + { + DBG1(DBG_LIB, "received NTRU public key with invalid header"); + return NULL; + } + params = ntru_param_set_get_by_oid(data.ptr + 2); + + if (!params) + { + DBG1(DBG_LIB, "received NTRU public key with unknown OID"); + return NULL; + } + + pubkey_packed_len = (params->N * params->q_bits + 7) / 8; + + if (data.len < header_len + pubkey_packed_len) + { + DBG1(DBG_LIB, "received NTRU public key with wrong packed key size"); + return NULL; + } + + INIT(this, + .public = { + .get_id = _get_id, + .get_encoding = _get_encoding, + .encrypt = _encrypt, + .destroy = _destroy, + }, + .params = params, + .pubkey = malloc(params->N * sizeof(uint16_t)), + .encoding = chunk_clone(data), + .drbg = drbg->get_ref(drbg), + ); + + /* unpack the encoded public key */ + ntru_octets_2_elements(pubkey_packed_len, data.ptr + header_len, + params->q_bits, this->pubkey); + + return &this->public; +} + +EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_public_key_create_from_data); diff --git a/src/libstrongswan/plugins/ntru/ntru_public_key.h b/src/libstrongswan/plugins/ntru/ntru_public_key.h new file mode 100644 index 000000000..baa8eabcd --- /dev/null +++ b/src/libstrongswan/plugins/ntru/ntru_public_key.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * 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 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup ntru_public_key ntru_public_key + * @{ @ingroup ntru_p + */ + +#ifndef NTRU_PUBLIC_KEY_H_ +#define NTRU_PUBLIC_KEY_H_ + +typedef struct ntru_public_key_t ntru_public_key_t; + +#include "ntru_param_set.h" +#include "ntru_drbg.h" + +#include <library.h> + +/** + * Implements an NTRU encryption public key + */ +struct ntru_public_key_t { + + /** + * Returns NTRU parameter set ID of the public key + * + * @return NTRU parameter set ID + */ + ntru_param_set_id_t (*get_id)(ntru_public_key_t *this); + + /** + * Returns the packed encoding of the NTRU encryption public key + * + * @return Packed encoding of NTRU encryption public key + */ + chunk_t (*get_encoding)(ntru_public_key_t *this); + + /** + * Encrypts a plaintext with the NTRU public key + * + * @param ciphertext Plaintext + * @param plaintext Ciphertext + * @return TRUE if encryption was successful + */ + bool (*encrypt)(ntru_public_key_t *this, chunk_t plaintext, + chunk_t *ciphertext); + + /** + * Destroy ntru_public_key_t object + */ + void (*destroy)(ntru_public_key_t *this); +}; + +/** + * Creates an NTRU encryption public key from coefficients + * + * @param drbg Deterministic random bit generator + * @param params NTRU encryption parameter set to be used + * @param pubkey Coefficients of public key polynomial h + */ +ntru_public_key_t *ntru_public_key_create(ntru_drbg_t *drbg, + ntru_param_set_t *params, + uint16_t *pubkey); + +/** + * Creates an NTRU encryption public key from encoding + * + * @param drbg Deterministic random bit generator + * @param data Encoded NTRU public key + */ +ntru_public_key_t *ntru_public_key_create_from_data(ntru_drbg_t *drbg, + chunk_t data); + + +#endif /** NTRU_PUBLIC_KEY_H_ @}*/ + diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.c b/src/libstrongswan/plugins/ntru/ntru_trits.c index f82501629..1abb7671c 100644 --- a/src/libstrongswan/plugins/ntru/ntru_trits.c +++ b/src/libstrongswan/plugins/ntru/ntru_trits.c @@ -15,8 +15,7 @@ #include "ntru_trits.h" #include "ntru_mgf1.h" - -#include "ntru_crypto/ntru_crypto_ntru_convert.h" +#include "ntru_convert.h" #include <utils/debug.h> #include <utils/test.h> diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in index f0735294b..5d8ada2fa 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.in +++ b/src/libstrongswan/plugins/openssl/Makefile.in @@ -379,7 +379,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/openssl/openssl_gcm.c b/src/libstrongswan/plugins/openssl/openssl_gcm.c index 842111bd3..147e4afb4 100644 --- a/src/libstrongswan/plugins/openssl/openssl_gcm.c +++ b/src/libstrongswan/plugins/openssl/openssl_gcm.c @@ -202,7 +202,8 @@ METHOD(aead_t, destroy, void, /* * Described in header */ -aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size) +aead_t *openssl_gcm_create(encryption_algorithm_t algo, + size_t key_size, size_t salt_size) { private_aead_t *this; @@ -236,6 +237,13 @@ aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size) return NULL; } + if (salt_size && salt_size != SALT_LEN) + { + /* currently not supported */ + free(this); + return NULL; + } + switch (algo) { case ENCR_AES_GCM_ICV8: diff --git a/src/libstrongswan/plugins/openssl/openssl_gcm.h b/src/libstrongswan/plugins/openssl/openssl_gcm.h index 12d2e8ab6..4ae268bd6 100644 --- a/src/libstrongswan/plugins/openssl/openssl_gcm.h +++ b/src/libstrongswan/plugins/openssl/openssl_gcm.h @@ -30,8 +30,10 @@ * * @param algo algorithm to implement * @param key_size key size in bytes + * @param salt_size size of implicit salt length * @return aead_t object, NULL if not supported */ -aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size); +aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size, + size_t salt_size); #endif /** OPENSSL_GCM_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index f0c172629..9748e28f2 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -222,7 +222,21 @@ bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp) i2d_RSA_PUBKEY(rsa, &p); break; default: - return FALSE; + { + chunk_t n = chunk_empty, e = chunk_empty; + bool success = FALSE; + + if (openssl_bn2chunk(rsa->n, &n) && + openssl_bn2chunk(rsa->e, &e)) + { + success = lib->encoding->encode(lib->encoding, type, rsa, fp, + CRED_PART_RSA_MODULUS, n, + CRED_PART_RSA_PUB_EXP, e, CRED_PART_END); + } + chunk_free(&n); + chunk_free(&e); + return success; + } } hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); if (!hasher || !hasher->allocate_hash(hasher, key, fp)) diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in index 55c0271ce..0450ab053 100644 --- a/src/libstrongswan/plugins/padlock/Makefile.in +++ b/src/libstrongswan/plugins/padlock/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in index 22c33b0c8..300615eb7 100644 --- a/src/libstrongswan/plugins/pem/Makefile.in +++ b/src/libstrongswan/plugins/pem/Makefile.in @@ -371,7 +371,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c index 9c8237e4d..df4b77cc3 100644 --- a/src/libstrongswan/plugins/pem/pem_encoder.c +++ b/src/libstrongswan/plugins/pem/pem_encoder.c @@ -106,6 +106,12 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, label = "CERTIFICATE REQUEST"; break; } + if (cred_encoding_args(args, CRED_PART_X509_AC_ASN1_DER, + &asn1, CRED_PART_END)) + { + label = "ATTRIBUTE CERTIFICATE"; + break; + } default: return FALSE; } @@ -154,4 +160,3 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, encoding->len = pos - encoding->ptr; return TRUE; } - diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in index e2491f5a4..ca8743bc0 100644 --- a/src/libstrongswan/plugins/pgp/Makefile.in +++ b/src/libstrongswan/plugins/pgp/Makefile.in @@ -371,7 +371,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in index d3f3fdf49..c563806ee 100644 --- a/src/libstrongswan/plugins/pkcs1/Makefile.in +++ b/src/libstrongswan/plugins/pkcs1/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c index b304a5101..eb0903d47 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c @@ -46,6 +46,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + PLUGIN_SDEPEND(PUBKEY, KEY_RSA), + PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA), + PLUGIN_SDEPEND(PUBKEY, KEY_DSA), PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_RSA), }; diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in index c8cec3771..5d2f39c9e 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.in +++ b/src/libstrongswan/plugins/pkcs11/Makefile.in @@ -375,7 +375,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/pkcs12/Makefile.in b/src/libstrongswan/plugins/pkcs12/Makefile.in index 67b1f4f57..f398652d5 100644 --- a/src/libstrongswan/plugins/pkcs12/Makefile.in +++ b/src/libstrongswan/plugins/pkcs12/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/pkcs7/Makefile.in b/src/libstrongswan/plugins/pkcs7/Makefile.in index feff6e5b0..7d1c65538 100644 --- a/src/libstrongswan/plugins/pkcs7/Makefile.in +++ b/src/libstrongswan/plugins/pkcs7/Makefile.in @@ -374,7 +374,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in index 35a5c9a35..fca8fd1f9 100644 --- a/src/libstrongswan/plugins/pkcs8/Makefile.in +++ b/src/libstrongswan/plugins/pkcs8/Makefile.in @@ -371,7 +371,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c index 8a1958be5..65cdbe9d9 100644 --- a/src/libstrongswan/plugins/plugin_feature.c +++ b/src/libstrongswan/plugins/plugin_feature.c @@ -73,25 +73,55 @@ u_int32_t plugin_feature_hash(plugin_feature_t *feature) data = chunk_empty; break; case FEATURE_CRYPTER: + data = chunk_from_thing(feature->arg.crypter); + break; case FEATURE_AEAD: + data = chunk_from_thing(feature->arg.aead); + break; case FEATURE_SIGNER: + data = chunk_from_thing(feature->arg.signer); + break; case FEATURE_HASHER: + data = chunk_from_thing(feature->arg.hasher); + break; case FEATURE_PRF: + data = chunk_from_thing(feature->arg.prf); + break; case FEATURE_DH: + data = chunk_from_thing(feature->arg.dh_group); + break; case FEATURE_PRIVKEY: + data = chunk_from_thing(feature->arg.privkey); + break; case FEATURE_PRIVKEY_GEN: + data = chunk_from_thing(feature->arg.privkey_gen); + break; case FEATURE_PUBKEY: + data = chunk_from_thing(feature->arg.pubkey); + break; case FEATURE_PRIVKEY_SIGN: + data = chunk_from_thing(feature->arg.privkey_sign); + break; case FEATURE_PUBKEY_VERIFY: + data = chunk_from_thing(feature->arg.pubkey_verify); + break; case FEATURE_PRIVKEY_DECRYPT: + data = chunk_from_thing(feature->arg.privkey_decrypt); + break; case FEATURE_PUBKEY_ENCRYPT: + data = chunk_from_thing(feature->arg.pubkey_encrypt); + break; case FEATURE_CERT_DECODE: case FEATURE_CERT_ENCODE: + data = chunk_from_thing(feature->arg.cert); + break; case FEATURE_CONTAINER_DECODE: case FEATURE_CONTAINER_ENCODE: + data = chunk_from_thing(feature->arg.container); + break; case FEATURE_EAP_SERVER: case FEATURE_EAP_PEER: - data = chunk_from_thing(feature->arg); + data = chunk_from_thing(feature->arg.eap); break; case FEATURE_CUSTOM: data = chunk_create(feature->arg.custom, diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index 08a8442ea..487fafa01 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -1047,6 +1047,7 @@ static char *modular_pluginlist(char *list) array_sort(final, (void*)plugin_priority_cmp, NULL); + plugins = strdup(""); enumerator = array_create_enumerator(final); while (enumerator->enumerate(enumerator, ¤t)) { diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in index 803eeab44..6f00e7eb1 100644 --- a/src/libstrongswan/plugins/pubkey/Makefile.in +++ b/src/libstrongswan/plugins/pubkey/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in index 0efe24cb7..59f062dd2 100644 --- a/src/libstrongswan/plugins/random/Makefile.in +++ b/src/libstrongswan/plugins/random/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/rc2/Makefile.in b/src/libstrongswan/plugins/rc2/Makefile.in index afcbc07eb..b820d1211 100644 --- a/src/libstrongswan/plugins/rc2/Makefile.in +++ b/src/libstrongswan/plugins/rc2/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/rdrand/Makefile.in b/src/libstrongswan/plugins/rdrand/Makefile.in index 88b283e87..db926c545 100644 --- a/src/libstrongswan/plugins/rdrand/Makefile.in +++ b/src/libstrongswan/plugins/rdrand/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in index 745ee83e7..cfdd7e8b6 100644 --- a/src/libstrongswan/plugins/revocation/Makefile.in +++ b/src/libstrongswan/plugins/revocation/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c index c8ec3f723..9fd5b2a22 100644 --- a/src/libstrongswan/plugins/revocation/revocation_validator.c +++ b/src/libstrongswan/plugins/revocation/revocation_validator.c @@ -93,40 +93,92 @@ static certificate_t *fetch_ocsp(char *url, certificate_t *subject, /** * check the signature of an OCSP response */ -static bool verify_ocsp(ocsp_response_t *response, auth_cfg_t *auth) +static bool verify_ocsp(ocsp_response_t *response, certificate_t *ca) { certificate_t *issuer, *subject; identification_t *responder; ocsp_response_wrapper_t *wrapper; enumerator_t *enumerator; - auth_cfg_t *current; - bool verified = FALSE; + x509_t *x509; + bool verified = FALSE, found = FALSE; wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response); lib->credmgr->add_local_set(lib->credmgr, &wrapper->set, FALSE); subject = &response->certificate; responder = subject->get_issuer(subject); - enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr, + + /* check OCSP response using CA or directly delegated OCSP signer */ + enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, CERT_X509, KEY_ANY, responder, FALSE); - while (enumerator->enumerate(enumerator, &issuer, ¤t)) + while (enumerator->enumerate(enumerator, &issuer)) { + x509 = (x509_t*)issuer; + if (!issuer->get_validity(issuer, NULL, NULL, NULL)) + { /* OCSP signer currently invalid */ + continue; + } + if (!ca->equals(ca, issuer)) + { /* delegated OCSP signer? */ + if (!lib->credmgr->issued_by(lib->credmgr, issuer, ca, NULL)) + { /* OCSP response not signed by CA, nor delegated OCSP signer */ + continue; + } + if (!(x509->get_flags(x509) & X509_OCSP_SIGNER)) + { /* delegated OCSP signer does not have OCSP signer flag */ + continue; + } + } + found = TRUE; if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL)) { DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"", - issuer->get_subject(issuer)); - if (auth) - { - auth->merge(auth, current, FALSE); - } + issuer->get_subject(issuer)); verified = TRUE; break; } + DBG1(DBG_CFG, "ocsp response verification failed, " + "invalid signature"); } enumerator->destroy(enumerator); + if (!verified) + { + /* as fallback, use any locally installed OCSP signer certificate */ + enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, + CERT_X509, KEY_ANY, responder, TRUE); + while (enumerator->enumerate(enumerator, &issuer)) + { + x509 = (x509_t*)issuer; + /* while issued_by() accepts both OCSP signer or CA basic + * constraint flags to verify OCSP responses, unrelated but trusted + * OCSP signers must explicitly have the OCSP signer flag set. */ + if ((x509->get_flags(x509) & X509_OCSP_SIGNER) && + issuer->get_validity(issuer, NULL, NULL, NULL)) + { + found = TRUE; + if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL)) + { + DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"", + issuer->get_subject(issuer)); + verified = TRUE; + break; + } + DBG1(DBG_CFG, "ocsp response verification failed, " + "invalid signature"); + } + } + enumerator->destroy(enumerator); + } + lib->credmgr->remove_local_set(lib->credmgr, &wrapper->set); wrapper->destroy(wrapper); + + if (!found) + { + DBG1(DBG_CFG, "ocsp response verification failed, " + "no signer certificate '%Y' found", responder); + } return verified; } @@ -134,8 +186,8 @@ static bool verify_ocsp(ocsp_response_t *response, auth_cfg_t *auth) * Get the better of two OCSP responses, and check for usable OCSP info */ static certificate_t *get_better_ocsp(certificate_t *cand, certificate_t *best, - x509_t *subject, x509_t *issuer, cert_validation_t *valid, - auth_cfg_t *auth, bool cache) + x509_t *subject, x509_t *issuer, + cert_validation_t *valid, bool cache) { ocsp_response_t *response; time_t revocation, this_update, next_update, valid_until; @@ -145,9 +197,8 @@ static certificate_t *get_better_ocsp(certificate_t *cand, certificate_t *best, response = (ocsp_response_t*)cand; /* check ocsp signature */ - if (!verify_ocsp(response, auth)) + if (!verify_ocsp(response, &issuer->interface)) { - DBG1(DBG_CFG, "ocsp response verification failed"); cand->destroy(cand); return best; } @@ -226,8 +277,7 @@ static cert_validation_t check_ocsp(x509_t *subject, x509_t *issuer, while (enumerator->enumerate(enumerator, ¤t)) { current->get_ref(current); - best = get_better_ocsp(current, best, subject, issuer, - &valid, auth, FALSE); + best = get_better_ocsp(current, best, subject, issuer, &valid, FALSE); if (best && valid != VALIDATION_STALE) { DBG1(DBG_CFG, " using cached ocsp response"); @@ -254,7 +304,7 @@ static cert_validation_t check_ocsp(x509_t *subject, x509_t *issuer, if (current) { best = get_better_ocsp(current, best, subject, issuer, - &valid, auth, TRUE); + &valid, TRUE); if (best && valid != VALIDATION_STALE) { break; @@ -276,7 +326,7 @@ static cert_validation_t check_ocsp(x509_t *subject, x509_t *issuer, if (current) { best = get_better_ocsp(current, best, subject, issuer, - &valid, auth, TRUE); + &valid, TRUE); if (best && valid != VALIDATION_STALE) { break; @@ -330,25 +380,20 @@ static certificate_t* fetch_crl(char *url) /** * check the signature of an CRL */ -static bool verify_crl(certificate_t *crl, auth_cfg_t *auth) +static bool verify_crl(certificate_t *crl) { certificate_t *issuer; enumerator_t *enumerator; bool verified = FALSE; - auth_cfg_t *current; enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, crl->get_issuer(crl), FALSE); - while (enumerator->enumerate(enumerator, &issuer, ¤t)) + while (enumerator->enumerate(enumerator, &issuer, NULL)) { if (lib->credmgr->issued_by(lib->credmgr, crl, issuer, NULL)) { DBG1(DBG_CFG, " crl correctly signed by \"%Y\"", issuer->get_subject(issuer)); - if (auth) - { - auth->merge(auth, current, FALSE); - } verified = TRUE; break; } @@ -362,7 +407,7 @@ static bool verify_crl(certificate_t *crl, auth_cfg_t *auth) * Get the better of two CRLs, and check for usable CRL info */ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, - x509_t *subject, cert_validation_t *valid, auth_cfg_t *auth, + x509_t *subject, cert_validation_t *valid, bool cache, crl_t *base) { enumerator_t *enumerator; @@ -390,7 +435,7 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, } /* check CRL signature */ - if (!verify_crl(cand, auth)) + if (!verify_crl(cand)) { DBG1(DBG_CFG, "crl response verification failed"); cand->destroy(cand); @@ -452,8 +497,8 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, * Find or fetch a certificate for a given crlIssuer */ static cert_validation_t find_crl(x509_t *subject, identification_t *issuer, - auth_cfg_t *auth, crl_t *base, - certificate_t **best, bool *uri_found) + crl_t *base, certificate_t **best, + bool *uri_found) { cert_validation_t valid = VALIDATION_SKIPPED; enumerator_t *enumerator; @@ -466,8 +511,7 @@ static cert_validation_t find_crl(x509_t *subject, identification_t *issuer, while (enumerator->enumerate(enumerator, ¤t)) { current->get_ref(current); - *best = get_better_crl(current, *best, subject, &valid, - auth, FALSE, base); + *best = get_better_crl(current, *best, subject, &valid, FALSE, base); if (*best && valid != VALIDATION_STALE) { DBG1(DBG_CFG, " using cached crl"); @@ -495,7 +539,7 @@ static cert_validation_t find_crl(x509_t *subject, identification_t *issuer, continue; } *best = get_better_crl(current, *best, subject, - &valid, auth, TRUE, base); + &valid, TRUE, base); if (*best && valid != VALIDATION_STALE) { break; @@ -511,7 +555,7 @@ static cert_validation_t find_crl(x509_t *subject, identification_t *issuer, * Look for a delta CRL for a given base CRL */ static cert_validation_t check_delta_crl(x509_t *subject, x509_t *issuer, - crl_t *base, cert_validation_t base_valid, auth_cfg_t *auth) + crl_t *base, cert_validation_t base_valid) { cert_validation_t valid = VALIDATION_SKIPPED; certificate_t *best = NULL, *current; @@ -526,7 +570,7 @@ static cert_validation_t check_delta_crl(x509_t *subject, x509_t *issuer, if (chunk.len) { id = identification_create_from_encoding(ID_KEY_ID, chunk); - valid = find_crl(subject, id, auth, base, &best, &uri); + valid = find_crl(subject, id, base, &best, &uri); id->destroy(id); } @@ -537,7 +581,7 @@ static cert_validation_t check_delta_crl(x509_t *subject, x509_t *issuer, { if (cdp->issuer) { - valid = find_crl(subject, cdp->issuer, auth, base, &best, &uri); + valid = find_crl(subject, cdp->issuer, base, &best, &uri); } } enumerator->destroy(enumerator); @@ -558,8 +602,7 @@ static cert_validation_t check_delta_crl(x509_t *subject, x509_t *issuer, current->destroy(current); continue; } - best = get_better_crl(current, best, subject, &valid, - auth, TRUE, base); + best = get_better_crl(current, best, subject, &valid, TRUE, base); if (best && valid != VALIDATION_STALE) { break; @@ -576,7 +619,6 @@ static cert_validation_t check_delta_crl(x509_t *subject, x509_t *issuer, return base_valid; } - /** * validate a x509 certificate using CRL */ @@ -597,7 +639,7 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer, if (chunk.len) { id = identification_create_from_encoding(ID_KEY_ID, chunk); - valid = find_crl(subject, id, auth, NULL, &best, &uri_found); + valid = find_crl(subject, id, NULL, &best, &uri_found); id->destroy(id); } @@ -608,8 +650,7 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer, { if (cdp->issuer) { - valid = find_crl(subject, cdp->issuer, auth, NULL, - &best, &uri_found); + valid = find_crl(subject, cdp->issuer, NULL, &best, &uri_found); } } enumerator->destroy(enumerator); @@ -633,7 +674,7 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer, continue; } best = get_better_crl(current, best, subject, &valid, - auth, TRUE, NULL); + TRUE, NULL); if (best && valid != VALIDATION_STALE) { break; @@ -646,7 +687,7 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer, /* look for delta CRLs */ if (best && (valid == VALIDATION_GOOD || valid == VALIDATION_STALE)) { - valid = check_delta_crl(subject, issuer, (crl_t*)best, valid, auth); + valid = check_delta_crl(subject, issuer, (crl_t*)best, valid); } /* an uri was found, but no result. switch validation state to failed */ diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in index e57eb78ab..4f9d24a7e 100644 --- a/src/libstrongswan/plugins/sha1/Makefile.in +++ b/src/libstrongswan/plugins/sha1/Makefile.in @@ -371,7 +371,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in index c044178b9..ddc287522 100644 --- a/src/libstrongswan/plugins/sha2/Makefile.in +++ b/src/libstrongswan/plugins/sha2/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in index cc16ef5cb..2ba05f71e 100644 --- a/src/libstrongswan/plugins/soup/Makefile.in +++ b/src/libstrongswan/plugins/soup/Makefile.in @@ -371,7 +371,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in index c428b883f..2cbacddf1 100644 --- a/src/libstrongswan/plugins/sqlite/Makefile.in +++ b/src/libstrongswan/plugins/sqlite/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/sshkey/Makefile.in b/src/libstrongswan/plugins/sshkey/Makefile.in index 3c9926acc..6bd82503d 100644 --- a/src/libstrongswan/plugins/sshkey/Makefile.in +++ b/src/libstrongswan/plugins/sshkey/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in index a1439f6ea..7443f531c 100644 --- a/src/libstrongswan/plugins/test_vectors/Makefile.in +++ b/src/libstrongswan/plugins/test_vectors/Makefile.in @@ -387,7 +387,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h index 788baae57..33c13d9f4 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors.h +++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h @@ -88,11 +88,18 @@ TEST_VECTOR_AEAD(aes_ccm10) TEST_VECTOR_AEAD(aes_ccm11) TEST_VECTOR_AEAD(aes_gcm1) TEST_VECTOR_AEAD(aes_gcm2) -TEST_VECTOR_AEAD(aes_gcm3) +TEST_VECTOR_AEAD(aes_gcm3_1) +TEST_VECTOR_AEAD(aes_gcm3_2) +TEST_VECTOR_AEAD(aes_gcm3_3) TEST_VECTOR_AEAD(aes_gcm4) -TEST_VECTOR_AEAD(aes_gcm5) -TEST_VECTOR_AEAD(aes_gcm6) TEST_VECTOR_AEAD(aes_gcm7) +TEST_VECTOR_AEAD(aes_gcm8) +TEST_VECTOR_AEAD(aes_gcm9) +TEST_VECTOR_AEAD(aes_gcm10) +TEST_VECTOR_AEAD(aes_gcm13) +TEST_VECTOR_AEAD(aes_gcm14) +TEST_VECTOR_AEAD(aes_gcm15) +TEST_VECTOR_AEAD(aes_gcm16) TEST_VECTOR_SIGNER(aes_xcbc_s1) TEST_VECTOR_SIGNER(aes_xcbc_s2) diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_ccm.c b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_ccm.c index 8de180ad5..95c41ecbc 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_ccm.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_ccm.c @@ -21,7 +21,8 @@ * originally from "fips cavs fax files on hand at Red Hat". */ aead_test_vector_t aes_ccm1 = { - .alg = ENCR_AES_CCM_ICV16, .key_size = 16, .len = 32, .alen = 0, + .alg = ENCR_AES_CCM_ICV16, .key_size = 16, .salt_size = 3, + .len = 32, .alen = 0, .key = "\x83\xac\x54\x66\xc2\xeb\xe5\x05\x2e\x01\xd1\xfc\x5d\x82\x66\x2e" "\x96\xac\x59", .iv = "\x30\x07\xa1\xe2\xa2\xc7\x55\x24", @@ -33,7 +34,8 @@ aead_test_vector_t aes_ccm1 = { }; aead_test_vector_t aes_ccm2 = { - .alg = ENCR_AES_CCM_ICV16, .key_size = 16, .len = 32, .alen = 32, + .alg = ENCR_AES_CCM_ICV16, .key_size = 16, .salt_size = 3, + .len = 32, .alen = 32, .key = "\x1e\x2c\x7e\x01\x41\x9a\xef\xc0\x0d\x58\x96\x6e\x5c\xa2\x4b\xd3" "\x4f\xa3\x19", .iv = "\xd3\x01\x5a\xd8\x30\x60\x15\x56", @@ -47,7 +49,8 @@ aead_test_vector_t aes_ccm2 = { }; aead_test_vector_t aes_ccm3 = { - .alg = ENCR_AES_CCM_ICV16, .key_size = 24, .len = 0, .alen = 32, + .alg = ENCR_AES_CCM_ICV16, .key_size = 24, .salt_size = 3, + .len = 0, .alen = 32, .key = "\xf4\x6b\xc2\x75\x62\xfe\xb4\xe1\xa3\xf0\xff\xdd\x4e\x4b\x12\x75" "\x53\x14\x73\x66\x8d\x88\xf6\x80\xa0\x20\x35", .iv = "\x26\xf2\x21\x8d\x50\x20\xda\xe2", @@ -57,7 +60,8 @@ aead_test_vector_t aes_ccm3 = { }; aead_test_vector_t aes_ccm4 = { - .alg = ENCR_AES_CCM_ICV16, .key_size = 24, .len = 32, .alen = 32, + .alg = ENCR_AES_CCM_ICV16, .key_size = 24, .salt_size = 3, + .len = 32, .alen = 32, .key = "\x56\xdf\x5c\x8f\x26\x3f\x0e\x42\xef\x7a\xd3\xce\xfc\x84\x60\x62" "\xca\xb4\x40\xaf\x5f\xc9\xc9\x01\xd6\x3c\x8c", .iv = "\x86\x84\xb6\xcd\xef\x09\x2e\x94", @@ -71,7 +75,8 @@ aead_test_vector_t aes_ccm4 = { }; aead_test_vector_t aes_ccm5 = { - .alg = ENCR_AES_CCM_ICV8, .key_size = 32, .len = 32, .alen = 32, + .alg = ENCR_AES_CCM_ICV8, .key_size = 32, .salt_size = 3, + .len = 32, .alen = 32, .key = "\xe0\x8d\x99\x71\x60\xd7\x97\x1a\xbd\x01\x99\xd5\x8a\xdf\x71\x3a" "\xd3\xdf\x24\x4b\x5e\x3d\x4b\x4e\x30\x7a\xb9\xd8\x53\x0a\x5e\x2b" "\x1e\x29\x91", @@ -86,7 +91,8 @@ aead_test_vector_t aes_ccm5 = { }; aead_test_vector_t aes_ccm6 = { - .alg = ENCR_AES_CCM_ICV12, .key_size = 32, .len = 32, .alen = 32, + .alg = ENCR_AES_CCM_ICV12, .key_size = 32, .salt_size = 3, + .len = 32, .alen = 32, .key = "\x7c\xc8\x18\x3b\x8d\x99\xe0\x7c\x45\x41\xb8\xbd\x5c\xa7\xc2\x32" "\x8a\xb8\x02\x59\xa4\xfe\xa9\x2c\x09\x75\x9a\x9b\x3c\x9b\x27\x39" "\xf9\xd9\x4e", @@ -101,7 +107,8 @@ aead_test_vector_t aes_ccm6 = { }; aead_test_vector_t aes_ccm7 = { - .alg = ENCR_AES_CCM_ICV16, .key_size = 32, .len = 32, .alen = 32, + .alg = ENCR_AES_CCM_ICV16, .key_size = 32, .salt_size = 3, + .len = 32, .alen = 32, .key = "\xab\xd0\xe9\x33\x07\x26\xe5\x83\x8c\x76\x95\xd4\xb6\xdc\xf3\x46" "\xf9\x8f\xad\xe3\x02\x13\x83\x77\x3f\xb0\xf1\xa1\xa1\x22\x0f\x2b" "\x24\xa7\x8b", @@ -116,7 +123,8 @@ aead_test_vector_t aes_ccm7 = { }; aead_test_vector_t aes_ccm8 = { - .alg = ENCR_AES_CCM_ICV8, .key_size = 16, .len = 0, .alen = 0, + .alg = ENCR_AES_CCM_ICV8, .key_size = 16, .salt_size = 3, + .len = 0, .alen = 0, .key = "\xab\x2f\x8a\x74\xb7\x1c\xd2\xb1\xff\x80\x2e\x48\x7d\x82\xf8\xb9" "\xaf\x94\x87", .iv = "\x78\x35\x82\x81\x7f\x88\x94\x68", @@ -124,7 +132,8 @@ aead_test_vector_t aes_ccm8 = { }; aead_test_vector_t aes_ccm9 = { - .alg = ENCR_AES_CCM_ICV8, .key_size = 24, .len = 0, .alen = 32, + .alg = ENCR_AES_CCM_ICV8, .key_size = 24, .salt_size = 3, + .len = 0, .alen = 32, .key = "\x39\xbb\xa7\xbe\x59\x97\x9e\x73\xa2\xbc\x6b\x98\xd7\x75\x7f\xe3" "\xa4\x48\x93\x39\x26\x71\x4a\xc6\xee\x49\x83", .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e", @@ -134,7 +143,8 @@ aead_test_vector_t aes_ccm9 = { }; aead_test_vector_t aes_ccm10 = { - .alg = ENCR_AES_CCM_ICV8, .key_size = 32, .len = 0, .alen = 0, + .alg = ENCR_AES_CCM_ICV8, .key_size = 32, .salt_size = 3, + .len = 0, .alen = 0, .key = "\xa4\x4b\x54\x29\x0a\xb8\x6d\x01\x5b\x80\x2a\xcf\x25\xc4\xb7\x5c" "\x20\x2c\xad\x30\xc2\x2b\x41\xfb\x0e\x85\xbc\x33\xad\x0f\x2b\xff" "\xee\x49\x83", @@ -143,7 +153,8 @@ aead_test_vector_t aes_ccm10 = { }; aead_test_vector_t aes_ccm11 = { - .alg = ENCR_AES_CCM_ICV8, .key_size = 24, .len = 32, .alen = 32, + .alg = ENCR_AES_CCM_ICV8, .key_size = 24, .salt_size = 3, + .len = 32, .alen = 32, .key = "\x58\x5d\xa0\x96\x65\x1a\x04\xd7\x96\xe5\xc5\x68\xaa\x95\x35\xe0" "\x29\xa0\xba\x9e\x48\x78\xd1\xba\xee\x49\x83", .iv = "\xe9\xa9\xff\xe9\x57\xba\xfd\x9e", diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_gcm.c b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_gcm.c index 7534633e1..1f33bcbd5 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_gcm.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_gcm.c @@ -16,11 +16,37 @@ #include <crypto/crypto_tester.h> /** - * From the Linux kernel, those with an IV. Originally from - * McGrew & Viega - http://citeseer.ist.psu.edu/656989.html + * From McGrew & Viega + * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + * Formatted to match our API which expects the first four bytes (salt) of the + * IV as part of the key and writes/expects the ICV at the end of the cipher + * text. + * Since our implementations are currently limited to IV lengths of 12 (IV=8, + * SALT=4 as per RFC 4106/5282) the test cases 5/6, 11/12 and 17/18 aren't + * compatible. */ aead_test_vector_t aes_gcm1 = { - .alg = ENCR_AES_GCM_ICV8, .key_size = 16, .len = 64, .alen = 0, + .alg = ENCR_AES_GCM_ICV16, .key_size = 16, .salt_size = 4, + .len = 0, .alen = 0, + .key = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00", + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", + .plain = "", + .cipher = "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45\x5a", +}; +aead_test_vector_t aes_gcm2 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 16, .salt_size = 4, + .len = 16, .alen = 0, + .key = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00", + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", + .plain = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + .cipher = "\x03\x88\xda\xce\x60\xb6\xa3\x92\xf3\x28\xc2\xb9\x71\xb2\xfe\x78" + "\xab\x6e\x47\xd4\x2c\xec\x13\xbd\xf5\x3a\x67\xb2\x12\x57\xbd\xdf", +}; +aead_test_vector_t aes_gcm3_1 = { + .alg = ENCR_AES_GCM_ICV8, .key_size = 16, .salt_size = 4, + .len = 64, .alen = 0, .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xca\xfe\xba\xbe", .iv = "\xfa\xce\xdb\xad\xde\xca\xf8\x88", @@ -34,9 +60,9 @@ aead_test_vector_t aes_gcm1 = { "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85" "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6", }; - -aead_test_vector_t aes_gcm2 = { - .alg = ENCR_AES_GCM_ICV12, .key_size = 16, .len = 64, .alen = 0, +aead_test_vector_t aes_gcm3_2 = { + .alg = ENCR_AES_GCM_ICV12, .key_size = 16, .salt_size = 4, + .len = 64, .alen = 0, .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xca\xfe\xba\xbe", .iv = "\xfa\xce\xdb\xad\xde\xca\xf8\x88", @@ -50,9 +76,9 @@ aead_test_vector_t aes_gcm2 = { "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85" "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6\x2c\xf3\x5a\xbd", }; - -aead_test_vector_t aes_gcm3 = { - .alg = ENCR_AES_GCM_ICV16, .key_size = 16, .len = 64, .alen = 0, +aead_test_vector_t aes_gcm3_3 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 16, .salt_size = 4, + .len = 64, .alen = 0, .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xca\xfe\xba\xbe", .iv = "\xfa\xce\xdb\xad\xde\xca\xf8\x88", @@ -66,9 +92,9 @@ aead_test_vector_t aes_gcm3 = { "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85" "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4", }; - aead_test_vector_t aes_gcm4 = { - .alg = ENCR_AES_GCM_ICV16, .key_size = 16, .len = 60, .alen = 20, + .alg = ENCR_AES_GCM_ICV16, .key_size = 16, .salt_size = 4, + .len = 60, .alen = 20, .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xca\xfe\xba\xbe", .iv = "\xfa\xce\xdb\xad\xde\xca\xf8\x88", @@ -84,9 +110,28 @@ aead_test_vector_t aes_gcm4 = { "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x5b\xc9\x4f\xbc" "\x32\x21\xa5\xdb\x94\xfa\xe9\x5a\xe7\x12\x1a\x47", }; - -aead_test_vector_t aes_gcm5 = { - .alg = ENCR_AES_GCM_ICV16, .key_size = 24, .len = 64, .alen = 0, +aead_test_vector_t aes_gcm7 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 24, .salt_size = 4, + .len = 0, .alen = 0, + .key = "\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", + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", + .plain = "", + .cipher = "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b\xa0\x0e\xd1\xf3\x12\x57\x24\x35", +}; +aead_test_vector_t aes_gcm8 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 24, .salt_size = 4, + .len = 16, .alen = 0, + .key = "\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", + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", + .plain = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + .cipher = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41\x1c\x26\x7e\x43\x84\xb0\xf6\x00" + "\x2f\xf5\x8d\x80\x03\x39\x27\xab\x8e\xf4\xd4\x58\x75\x14\xf0\xfb", +}; +aead_test_vector_t aes_gcm9 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 24, .salt_size = 4, + .len = 64, .alen = 0, .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xfe\xff\xe9\x92\x86\x65\x73\x1c\xca\xfe\xba\xbe", .iv = "\xfa\xce\xdb\xad\xde\xca\xf8\x88", @@ -100,9 +145,48 @@ aead_test_vector_t aes_gcm5 = { "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9\xcc\xda\x27\x10\xac\xad\xe2\x56" "\x99\x24\xa7\xc8\x58\x73\x36\xbf\xb1\x18\x02\x4d\xb8\x67\x4a\x14", }; - -aead_test_vector_t aes_gcm6 = { - .alg = ENCR_AES_GCM_ICV16, .key_size = 32, .len = 64, .alen = 0, +aead_test_vector_t aes_gcm10 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 24, .salt_size = 4, + .len = 60, .alen = 20, + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\xfe\xff\xe9\x92\x86\x65\x73\x1c\xca\xfe\xba\xbe", + .iv = "\xfa\xce\xdb\xad\xde\xca\xf8\x88", + .plain = "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" + "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" + "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" + "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", + .adata = "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" + "\xab\xad\xda\xd2", + .cipher = "\x39\x80\xca\x0b\x3c\x00\xe8\x41\xeb\x06\xfa\xc4\x87\x2a\x27\x57" + "\x85\x9e\x1c\xea\xa6\xef\xd9\x84\x62\x85\x93\xb4\x0c\xa1\xe1\x9c" + "\x7d\x77\x3d\x00\xc1\x44\xc5\x25\xac\x61\x9d\x18\xc8\x4a\x3f\x47" + "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9\xcc\xda\x27\x10\x25\x19\x49\x8e" + "\x80\xf1\x47\x8f\x37\xba\x55\xbd\x6d\x27\x61\x8c", +}; +aead_test_vector_t aes_gcm13 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 32, .salt_size = 4, + .len = 0, .alen = 0, + .key = "\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", + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", + .plain = "", + .cipher = "\x53\x0f\x8a\xfb\xc7\x45\x36\xb9\xa9\x63\xb4\xf1\xc4\xcb\x73\x8b", +}; +aead_test_vector_t aes_gcm14 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 32, .salt_size = 4, + .len = 16, .alen = 0, + .key = "\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", + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00", + .plain = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + .cipher = "\xce\xa7\x40\x3d\x4d\x60\x6b\x6e\x07\x4e\xc5\xd3\xba\xf3\x9d\x18" + "\xd0\xd1\xc8\xa7\x99\x99\x6b\xf0\x26\x5b\x98\xb5\xd4\x8a\xb9\x19", +}; +aead_test_vector_t aes_gcm15 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 32, .salt_size = 4, + .len = 64, .alen = 0, .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xca\xfe\xba\xbe", @@ -117,9 +201,9 @@ aead_test_vector_t aes_gcm6 = { "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a\xbc\xc9\xf6\x62\x89\x80\x15\xad" "\xb0\x94\xda\xc5\xd9\x34\x71\xbd\xec\x1a\x50\x22\x70\xe3\xcc\x6c", }; - -aead_test_vector_t aes_gcm7 = { - .alg = ENCR_AES_GCM_ICV16, .key_size = 32, .len = 60, .alen = 20, +aead_test_vector_t aes_gcm16 = { + .alg = ENCR_AES_GCM_ICV16, .key_size = 32, .salt_size = 4, + .len = 60, .alen = 20, .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xca\xfe\xba\xbe", @@ -136,4 +220,3 @@ aead_test_vector_t aes_gcm7 = { "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a\xbc\xc9\xf6\x62\x76\xfc\x6e\xce" "\x0f\x4e\x17\x68\xcd\xdf\x88\x53\xbb\x2d\x55\x1b", }; - diff --git a/src/libstrongswan/plugins/unbound/Makefile.in b/src/libstrongswan/plugins/unbound/Makefile.in index 961311eb0..c3c6ed6a7 100644 --- a/src/libstrongswan/plugins/unbound/Makefile.in +++ b/src/libstrongswan/plugins/unbound/Makefile.in @@ -373,7 +373,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in index 74552e00b..154fc5ccd 100644 --- a/src/libstrongswan/plugins/x509/Makefile.in +++ b/src/libstrongswan/plugins/x509/Makefile.in @@ -372,7 +372,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index 7d83e48ea..30b871d42 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -29,7 +29,6 @@ #include <utils/identification.h> #include <collections/linked_list.h> #include <credentials/certificates/x509.h> -#include <credentials/ietf_attributes/ietf_attributes.h> #include <credentials/keys/private_key.h> extern chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, @@ -75,7 +74,7 @@ struct private_x509_ac_t { /** * Serial number of the holder certificate */ - chunk_t holderSerial; + identification_t *holderSerial; /** * ID representing the holder @@ -98,14 +97,9 @@ struct private_x509_ac_t { time_t notAfter; /** - * List of charging attributes + * List of group attributes, as group_t */ - ietf_attributes_t *charging; - - /** - * List of groub attributes - */ - ietf_attributes_t *groups; + linked_list_t *groups; /** * Authority Key Identifier @@ -153,6 +147,25 @@ struct private_x509_ac_t { refcount_t ref; }; +/** + * Group definition, an IETF attribute + */ +typedef struct { + /** Attribute type */ + ac_group_type_t type; + /* attribute value */ + chunk_t value; +} group_t; + +/** + * Clean up a group entry + */ +static void group_destroy(group_t *group) +{ + free(group->value.ptr); + free(group); +} + static chunk_t ASN1_noRevAvail_ext = chunk_from_chars( 0x30, 0x09, 0x06, 0x03, @@ -169,42 +182,41 @@ extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, /** * parses a directoryName */ -static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name) +static bool parse_directoryName(chunk_t blob, int level, bool implicit, + identification_t **name) { - bool has_directoryName; - linked_list_t *list = linked_list_create(); + identification_t *directoryName; + enumerator_t *enumerator; + bool first = TRUE; + linked_list_t *list; + list = linked_list_create(); x509_parse_generalNames(blob, level, implicit, list); - has_directoryName = list->get_count(list) > 0; - if (has_directoryName) + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &directoryName)) { - enumerator_t *enumerator = list->create_enumerator(list); - identification_t *directoryName; - bool first = TRUE; - - while (enumerator->enumerate(enumerator, (void**)&directoryName)) + if (first) { - if (first) - { - *name = directoryName; - first = FALSE; - } - else - { - DBG1(DBG_ASN, "more than one directory name - first selected"); - directoryName->destroy(directoryName); - } + *name = directoryName; + first = FALSE; + } + else + { + DBG1(DBG_ASN, "more than one directory name - first selected"); + directoryName->destroy(directoryName); + break; } - enumerator->destroy(enumerator); } - else + enumerator->destroy(enumerator); + list->destroy(list); + + if (first) { DBG1(DBG_ASN, "no directoryName found"); + return FALSE; } - - list->destroy(list); - return has_directoryName; + return TRUE; } /** @@ -244,63 +256,131 @@ static void parse_roleSyntax(chunk_t blob, int level0) } /** + * ASN.1 definition of ietfAttrSyntax + */ +static const asn1Object_t ietfAttrSyntaxObjects[] = +{ + { 0, "ietfAttrSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "policyAuthority", ASN1_CONTEXT_C_0, ASN1_OPT | + ASN1_BODY }, /* 1 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */ + { 1, "values", ASN1_SEQUENCE, ASN1_LOOP }, /* 3 */ + { 2, "octets", ASN1_OCTET_STRING, ASN1_OPT | + ASN1_BODY }, /* 4 */ + { 2, "end choice", ASN1_EOC, ASN1_END }, /* 5 */ + { 2, "oid", ASN1_OID, ASN1_OPT | + ASN1_BODY }, /* 6 */ + { 2, "end choice", ASN1_EOC, ASN1_END }, /* 7 */ + { 2, "string", ASN1_UTF8STRING, ASN1_OPT | + ASN1_BODY }, /* 8 */ + { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */ + { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define IETF_ATTR_OCTETS 4 +#define IETF_ATTR_OID 6 +#define IETF_ATTR_STRING 8 + +/** + * Parse group memberships, IETF attributes + */ +static bool parse_groups(private_x509_ac_t *this, chunk_t encoded, int level0) +{ + ac_group_type_t type; + group_t *group; + asn1_parser_t *parser; + chunk_t object; + int objectID; + bool success; + + parser = asn1_parser_create(ietfAttrSyntaxObjects, encoded); + parser->set_top_level(parser, level0); + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case IETF_ATTR_OCTETS: + type = AC_GROUP_TYPE_OCTETS; + break; + case IETF_ATTR_OID: + type = AC_GROUP_TYPE_OID; + break; + case IETF_ATTR_STRING: + type = AC_GROUP_TYPE_STRING; + break; + default: + continue; + } + INIT(group, + .type = type, + .value = chunk_clone(object), + ); + this->groups->insert_last(this->groups, group); + } + success = parser->success(parser); + parser->destroy(parser); + + return success; +} + +/** * ASN.1 definition of an X509 attribute certificate */ static const asn1Object_t acObjects[] = { { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */ { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */ - { 2, "version", ASN1_INTEGER, ASN1_DEF | + { 2, "version", ASN1_INTEGER, ASN1_DEF | ASN1_BODY }, /* 2 */ - { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */ - { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */ - { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */ - { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */ + { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */ + { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */ + { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */ + { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */ { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT | ASN1_BODY }, /* 7 */ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */ - { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT | + { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT | ASN1_OBJ }, /* 10 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */ - { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */ - { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13 */ - { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT | + { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */ + { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13 */ + { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT | ASN1_BODY }, /* 14 */ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15 */ { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */ - { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */ - { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT | + { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */ + { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT | ASN1_OBJ }, /* 19 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */ - { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */ - { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */ - { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */ - { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */ + { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */ + { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */ + { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */ + { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */ { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT | ASN1_BODY }, /* 25 */ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */ { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */ - { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */ - { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */ - { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT | + { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */ + { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */ + { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT | ASN1_BODY }, /* 31 */ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */ { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */ - { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */ - { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */ - { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */ - { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */ - { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */ - { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */ + { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */ + { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */ + { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */ + { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */ + { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */ + { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */ { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */ { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */ { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */ { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */ - { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */ + { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */ { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */ @@ -368,22 +448,26 @@ static bool parse_certificate(private_x509_ac_t *this) } break; case AC_OBJ_HOLDER_ISSUER: - if (!parse_directoryName(object, level, FALSE, &this->holderIssuer)) + if (!parse_directoryName(object, level, FALSE, + &this->holderIssuer)) { goto end; } break; case AC_OBJ_HOLDER_SERIAL: - this->holderSerial = object; + this->holderSerial = identification_create_from_encoding( + ID_KEY_ID, object); break; case AC_OBJ_ENTITY_NAME: - if (!parse_directoryName(object, level, TRUE, &this->entityName)) + if (!parse_directoryName(object, level, TRUE, + &this->entityName)) { goto end; } break; case AC_OBJ_ISSUER_NAME: - if (!parse_directoryName(object, level, FALSE, &this->issuerName)) + if (!parse_directoryName(object, level, FALSE, + &this->issuerName)) { goto end; } @@ -414,13 +498,14 @@ static bool parse_certificate(private_x509_ac_t *this) DBG2(DBG_ASN, " need to parse accessIdentity"); break; case OID_CHARGING_IDENTITY: - DBG2(DBG_ASN, "-- > --"); - this->charging = ietf_attributes_create_from_encoding(object); - DBG2(DBG_ASN, "-- < --"); + DBG2(DBG_ASN, " need to parse chargingIdentity"); break; case OID_GROUP: DBG2(DBG_ASN, "-- > --"); - this->groups = ietf_attributes_create_from_encoding(object); + if (!parse_groups(this, object, level)) + { + goto end; + } DBG2(DBG_ASN, "-- < --"); break; case OID_ROLE: @@ -446,8 +531,9 @@ static bool parse_certificate(private_x509_ac_t *this) DBG2(DBG_ASN, " need to parse crlDistributionPoints"); break; case OID_AUTHORITY_KEY_ID: - this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object, - level, &this->authKeySerialNumber); + this->authKeyIdentifier = + x509_parse_authorityKeyIdentifier(object, + level, &this->authKeySerialNumber); break; case OID_TARGET_INFORMATION: DBG2(DBG_ASN, " need to parse targetInformation"); @@ -490,7 +576,7 @@ end: static chunk_t build_directoryName(asn1_t tag, chunk_t name) { return asn1_wrap(tag, "m", - asn1_simple_object(ASN1_CONTEXT_C_4, name)); + asn1_simple_object(ASN1_CONTEXT_C_4, name)); } /** @@ -499,14 +585,15 @@ static chunk_t build_directoryName(asn1_t tag, chunk_t name) static chunk_t build_holder(private_x509_ac_t *this) { x509_t* x509 = (x509_t*)this->holderCert; - identification_t *issuer = this->holderCert->get_issuer(this->holderCert); - identification_t *subject = this->holderCert->get_subject(this->holderCert); + identification_t *issuer, *subject; + + issuer = this->holderCert->get_issuer(this->holderCert); + subject = this->holderCert->get_subject(this->holderCert); return asn1_wrap(ASN1_SEQUENCE, "mm", asn1_wrap(ASN1_CONTEXT_C_0, "mm", build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)), - asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509)) - ), + asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509))), build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject))); } @@ -515,10 +602,12 @@ static chunk_t build_holder(private_x509_ac_t *this) */ static chunk_t build_v2_form(private_x509_ac_t *this) { - identification_t *subject = this->signerCert->get_subject(this->signerCert); + identification_t *subject; + subject = this->signerCert->get_subject(this->signerCert); return asn1_wrap(ASN1_CONTEXT_C_0, "m", - build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject))); + build_directoryName(ASN1_SEQUENCE, + subject->get_encoding(subject))); } /** @@ -531,7 +620,6 @@ static chunk_t build_attr_cert_validity(private_x509_ac_t *this) asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME)); } - /** * build attribute type */ @@ -547,8 +635,55 @@ static chunk_t build_attribute_type(int type, chunk_t content) */ static chunk_t build_attributes(private_x509_ac_t *this) { + enumerator_t *enumerator; + group_t *group; + chunk_t values; + size_t size = 0, len; + u_char *pos; + + /* precalculate the total size of all values */ + enumerator = this->groups->create_enumerator(this->groups); + while (enumerator->enumerate(enumerator, &group)) + { + len = group->value.len; + size += 1 + (len > 0) + (len >= 128) + + (len >= 256) + (len >= 65536) + len; + } + enumerator->destroy(enumerator); + + pos = asn1_build_object(&values, ASN1_SEQUENCE, size); + + enumerator = this->groups->create_enumerator(this->groups); + while (enumerator->enumerate(enumerator, &group)) + { + chunk_t attr; + asn1_t type; + + switch (group->type) + { + case AC_GROUP_TYPE_OCTETS: + type = ASN1_OCTET_STRING; + break; + case AC_GROUP_TYPE_STRING: + type = ASN1_UTF8STRING; + break; + case AC_GROUP_TYPE_OID: + type = ASN1_OID; + break; + default: + continue; + } + attr = asn1_simple_object(type, group->value); + + memcpy(pos, attr.ptr, attr.len); + pos += attr.len; + free(attr.ptr); + } + enumerator->destroy(enumerator); + return asn1_wrap(ASN1_SEQUENCE, "m", - build_attribute_type(OID_GROUP, this->groups->get_encoding(this->groups))); + build_attribute_type(OID_GROUP, + asn1_wrap(ASN1_SEQUENCE, "m", values))); } /** @@ -621,14 +756,11 @@ static chunk_t build_attr_cert_info(private_x509_ac_t *this) */ static chunk_t build_ac(private_x509_ac_t *this) { - chunk_t signatureValue; - chunk_t attributeCertificateInfo; + chunk_t signatureValue, attributeCertificateInfo; attributeCertificateInfo = build_attr_cert_info(this); - this->signerKey->sign(this->signerKey, SIGN_RSA_EMSA_PKCS1_SHA1, attributeCertificateInfo, &signatureValue); - return asn1_wrap(ASN1_SEQUENCE, "mmm", attributeCertificateInfo, asn1_algorithmIdentifier(OID_SHA1_WITH_RSA), @@ -644,7 +776,11 @@ METHOD(ac_t, get_serial, chunk_t, METHOD(ac_t, get_holderSerial, chunk_t, private_x509_ac_t *this) { - return this->holderSerial; + if (this->holderSerial) + { + return this->holderSerial->get_encoding(this->holderSerial); + } + return chunk_empty; } METHOD(ac_t, get_holderIssuer, identification_t*, @@ -659,10 +795,28 @@ METHOD(ac_t, get_authKeyIdentifier, chunk_t, return this->authKeyIdentifier; } -METHOD(ac_t, get_groups, ietf_attributes_t*, +/** + * Filter function for attribute enumeration + */ +static bool attr_filter(void *null, group_t **in, ac_group_type_t *type, + void *in2, chunk_t *out) +{ + if ((*in)->type == AC_GROUP_TYPE_STRING && + !chunk_printable((*in)->value, NULL, 0)) + { /* skip non-printable strings */ + return FALSE; + } + *type = (*in)->type; + *out = (*in)->value; + return TRUE; +} + +METHOD(ac_t, create_group_enumerator, enumerator_t*, private_x509_ac_t *this) { - return this->groups ? this->groups->get_ref(this->groups) : NULL; + return enumerator_create_filter( + this->groups->create_enumerator(this->groups), + (void*)attr_filter, NULL, NULL); } METHOD(certificate_t, get_type, certificate_type_t, @@ -674,7 +828,11 @@ METHOD(certificate_t, get_type, certificate_type_t, METHOD(certificate_t, get_subject, identification_t*, private_x509_ac_t *this) { - return this->entityName; + if (this->entityName) + { + return this->entityName; + } + return this->holderSerial; } METHOD(certificate_t, get_issuer, identification_t*, @@ -686,13 +844,24 @@ METHOD(certificate_t, get_issuer, identification_t*, METHOD(certificate_t, has_subject, id_match_t, private_x509_ac_t *this, identification_t *subject) { - return ID_MATCH_NONE; + id_match_t entity = ID_MATCH_NONE, serial = ID_MATCH_NONE; + + if (this->entityName) + { + entity = this->entityName->matches(this->entityName, subject); + } + if (this->holderSerial) + { + serial = this->holderSerial->matches(this->holderSerial, subject); + } + return max(entity, serial); } METHOD(certificate_t, has_issuer, id_match_t, private_x509_ac_t *this, identification_t *issuer) { - if (issuer->get_type(issuer) == ID_KEY_ID && this->authKeyIdentifier.ptr && + if (issuer->get_type(issuer) == ID_KEY_ID && + this->authKeyIdentifier.ptr && chunk_equals(this->authKeyIdentifier, issuer->get_encoding(issuer))) { return ID_MATCH_PERFECT; @@ -808,9 +977,10 @@ METHOD(certificate_t, equals, bool, { return TRUE; } - if (other->equals == (void*)equals) + if (other->equals == _equals) { /* skip allocation if we have the same implementation */ - return chunk_equals(this->encoding, ((private_x509_ac_t*)other)->encoding); + return chunk_equals(this->encoding, + ((private_x509_ac_t*)other)->encoding); } if (!other->get_encoding(other, CERT_ASN1_DER, &encoding)) { @@ -827,13 +997,13 @@ METHOD(certificate_t, destroy, void, if (ref_put(&this->ref)) { DESTROY_IF(this->holderIssuer); + DESTROY_IF(this->holderSerial); DESTROY_IF(this->entityName); DESTROY_IF(this->issuerName); DESTROY_IF(this->holderCert); DESTROY_IF(this->signerCert); DESTROY_IF(this->signerKey); - DESTROY_IF(this->charging); - DESTROY_IF(this->groups); + this->groups->destroy_function(this->groups, (void*)group_destroy); free(this->serialNumber.ptr); free(this->authKeyIdentifier.ptr); free(this->encoding.ptr); @@ -869,9 +1039,10 @@ static private_x509_ac_t *create_empty(void) .get_holderSerial = _get_holderSerial, .get_holderIssuer = _get_holderIssuer, .get_authKeyIdentifier = _get_authKeyIdentifier, - .get_groups = _get_groups, + .create_group_enumerator = _create_group_enumerator, }, }, + .groups = linked_list_create(), .ref = 1, ); @@ -914,6 +1085,27 @@ x509_ac_t *x509_ac_load(certificate_type_t type, va_list args) } /** + * Add groups from a list into AC group memberships + */ +static void add_groups_from_list(private_x509_ac_t *this, linked_list_t *list) +{ + enumerator_t *enumerator; + group_t *group; + char *name; + + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &name)) + { + INIT(group, + .type = AC_GROUP_TYPE_STRING, + .value = chunk_clone(chunk_from_str(name)), + ); + this->groups->insert_last(this->groups, group); + } + enumerator->destroy(enumerator); +} + +/** * See header. */ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args) @@ -934,8 +1126,8 @@ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args) case BUILD_SERIAL: ac->serialNumber = chunk_clone(va_arg(args, chunk_t)); continue; - case BUILD_IETF_GROUP_ATTR: - ac->groups = ietf_attributes_create_from_string(va_arg(args, char*)); + case BUILD_AC_GROUP_STRINGS: + add_groups_from_list(ac, va_arg(args, linked_list_t*)); continue; case BUILD_CERT: ac->holderCert = va_arg(args, certificate_t*); @@ -968,4 +1160,3 @@ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args) destroy(ac); return NULL; } - diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index ed850e8f5..9fd869e77 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -758,6 +758,9 @@ static void parse_extendedKeyUsage(chunk_t blob, int level0, case OID_OCSP_SIGNING: this->flags |= X509_OCSP_SIGNER; break; + case OID_MS_SMARTCARD_LOGON: + this->flags |= X509_MS_SMARTCARD_LOGON; + break; default: break; } @@ -2008,7 +2011,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty; chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty; chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty; - chunk_t ikeIntermediate = chunk_empty; + chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty; identification_t *issuer, *subject; chunk_t key_info; signature_scheme_t scheme; @@ -2139,6 +2142,10 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, { ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING); } + if (cert->flags & X509_MS_SMARTCARD_LOGON) + { + msSmartcardLogon = asn1_build_known_oid(OID_MS_SMARTCARD_LOGON); + } if (serverAuth.ptr || clientAuth.ptr || ikeIntermediate.ptr || ocspSigning.ptr) @@ -2146,9 +2153,9 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(OID_EXTENDED_KEY_USAGE), asn1_wrap(ASN1_OCTET_STRING, "m", - asn1_wrap(ASN1_SEQUENCE, "mmmm", + asn1_wrap(ASN1_SEQUENCE, "mmmmm", serverAuth, clientAuth, ikeIntermediate, - ocspSigning))); + ocspSigning, msSmartcardLogon))); } /* add subjectKeyIdentifier to CA and OCSP signer certificates */ @@ -2167,7 +2174,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, } /* add the keyid authKeyIdentifier for non self-signed certificates */ - if (sign_key) + if (sign_cert) { chunk_t keyid; diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c index 09c5a8539..ff0f0231f 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c @@ -252,7 +252,7 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this, { int oid; signature_scheme_t scheme; - chunk_t certs, signature, encoding; + chunk_t certs = chunk_empty, signature, encoding; switch (this->key->get_type(this->key)) { diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c index 15fea7ee0..54bef7357 100644 --- a/src/libstrongswan/plugins/x509/x509_plugin.c +++ b/src/libstrongswan/plugins/x509/x509_plugin.c @@ -52,9 +52,7 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(CERT_DECODE, x509_cert_load, TRUE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), PLUGIN_DEPENDS(HASHER, HASH_SHA1), - PLUGIN_SDEPEND(PUBKEY, KEY_RSA), - PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA), - PLUGIN_SDEPEND(PUBKEY, KEY_DSA), + PLUGIN_DEPENDS(PUBKEY, KEY_ANY), PLUGIN_REGISTER(CERT_ENCODE, x509_ac_gen, FALSE), PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_AC), diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in index c8f886c60..ca6164371 100644 --- a/src/libstrongswan/plugins/xcbc/Makefile.in +++ b/src/libstrongswan/plugins/xcbc/Makefile.in @@ -370,7 +370,6 @@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ -openac_plugins = @openac_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ |